intmain(int argc, char **argv) { if (argc != 3) { printf("USAGE: %s INPUT OUTPUT\n", argv[0]); return0; } FILE* input = fopen(argv[1], "rb"); FILE* output = fopen(argv[2], "wb"); if (!input || !output) { printf("Error\n"); return0; } char key[] = "guessthekey"; char d, q, t = 0; int ijk = 0; while ((q = fgetc(input)) != EOF) { d = (q + (key[ijk % strlen( key )] ^ t) + ijk*ijk) & 0xff; t = q; ijk++; fputc(d, output); } return0; }
题解
加密函数如下:
1 2 3 4 5 6
while ((q = fgetc(input)) != EOF) { d = (q + (key[ijk % strlen( key )] ^ t) + ijk*ijk) & 0xff; t = q; ijk++; fputc(d, output); }
给了四个文件,加密脚本,明文1和对应的密文,flag的密文
我们需要写一个求key的脚本来还原key,然后再用key去解密flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# python # 求密钥 withopen("msg01.enc", "rb") as f: result = f.read() cipher = [] for i in result: cipher.append(i) withopen("msg01","rb") as f: result1 = f.read() message = result1.decode() key = '' for i inrange(len(message)): if i == 0: key = key + chr((cipher[i] - ord(message[i])) & 0xff) else: key = key + chr(((cipher[i] - i * i - ord(message[i])) ^ ord(message[i - 1])) & 0xff) print(key) # VeryVeryLongKeyYouWillNeverKnowVeryV
然后就是解密flag,主要考察对代码的逆行分析
1 2 3 4 5 6 7 8 9 10 11 12
key = "VeryVeryLongKeyYouWillNeverKnow" withopen("msg02.enc", "rb") as f: result = f.read() cipher = [i for i in result] new_flag = "" for i inrange(len(cipher)): if i == 0: new_flag = new_flag + chr((cipher[i] - ord(key[i % len(key)])) & 0xff) else: new_flag = new_flag + chr((cipher[i] - i * i - (ord(key[i % len(key)]) ^ (ord(new_flag[i - 1])))) & 0xff) print(new_flag) # She had been shopping with her Mom in Wal-Mart. She must have been 6 years old, this beautiful brown haired, freckle-faced image of innocence. It was pouring outside. The kind of rain that gushes over the top of rain gutters, so much in a hurry to hit the Earth, it has no time to flow down the spout.flag{101a6ec9f938885df0a44f20458d2eb4}
s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_{}" p = "flag{" c = "kY0awfsdlY1FFL8C3bi4GSYCF{8W_E" k = [] for i inrange(len(p)): P = s.find(p[i]) C = s.find(c[i]) if P <= C: k.append(C - P) continue k.append((len(s) - P) + C) k += k[::-1]
p = "" for i inrange(len(c)): num = s.find(c[i]) - k[i % len(k)] if num < 0: num = len(s) + num p += s[num % len(s)] print(p) # flag{kynFTW2PRdH9lCZBf8IKDe6U}
R.<x> = Zmod(p)[] f = x ^ e - c f = f.monic() res1 = f.roots()
R.<x> = Zmod(q)[] f = x ^ e - c f = f.monic() res2 = f.roots()
# b是密文列表 m是模数列表 defcrtcrt(b, m): # 传入的参数分别为密文 和 模数n # 乘积计算 M = 1 for i inrange(len(m)): M *= m[i]
Mm = [] # 求余数 M/m[i] for i inrange(len(m)): Mm.append(M // m[i])
# 求Mm[i]的乘法逆元 Mm_ = [] for i inrange(len(m)): t, a, _ = gmpy2.gcdext(Mm[i], m[i]) Mm_.append(int(a % m[i]))
# 求的累加 y = 0 for i inrange(len(m)): y += (Mm[i] * Mm_[i] * b[i]) y = y % M return y, M
for i in res1: for j in res2: # 普普通通中国剩余定理 m = crtcrt([int(i[0]),int(j[0])],[p,q])[0] print(long_to_bytes(int(m))) # flag{9cddd5588513a46a54f02ef72330eaed}