# Decompiled with PyLingual (https://pylingual.io) # Internal filename: '/tmp/r2_gen.py' # Bytecode version: 3.12.0rc2 (3531) # Source timestamp: 2026-10-28 05:33:23 UTC (1793165603) import sys _PROG = b'0\x10576>46.32\xcc1\xb0566\xdc46!32\xcc1\xda556\\46X32\xcc1\xf8546\x8446\xf432\xcc1\xbb536B46I32\xcc1\x92526f46\xcf32\xcc1\xa6516f46M32\xcc1\x1a506h46\xc032\xcc1i5?6\x9846&32\xcc1[5>6\x8246\x9532\xcc1\x8e5=6\xfe46\xb232\xcc1\xfa5<6\x1c46\xad32\xcc1\xe85;6\xc646\x9232\xcc1$5:6X46u32\xcc1\xba596N46)32\xcc1\x18586\xd046\x9732\xcc1\x8b5\'6\x1046632\xcc1\xa95&6\x1446\xc532\xcc1\x025%6\xf046\x9532\xcc1\'5$6\xb446\xa732\xcc1\x845#6T46332\xcc1\'5"6\xe846\xc032\xcc1W5!6\x9c46"32\xcc1B5 6\xce46h32\xcc1I5/6\x9e46\xfc32\xcc1\xfb5.6x46\xcf32\xcc1\xe85-6\xaa46\xe332\xcc1\x135,6J46\xf132\xcc1;5+6\x9246\x8d32\xcc1\xcd5*6X46\xaf32\xcc1\x1f5)6\x1a46\xd132\xcc1\x905(6\x1446\xb032\xcc1\r5\x176\x8246:32\xcc1\x1e5\x166046o32\xcc1\x1d5\x156P46~32\xcc1r5\x146\x1246y32\xcc1*5\x136046\x8232\xcc1\x135\x126\x9c46`32\xcc1\x8e5\x116b46G32\xcc1\xf47' _XK = 55 def _run(s): prog = bytes((b ^ _XK for b in _PROG)) pc = 0 st = [] while pc < len(prog): op = prog[pc] pc += 1 if op == 0: return True if op == 1: st.append(prog[pc]) pc += 1 else: if op == 2: st.append(ord(s[prog[pc]])) pc += 1 else: if op == 3: b = st.pop() a = st.pop() st.append(a * b) else: if op == 4: b = st.pop() a = st.pop() st.append(a + b) else: if op == 5: m = prog[pc] pc += 1 st.append(st.pop() % m) else: if op == 6: t = prog[pc] pc += 1 if st.pop() != t: return False else: if op == 7: if len(s) != prog[pc]: return False else: pc += 1 else: return False return True def main(): try: s = sys.stdin.readline().rstrip('\n') except Exception: print('[-] read error') return None if _run(s): print('[+] Correct! The flag is what you entered.') else: print('[-] Wrong.') main()
字节码是栈式虚拟机,程序先与 55 异或。长度必须是 39,每个字符满足 (s[i]*a+b) mod 251 == t
_PROG = ( b'0\x10576>46.32\xcc1\xb0566\xdc46!32\xcc1\xda556\\46X32\xcc1\xf8546\x8446\xf432' b'\xcc1\xbb536B46I32\xcc1\x92526f46\xcf32\xcc1\xa6516f46M32\xcc1\x1a506h46\xc032' b'\xcc1i5?6\x9846&32\xcc1[5>6\x8246\x9532\xcc1\x8e5=6\xfe46\xb232\xcc1\xfa5<6\x1c46' b'\xad32\xcc1\xe85;6\xc646\x9232\xcc1$5:6X46u32\xcc1\xba596N46)32\xcc1\x18586\xd046' b'\x9732\xcc1\x8b5\'6\x1046632\xcc1\xa95&6\x1446\xc532\xcc1\x025%6\xf046\x9532\xcc1\'5$6' b'\xb446\xa732\xcc1\x845#6T46332\xcc1\'5"6\xe846\xc032\xcc1W5!6\x9c46"32\xcc1B5 6' b'\xce46h32\xcc1I5/6\x9e46\xfc32\xcc1\xfb5.6x46\xcf32\xcc1\xe85-6\xaa46\xe332\xcc1\x135,6' b'J46\xf132\xcc1;5+6\x9246\x8d32\xcc1\xcd5*6X46\xaf32\xcc1\x1f5)6\x1a46\xd132\xcc1\x905(6' b'\x1446\xb032\xcc1\r5\x176\x8246:32\xcc1\x1e5\x166046o32\xcc1\x1d5\x156P46~32\xcc1r5\x146' b'\x1246y32\xcc1*5\x136046\x8232\xcc1\x135\x126\x9c46`32\xcc1\x8e5\x116b46G32\xcc1\xf47' ) prog = bytes(b ^ 55 for b in _PROG) s = {} pc = 0 while pc < len(prog): op = prog[pc] pc += 1 if op == 0: break elif op == 7: length = prog[pc] pc += 1 elif op == 2: idx = prog[pc] pc += 1 k = prog[pc + 1] # 跳过 op=1 pc += 3 # 跳过 op=1, k, op=3 (mul) c = prog[pc + 1] # 跳过 op=1 pc += 3 # 跳过 op=1, c, op=4 (add) m = prog[pc + 1] # 跳过 op=5 pc += 2 # 跳过 op=5, m target = prog[pc + 1] # 跳过 op=6 pc += 2 # 跳过 op=6, target # 逆元求解:s[idx] = (target - c) * inv(k, m) % m s[idx] = chr(((target - c) * pow(k, -1, m)) % m) flag = "".join(s[i] for i in range(len(s))) print("Flag:", flag) DASCTF{pyvm_st4ck_m4ch1ne_byt3c0de_r3v}
crypto1
from secrets import flag from Crypto.Util.number import bytes_to_long, getRandomNBitInteger, getPrime import random def pad(data, size): pad_len = size - (len(data) % size) return data + bytes([random.randint(0, 255) for _ in range(pad_len)]) seg1 = pad(flag[:30], 100) values = [] for j in range(0, 100, 5): values.append(bytes_to_long(seg1[j: j + 5])) M = getPrime(40) keys = [getRandomNBitInteger(39) for _ in range(20)] loops = 130 for _ in range(loops): values.append(sum([x * y for x, y in zip(values[-20:], keys)]) % M) eseg1 = values[-22:] print(eseg1) print(keys) seg2 = pad(flag[30:], 100) values = [] for j in range(0, 100, 5): values.append(bytes_to_long(seg2[j: j + 5])) M = getPrime(40) keys = [getRandomNBitInteger(39) for _ in range(20)] for _ in range(loops): values.append(sum([x * y for x, y in zip(values[-20:], keys)]) % M) eseg2 = values[-40:] print(eseg2) print(M) ''' [376818201137, 373344659626, 267751741740, 578914814802, 315112932866, 1040644906770, 785822797437, 703235478908, 1025017459989, 615643804776, 729620589120, 436758957365, 286053138707, 237730655096, 85452568658, 473485643292, 680463972459, 144293060194, 260746425929, 72717474649, 1061708641255, 1070184096679] [344008490453, 514528133902, 527766050648, 449836608158, 414790402412, 284483393556, 333992848547, 549590511012, 425579415762, 400257628105, 531004324273, 361228357121, 543300341694, 326078138779, 415922195304, 499436322997, 433506027649, 346362953794, 399551972561, 484478359653] [128972742722, 135692086889, 178201495884, 584932066956, 428586471096, 800484953006, 379495867605, 271330740235, 505580115374, 443635759721, 119836360932, 19483937943, 428673105875, 452575805751, 601100197632, 689091914107, 134051842641, 17922454309, 50922359494, 113727814794, 609464504934, 447316793495, 211083727647, 256142256178, 747919828942, 530404205659, 205059332156, 260116005558, 626198465968, 662009491493, 404432792077, 30127043306, 681480368422, 263657409021, 45812925601, 205182746105, 775611547813, 319064382213, 449446096453, 125158160344] 811747846477 '''
task.py 把 flag 切成两段,每段按 5 字节一组,再做 20 阶线性递推:
将输入分段填充至100字节后,每5字节(40 bits)打包为一个整数,形成20维初始向量 ;
再随机选取一个40-bit素数模数 和20个随机系数 ;
随后执行130轮齐次线性递推 (),
对应伴随转移矩阵(Companion Matrix) 𝑇
import math from Crypto.Util.number import long_to_bytes # ================= 通用工具模块 ================= def recover_modulus(seq, keys): """ 通用函数:已知部分递推系数 keys 与一段连续输出 seq, 利用整数环上的残差差值求 GCD 恢复模数 M """ order = len(keys) diffs = [] for i in range(len(seq) - order): expected = sum(x * y for x, y in zip(seq[i : i + order], keys)) diffs.append(expected - seq[i + order]) # 连续做 GCD g = diffs[0] for d in diffs[1:]: g = math.gcd(g, d) # 除去可能的小因子 for p in [2, 3, 5, 7, 11, 13]: while g % p == 0: g //= p return g def solve_linear_system_gf_p(A, b, p): n = len(b) # 构造增广矩阵 mat = [A[i][:] + [b[i]] for i in range(n)] for col in range(n): # 寻找主元 pivot = None for r in range(col, n): if mat[r][col] % p != 0: pivot = r break if pivot is None: raise ValueError("矩阵奇异或线性相关,无法唯一确定解") mat[col], mat[pivot] = mat[pivot], mat[col] # 归一化主对角线 inv = pow(mat[col][col], -1, p) mat[col] = [(x * inv) % p for x in mat[col]] # 消去其他行 for r in range(n): if r != col and mat[r][col] % p != 0: factor = mat[r][col] mat[r] = [(x - factor * y) % p for x, y in zip(mat[r], mat[col])] return [mat[i][-1] % p for i in range(n)] def lfsr_step_back(state, keys, p, steps): cur = list(state) order = len(keys) inv_c0 = pow(keys[0], -1, p) for _ in range(steps): v_next = cur[-1] # v_next = sum_{k=0}^{order-1} cur[k-1] * keys[k] (mod p) rest = sum(cur[k - 1] * keys[k] for k in range(1, order)) % p v_prev = ((v_next - rest) * inv_c0) % p cur = [v_prev] + cur[:-1] return cur # 题目数据 eseg1 = [376818201137, 373344659626, 267751741740, 578914814802, 315112932866, 1040644906770, 785822797437, 703235478908, 1025017459989, 615643804776, 729620589120, 436758957365, 286053138707, 237730655096, 85452568658, 473485643292, 680463972459, 144293060194, 260746425929, 72717474649, 1061708641255, 1070184096679] keys1 = [344008490453, 514528133902, 527766050648, 449836608158, 414790402412, 284483393556, 333992848547, 549590511012, 425579415762, 400257628105, 531004324273, 361228357121, 543300341694, 326078138779, 415922195304, 499436322997, 433506027649, 346362953794, 399551972561, 484478359653] eseg2 = [128972742722, 135692086889, 178201495884, 584932066956, 428586471096, 800484953006, 379495867605, 271330740235, 505580115374, 443635759721, 119836360932, 19483937943, 428673105875, 452575805751, 601100197632, 689091914107, 134051842641, 17922454309, 50922359494, 113727814794, 609464504934, 447316793495, 211083727647, 256142256178, 747919828942, 530404205659, 205059332156, 260116005558, 626198465968, 662009491493, 404432792077, 30127043306, 681480368422, 263657409021, 45812925601, 205182746105, 775611547813, 319064382213, 449446096453, 125158160344] M2 = 811747846477 loops = 130 # ---- 解第一部分 ---- M1 = recover_modulus(eseg1, keys1) # 取最后 20 个元素作为终止状态 init_state1 = lfsr_step_back(eseg1[2:], keys1, M1, loops) flag_part1 = b"".join(long_to_bytes(x, 5) for x in init_state1[:6]) # flag 前 30 字节对应前 6 个元素 # ---- 解第二部分 ---- # 构建 20x20 线性方程组恢复 keys2 A = [eseg2[i : i + 20] for i in range(20)] b = eseg2[20 : 40] keys2 = solve_linear_system_gf_p(A, b, M2) init_state2 = lfsr_step_back(eseg2[20:], keys2, M2, loops) flag_part2 = b"".join(long_to_bytes(x, 5) for x in init_state2) flag_part2 = flag_part2[:flag_part2.index(b'}') + 1] # 截断至 '}' print("Flag:", (flag_part1 + flag_part2).decode())
crypto2
import json with open("params.json") as f: d = json.load(f) p = int(d["p"], 16) g = int(d["g"], 16) h = int(d["public_key_h"], 16) c1 = int(d["ciphertext"]["c1"], 16) c2 = int(d["ciphertext"]["c2"], 16) x = None if x is not None: m = c2 * pow(pow(c1, x, p), -1, p) % p print(m.to_bytes((m.bit_length() + 7) // 8, "big").decode()) { "incident": "EM-G3-2026-1018", "algorithm": "ElGamal-2048", "group": "RFC3526-14", "p": "0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff", "g": "0x48d408ae69bcb4aaba7f5c953afb601b114f1014c341401c3706e98a9a3860ad74ec07f6ec182a024a058ba990ef1815507c4bcb913ff98fbd975b646d874c22a34a43dd26f0d222cc95bfa8d10bff546758d5d2408cb38947f51dad6dee08093aaf1520b323dba9b53d25c12d8746197099132610dd65ee7271e968ce647a9b27373398747c14df36ee724aef10f8bfb3b4a45306e1ec0db500d0038d5f8eab39e3b164bf0f6c8d64111df8602d58934366c7564d19e2c5f20bec1902eea35da70488b4c934351e03549efd06420536f59da469e00d6656038c3587321adf3fd6544260fe808894a75f87ae5732d2e211fbcdd6f7858055768370feaa10edc", "public_key_h": "0xaad5b70b0f73b7542d053f9915da28f4fde941fb43010f2dbc282cc678f1d9e38244bd64059c65f1d3ac56543a4faafe1f7942de4bdc45f55bb3c792e0b0093fcf523f75f27c714e8d3c97443a6f7847d2c45c526201da0a00fc7004e9d4ba11f66ccf98c9bdd8a6dbf86dba08a137e3df4e6fa642372fa04462733a6d689a7db8593ec37bcdb77118ed23ba04b0bd9fb283f726fed22093699a3225513ea90c02983695fbd1010d8c50e3237d2ee251f5827619f6b88cf99f539a678154401af26425b9f883268f88479df5d0c708442f10bf3cbeb485815c6f89029ed39c7995c841df51adc37b9fe7a4e458c37ff1bb58024e7d96420861952dd55abee1a8", "ciphertext": { "c1": "0xc03872ba41ef41c96ffafbb01313576b3beeeae21462a61995225e07eaf1571beef0e2907b81a6a002e4745d954163d4e0f467cbca81f081a8a554700eee5a5d0a207bbfc3040a7a8d4700b63631838d5fad1fd045dd07aa97245fe3524d4e28259d6d36581875a287147ee33ebb0757b33ea8686cac9df331104fb46ce179dd0f9d9d753bce384dcecd048ba012b4d963bbcfcc303d16738998549221b38cab3d196aeb3f04b7efab17eb18ce674371ea40b85a42fd64a4c7f874dc242bf502ba7853c67052ebc811535c226321ef4c5caa54d42f480f0935993481195951f2215f2cb726656de8981a96ed9452c340dd197eb3cc5ea23168035fcd9fdd811a", "c2": "0x70eb6418da6678325c08408d3046ec75d6710a2b89e20fdacc059767fc8e34f596124f3ed466884fe95b2a45935d2edf9c67efd6425a614feed90c2b237df97157bb022254e354fc254a7656b43c7fe2572b35b4978f9da7ed3f8eed36e8515f4e5b4374c1a3c5941b57dc51f667a736fe177292b292849584782294d538fe91dbc046118fdcd45e52fb4df9bfcf7772503b58ea3cf150611db82ab3b0bd4c540444a9110079108ec4da406a368e7dba9a936cad249badd9c5b3f23e21454dd38c52af4e58831b78d813173da4252d22f4596b8f74c82e5ca2ec05ed3ce01504e7fd1f8235aff1b6e1c4f9fd87eeb9ee8e568b261d6b61d52993bc40919064d4" }, "note": "Legacy incident-recovery channel sealed during the April 2025 key ceremony. The private exponent came from the same broken RNG stage; entropy is measured in bits, not bytes." }
import json with open("params.json") as f: d = json.load(f) p = int(d["p"], 16) g = int(d["g"], 16) h = int(d["public_key_h"], 16) ur = (cur * g) % p cur = 1 for x in range(1, 100000): cur = (cur * g) % p if cur == h: print(f"[+] 成功命中!私钥 x = {x}") break
[+] 成功命中!私钥 x = 139
import json with open("params.json") as f: d = json.load(f) p = int(d["p"], 16) g = int(d["g"], 16) h = int(d["public_key_h"], 16) c1 = int(d["ciphertext"]["c1"], 16) c2 = int(d["ciphertext"]["c2"], 16) print(p) print(g) print(h) print(c1) print(c2) ''' P=32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559 G=574607236009822402597890565725727390768601887938144496075042620087932620463633235408520204173792638953479962544943047847177262504420188859153766321242826649193796718601580398374772349159742092973382946312178314046903160951606981204577885034703166985215149810706832236500449215770801739079362365949416802237156670274424439963829273423802133509320093188635742167546198316386883136029000560186565931296413859902483881269691752480161239247293983852542728393673984945984050833081948887833942778221422312994772555813104513202731114920293263072661292543397635219281567658776629981698030926201288502839449916121900459822812 H=21565898644722283717744952176648485763635294731582331269415742268820070120087387326431935553811363200949441999347314134477603463894798917417489050203821500951519824237010554099470100493695039375662069664619106637989576681376956637296248118450943117105986112456768299895800309057676891348120316302235651953848283932181297075236161147264777572274661179770571745842937713531844318433613308231224044751774542378269242555337484261147888536423917846856684449548439021682647011775254685516415197568202316669002463204990097448094039635049102357014274796820163176619527170236508117933434698741549405529493192486955798998475176 C1=24265590175947002118906835748085671231121922933187873180438937253545489780106347816330117106157268105500059452712287321176824820100389435904268502261846538267608303573279952858589819595643862325064108319236871884180231290401517735124370043654644703825703241699128709891716728977719930031889501125463787915607725977310247925241710870729938890619268407295725249178362131081309626269704029734054089488590886699845707658491151320065519005702697838682790077827384436057755667828319274619858923920987435936139014330494939942798054835284287166575675995230711924845410402284449530082337396011045175476017112768220783129231642 c214254765786581682196761578215234943350753449949323405680860010569686580331000938002464944626324317272063002634495838981192006277880830810115251053843619992363647706299968498253620403067728706878023090990952035919670517030403068748983429015476465295705884012834411584607504193653198412029435058197786767128273176287549303116857983920370257282532540114680565692104543174781629128403564444008317729967633162694441082959178048169482174064703566047738062295781730661587282965504649410078988177686060117795579400680221704514949491088525781664926802635103398892123114583627386848539165434725923786756139144769164991372747988 ''' x = 139 if x is not None: m = c2 * pow(pow(c1, x, p), -1, p) % p print(m.to_bytes((m.bit_length() + 7) // 8, "big").decode())
misc1-pyjail
Can you eeeeescape the jail? >> Traceback (most recent call last): File "/jail.py", line 12, in <module> exec(text) File "<string>", line 1, in <module> NameError: name 'a' is not defined
import sys, collections from scapy.all import rdpcap, TCP, ICMP, Raw PCAP = sys.argv[1] pkts = rdpcap(PCAP) # ---- 1. decode ICMP covert channel (same mapping as solve.py) ---- val_map = {21: 0, 85: 1, 149: 2, 213: 3} req = [p for p in pkts if p.haslayer(ICMP) and p[ICMP].type == 8] lens = [len(p[Raw].load) if p.haslayer(Raw) else 0 for p in req] vals = [val_map[L] for L in lens] out = bytearray() for i in range(0, len(vals), 4): out.append((vals[i] << 6) | (vals[i+1] << 4) | (vals[i+2] << 2) | vals[i+3]) S = bytes(out) print("ICMP decoded bytes:", S) # ---- 2. sub_7DA forward check, direction: plaintext = S ---- def enc_byte(c, k): return (((k & 0xFF) ^ c) + k % 93) % 94 + 0x21 def encrypt(s, k): return bytes(enc_byte(c, k) for c in s[:24]) hits = [] for k in range(10001): e = encrypt(S, k) if e.startswith(b"|y~~ww}") and e[23] == ord("w") and b"j" not in e and b"+" not in e: hits.append(k) flag_chars = [] for i in range(7, 23): var8 = i if i <= 11 else 11 flag_chars.append(chr((e[i] + var8 - 6) & 0xFF)) print("HIT k =", k, "enc =", e, "flag =", "DASCTF{" + "".join(flag_chars) + "}") print("hits:", hits) # ---- 3. list all TCP streams with payload size, for choosing FTP/HTTP sources ---- streams = collections.defaultdict(bytes) for p in pkts: if p.haslayer(TCP) and p.haslayer(Raw): key = (p[TCP].sport, p[TCP].dport) streams[key] += bytes(p[Raw].load) for key, data in sorted(streams.items(), key=lambda kv: -len(kv[1])): head = data[:60] print(key, len(data), head)
random.seed(0) m = list(range(int(h * 0.5))) n = list(range(w)) random.shuffle(m) random.shuffle(n) for i in range(int(h * 0.5)): for j in range(w): wm[m[i], n[j]] = diff[i, j]