202312_古剑山杯_GuessTheKey
0x00. 题目
附件路径:https://pan.baidu.com/s/1GyH7kitkMYywGC9YJeQLJA?pwd=Zmxh#list/path=/CTF附件
附件名称:202312_guess_the_key_古剑山杯.zip
main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
if (argc != 3) {
printf("USAGE: %s INPUT OUTPUT\n", argv[0]);
return 0;
}
FILE* input = fopen(argv[1], "rb");
FILE* output = fopen(argv[2], "wb");
if (!input || !output) {
printf("Error\n");
return 0;
}
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);
}
return 0;
}
0x01. WP
c程序
给了一个加密逻辑,只要知道input
和output
这两个文件,就可以根据加密逻辑恢复key
.
观察到题目给了msg01
和msg01.enc
,前者是对应的input
,后者是对应的output
.
于是,可以得到key[0] = chr(0x9E-ord('H') & 0xff)
恢复key后,同样的逻辑,解一遍msg02.enc
就可以了
exp.py
with open("msg01", "r") as file:
msg = file.read()
with open("msg01.enc","rb") as file:
enc = file.read()
hex_data = enc.hex()
# for i in range(len(msg)):
# print(msg[i], hex_data[2*i:2*i+2])
message = 'Hi,there is nothing here,heiheihei.'
key = ''
for i in range(len(message)):
if i == 0:
key += 'V'
else:
key += chr(((enc[i] - i * i - ord(message[i])) ^ ord(message[i - 1])) & 0xff)
print(key)
with open("msg02.enc","rb") as file:
cipher2 = file.read()
hex_data = cipher2.hex()
m=""
key = 'VeryVeryLongKeyYouWillNeverKnow'
for i in range(len(cipher2)):
if i == 0:
k = chr((cipher2[i] - i * i - (ord(key[i % len(key)]) ^ 0)) & 0xff)
else:
k = chr((cipher2[i] - i * i - (ord(key[i % len(key)]) ^ ord(t))) & 0xff)
t = k
m += k
print(m)
# flag{101a6ec9f938885df0a44f20458d2eb4}