# 一见如故
又是 mt19937 系列的
class Myrand(): | |
def __init__(self,seed): | |
self.index = 0 | |
self.isInit = 1 | |
self.MT = [seed] + [0] * 623 | |
for i in range(1,624): | |
t = 1314433253 * (self.MT[i-1] ^ (self.MT[i-1] >> 30)) + 1 | |
self.MT[i] = t & 0xffffffff | |
def generate(self): | |
for i in range(624): | |
y = (self.MT[i] & 0x80000000) + (self.MT[(i+1)%624] & 0x7fffffff) | |
self.MT[i] = self.MT[(i+397)%624] ^ (y >> 1) | |
if y & 1: | |
self.MT[i] ^= 2567483520 | |
def rand(self): | |
if self.index == 0: | |
self.generate() | |
y = self.MT[self.index] | |
y = y ^ self.cs2l(y, 11) ^ self.cs2l(y,15) | |
y = y ^ self.cs2r(y,7) ^ self.cs2r(y,19) | |
self.index = (self.index + 1) % 624 | |
return y | |
def cs2l(self, y, shift): | |
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff | |
def cs2r(self, y, shift): | |
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff | |
import os | |
r = Myrand(int(os.urandom(4).hex(),16)) | |
out = [] | |
for i in range(624): | |
out.append(r.rand()) | |
with open("output.txt","w") as f: | |
f.write(str(out)) | |
from hashlib import md5 | |
flag = 'flag{' + md5(str(r.rand()).encode()).hexdigest() + '}' | |
print(flag) |
rand () 有点不一样,是循环异或,在网上找到了可逆的脚本
# 破解右移 | |
def decrypted_first(y, key): | |
for _ in range(32): | |
y = y ^ cs2r(y, key[0]) ^ cs2r(y, key[1]) | |
key = [k << 1 for k in key] | |
return y | |
# 破解左移 | |
def decrypted_second(y, key): | |
for _ in range(32): | |
y = y ^ cs2l(y, key[0]) ^ cs2l(y, key[1]) | |
key = [k << 1 for k in key] | |
return y |
然后就可以求了
def cs2l( y, shift): | |
shift %= 32 | |
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff | |
def cs2r( y, shift): | |
shift %= 32 | |
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff | |
def aa(y): | |
y = y ^ cs2l(y, 11) ^ cs2l(y,15) | |
y = y ^ cs2r(y,7) ^ cs2r(y,19) | |
return y | |
def decrypted_first(y, key): | |
for _ in range(32): | |
y = y ^ cs2r(y, key[0]) ^ cs2r(y, key[1]) | |
key = [k << 1 for k in key] | |
return y | |
# 破解左移 | |
def decrypted_second(y, key): | |
for _ in range(32): | |
y = y ^ cs2l(y, key[0]) ^ cs2l(y, key[1]) | |
key = [k << 1 for k in key] | |
return y | |
key_r=[7,19] | |
key_l=[11,15] | |
mm=[1789930006, 1667540600, 1001134734, 2771087402, 1555158361, 3802425413, 186740355, 3238827425, 3822371986, 105656880, 2147674756, 4002398195, 999630311, 1043379329, 1844438614, 1573901879, 809580137, 1920530747, 3068490029, 188533208, 2352442425, 1356383568, 2045787189, 41701596, 2897419387, 1607593844, 3662695680, 3047281611, 2550334039, 3570740927, 1611931707, 2189890620, 4237125709, 696324445, 4021392896, 1806994450, 2017807642, 2469125736, 734874395, 1366419998, 2557317677, 2318441391, 1527271185, 739939051, 403949506, 2981867143, 3479641228, 1959324850, 38609469, 1962013477, 3446172738, 1254910762, 498476574, 255458888, 3793625513, 1630158993, 2279485383, 3669744498, 1492854939, 4097328621, 3192323478, 2071597028, 630826397, 428827189, 2368696996, 3055253655, 593469606, 3076863624, 55835342, 2766583770, 154612766, 2291460996, 2457259482, 3820553176, 1285798282, 3380034060, 3785911726, 281115523, 1685346148, 346211580, 589754395, 3153381906, 133879663, 2099773182, 4085199561, 4289422268, 1845420994, 4276887982, 2578038523, 3104059048, 3840618724, 3517595196, 1437174425, 331861497, 3020629410, 3612884080, 2364533907, 650538235, 3732309667, 3952278564, 27956256, 873990544, 1106130616, 4062763861, 1345922125, 1949409112, 543740334, 2356386296, 362665448, 569292348, 2417069446, 856220117, 610337377, 3715002089, 75605257, 1359669327, 549235605, 4147201887, 828943849, 3241074648, 3798702438, 4062212606, 2292101898, 2536161810, 2058208049, 1371637722, 3537388759, 2330897706, 771687299, 1810758562, 4075266992, 3136752169, 2965867171, 1907532906, 541865577, 833813451, 912325166, 3504529207, 4146661260, 43513704, 1188055084, 1460669959, 1441372078, 965044416, 1376283370, 1008912061, 2828206579, 2979859088, 1336911334, 2267227202, 3590615152, 2027071742, 4165198949, 2476117139, 4113179387, 842152977, 3334863091, 3208261808, 2491700976, 2416025359, 909914002, 1456853392, 584405349, 3450410558, 1008058255, 2173899613, 3454522095, 852025171, 4068323283, 1835293050, 2776504669, 2896956540, 1059582696, 3355842312, 3785046506, 3150432227, 899248345, 765362151, 297765964, 1839721704, 4135076330, 3802971234, 174032740, 330869440, 806730448, 2836319408, 1204866576, 1453685093, 1780827587, 2465584847, 485334173, 2258975595, 1604958487, 3091044353, 3654969666, 3179521007, 2914051939, 3077520681, 3529930595, 91469044, 100193981, 599625224, 175812373, 730628631, 264187248, 1956283294, 3644810780, 50475246, 3129247701, 3163094393, 2355260862, 436241481, 2960675442, 507658429, 1438698679, 554120231, 3160228468, 2149714696, 3217008673, 2829426481, 2509658698, 160550864, 998344493, 3224059883, 3706071477, 4013203721, 3039203009, 1900724496, 599236194, 1909569250, 3861601181, 2563580453, 2673673488, 1811137326, 1551186191, 1335639405, 1814773819, 2487495823, 1553705944, 4152430522, 3813662590, 939620828, 837675780, 1556020329, 3795725159, 2611629000, 2383061798, 171350680, 3683361407, 2953427424, 156701361, 1394830409, 1479716728, 1663136970, 1905123702, 3880810480, 3741001193, 4195599478, 3119408159, 3345902277, 1692442050, 418072450, 466246575, 3584148391, 1286172340, 3298303405, 153813789, 251189750, 1406369637, 1255015138, 164783996, 3071333073, 2013577078, 4169783817, 67626950, 908042796, 1581987189, 2808914198, 3187755899, 4150429886, 1568391086, 2787622463, 44688232, 2752263608, 600382819, 2685059730, 2082696936, 1651886831, 3260180554, 1454325295, 339099905, 2416413405, 292264001, 224448308, 2820205760, 800750924, 1692655009, 2940110853, 3206125267, 1284023574, 188806571, 1018253822, 1218521588, 127630641, 4272005916, 1983115840, 3724335557, 1480875599, 258556015, 387690320, 3307867721, 4092260344, 411103465, 719069720, 4215323854, 4112776693, 2889404156, 3574835124, 1159298981, 2305866473, 3158909197, 2452926716, 3463698794, 4186406925, 619215353, 2136303535, 841071810, 4209975253, 1563920806, 2788664963, 2285692078, 164748453, 3260915529, 2078551236, 1108180616, 2313020701, 2711601953, 3040284072, 4061505008, 3080883125, 46794326, 2539557719, 4235587220, 3713965477, 483788504, 2241106354, 400682955, 3283095717, 1851426695, 1064000523, 972160394, 1076563962, 1753602608, 1375888517, 1174039560, 4004713212, 2778702664, 2391507606, 2502750773, 3138779242, 3696713679, 3532841104, 515077954, 2342382087, 3418303246, 1721076811, 4019877170, 3829378939, 843608060, 1700376709, 649828753, 3070886865, 3433695660, 3059502160, 216554272, 2738464975, 2474575567, 3905056712, 645624775, 94893154, 2265734034, 2278406680, 566706528, 1904629525, 1293783964, 2146173917, 811121006, 3729400006, 3517862941, 195028545, 791864928, 1645052848, 1415212344, 1820637799, 362298413, 3473886649, 452928246, 898416880, 233774116, 1645021426, 3987051044, 39196131, 121419869, 2351563057, 680652927, 857972607, 3029438980, 1229946962, 233655181, 521122864, 2183657742, 484407290, 914882001, 146950515, 1082974333, 874762514, 3422883704, 3485156975, 3435115319, 2818202953, 3586825327, 2480062760, 3425716891, 1450326644, 3016221424, 2839134064, 2757606141, 2225601033, 3015322180, 1475949095, 2911465824, 1922094339, 383821393, 4250196262, 1199207077, 1170250221, 4010073388, 3538244808, 1066047253, 3579784593, 1100739262, 442414517, 1424751121, 490632186, 77339557, 777239460, 94846550, 2041789208, 1088291027, 1088989393, 1996188731, 1922726080, 173542137, 1660633903, 42490668, 4175299400, 546941808, 389670698, 4087711464, 953403827, 2689272300, 146383210, 991964967, 589177132, 2666116981, 2742384553, 2256937027, 3362235285, 1768372794, 2301508627, 3039631246, 4029873796, 3542162044, 4011314855, 3208705188, 3093664599, 955117791, 1898323176, 481158655, 1739494699, 3999748502, 2748166481, 1468096930, 269614143, 2539058881, 2437163900, 116042410, 2888056328, 3166050770, 764018772, 2895875342, 295377743, 301081897, 3242097759, 4133492089, 121772966, 3507787903, 857540916, 1013203234, 2930783587, 160548021, 1098790273, 6930677, 377945170, 1426843203, 30674711, 4194624825, 2844475300, 4050845555, 540285564, 4153161923, 3285107975, 3804387100, 1041301233, 1372558892, 2049773675, 975400211, 1602341781, 2428168445, 727020991, 3642365909, 2995017542, 1121830157, 1135422177, 1446184945, 1954739253, 2512295081, 1243062575, 2888686736, 1345095331, 2776320960, 2520780914, 3030218952, 3507873505, 566559925, 607563266, 2760603675, 2559643053, 370523859, 4152951015, 420593291, 3641300208, 4090307006, 4030514342, 3982102048, 3448920208, 3333296945, 2890840327, 403831131, 3053314412, 3541216602, 451345357, 2160618328, 4219999429, 334887708, 303960012, 2746583794, 167680781, 2646881889, 2222628925, 1589802426, 3647326978, 4214450178, 3942275726, 1184937518, 414660795, 4279106429, 3994881863, 1665475094, 3978476438, 417885097, 1914795868, 102257118, 2758276810, 528295518, 3523517380, 721631837, 4139270503, 239587328, 1468101505, 2955694973, 244330841, 3087815728, 1829583230, 416887979, 2145765582, 324272834, 2842681465, 3300197476, 1981480955, 3111840730, 819777040, 2973685169, 414658425, 149938512, 571957804, 1917410782, 1997835257, 4207405089, 3980449531, 1117683541, 1723925501, 3325014266, 3363338245, 2344916144, 3220067359, 3726608337, 175710897, 2941327892, 1316886944, 1279444044, 610743939, 2680076058, 1001211105, 3037856246, 207632498, 2702573225, 2008747623, 1711166061, 3635886836, 2103874588, 3661613767, 3624138576, 620466897] | |
MT=[] | |
for i in mm: | |
MT.append(decrypted_second(decrypted_first(i,key_r),key_l)) | |
def generate(): | |
for i in range(624): | |
y = (MT[i] & 0x80000000) + (MT[(i + 1) % 624] & 0x7fffffff) | |
MT[i] = MT[(i + 397) % 624] ^ (y >> 1) | |
if y & 1: | |
MT[i] ^= 2567483520 | |
def rand(index=0): | |
if index == 0: | |
generate() | |
y = MT[index] | |
y = y ^ cs2l(y, 11) ^ cs2l(y, 15) | |
y = y ^ cs2r(y, 7) ^ cs2r(y, 19) | |
index = (index + 1) % 624 | |
return y | |
from hashlib import md5 | |
flag = 'flag{' + md5(str(rand()).encode()).hexdigest() + '}' | |
print(flag) |
# 二眼情深
class Myrand(): | |
def __init__(self, seed): | |
self.index = 0 | |
self.isInit = 1 | |
self.MT = [seed] + [0] * 623 | |
for i in range(1, 624): | |
t = 2037740385 * (self.MT[i - 1] ^ (self.MT[i - 1] >> 30)) + 1 | |
self.MT[i] = t & 0xffffffff | |
# print(self.MT) | |
def generate(self): | |
for i in range(624): | |
y = (self.MT[i] & 0x80000000) + (self.MT[(i + 1) % 624] & 0x7fffffff) | |
self.MT[i] = self.MT[(i + 397) % 624] ^ (y >> 1) | |
if y & 1: | |
self.MT[i] ^= 2567483520 | |
# print(self.MT) | |
def rand(self): | |
if self.index == 0: | |
self.generate() | |
y = self.MT[self.index] | |
y = y ^ self.cs2l(y, 11) ^ self.cs2l(y, 15) | |
y = y ^ self.cs2r(y, 7) ^ self.cs2r(y, 19) | |
self.index = (self.index + 1) % 624 | |
return y | |
def cs2l(self, y, shift): | |
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff | |
def cs2r(self, y, shift): | |
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff | |
import socketserver | |
import os | |
class Task(socketserver.BaseRequestHandler): | |
def _recvall(self): | |
BUFF_SIZE = 2048 | |
data = b'' | |
while True: | |
part = self.request.recv(BUFF_SIZE) | |
data += part | |
if len(part) < BUFF_SIZE: | |
break | |
return data.strip() | |
def send(self, msg, newline=True): | |
try: | |
if newline: | |
msg += b'\n' | |
self.request.sendall(msg) | |
except: | |
pass | |
def recv(self, prompt): | |
self.send(prompt, newline=False) | |
return self._recvall() | |
def handle(self): | |
secret = int(os.urandom(4).hex(), 16) | |
r = Myrand(secret) | |
out = [] | |
for i in range(624): | |
out.append(r.rand()) | |
try: | |
for i in range(2): | |
a = int((self.recv(b"Your " + ['first', 'second'][i].encode() + b" see: ")).decode()) | |
self.send(str(out[a % len(out)]).encode()) | |
guess = int((input("You konw my secret? ")).decode()) | |
if guess == secret: | |
self.send(b"For you ~") | |
flag = open("flag", "rb").read() | |
self.send(flag) | |
exit() | |
else: | |
self.send(["Try again~ ", "Bye~"][i].encode()) | |
except Exception as e: | |
exit() | |
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer): | |
pass | |
class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer): | |
pass | |
if __name__ == "__main__": | |
HOST, PORT = '0.0.0.0', 80 | |
server = ForkedServer((HOST, PORT), Task) | |
server.allow_reuse_address = True | |
print(HOST, PORT) | |
server.serve_forever() |
交互的到两个数据,要求出 seed
昨天刚做过的 NPUCTF2020 Mersenne twister
也是两个数据恢复 seed
脚本参考
我们获取 s0 和 s227
227+397 %624 =0
然后求出 s228
def backtrace(cur): | |
high = 0x80000000 | |
low = 0x7fffffff | |
mask = 2567483520 | |
state = cur | |
tmp = state[1]^state[0] | |
if tmp & high == high: | |
tmp ^= mask | |
tmp <<= 1 | |
tmp |= 1 | |
else: | |
tmp <<=1 | |
# recover highest bit | |
state= tmp | |
return state |
再逆_init_
def invert_right(res,shift): | |
tmp = res | |
for i in range(32//shift): | |
res = tmp^res>>shift | |
return res&0xFFFFFFFF | |
def recover(last): | |
n = 1<<32 | |
inv = invert(2037740385,n) | |
for i in range(228,0,-1): | |
last = ((last-i)*inv)%n | |
last = invert_right(last,30) | |
return last |
完整 exp
from Crypto.Util.number import inverse | |
from gmpy2 import invert | |
from pwn import * | |
def cs2l( y, shift): | |
shift %= 32 | |
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff | |
def cs2r( y, shift): | |
shift %= 32 | |
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff | |
#破解右移 | |
def decrypted_first(y, key): | |
for _ in range(32): | |
y = y ^ cs2r(y, key[0]) ^ cs2r(y, key[1]) | |
key = [k << 1 for k in key] | |
return y | |
# 破解左移 | |
def decrypted_second(y, key): | |
for _ in range(32): | |
y = y ^ cs2l(y, key[0]) ^ cs2l(y, key[1]) | |
key = [k << 1 for k in key] | |
return y | |
def backtrace(cur): | |
high = 0x80000000 | |
low = 0x7fffffff | |
mask = 2567483520 | |
state = cur | |
tmp = state[1]^state[0] | |
if tmp & high == high: | |
tmp ^= mask | |
tmp <<= 1 | |
tmp |= 1 | |
else: | |
tmp <<=1 | |
# recover highest bit | |
state= tmp | |
return state | |
def invert_right(res,shift): | |
tmp = res | |
for i in range(32//shift): | |
res = tmp^res>>shift | |
return res&0xFFFFFFFF | |
def recover(last): | |
n = 1<<32 | |
inv = invert(2037740385,n) | |
for i in range(228,0,-1): | |
last = ((last-1)*inv)%n | |
last = invert_right(last,30) | |
return last | |
re=remote("ctf.mxx307.com", 28041) | |
re.recvuntil(b'Your first see:') | |
re.sendline(b'0') | |
s=[] | |
s.append(int(re.recvline().decode().strip())) | |
re.recvuntil(b'You konw my secret?') | |
re.sendline(b'1') | |
re.recvuntil(b'Your second see:') | |
re.sendline(b'227') | |
s.append(int(re.recvline().decode().strip())) | |
key_r=[7,19] | |
key_l=[11,15] | |
for i in range(len(s)): | |
s[i]=decrypted_second(decrypted_first(s[i],key_r),key_l) | |
print(s) | |
s228=backtrace(s) | |
print(s228) | |
seed=(recover(s228)) | |
print(seed) | |
re.sendline(str(seed).encode()) | |
re.interactive() |