逆向加密 | ISCTF2024 | Reverse Ezre
2024年12月10日约 410 字大约 1 分钟
把文件拖进 IDA 分析可得以下内容:
程序运行时,会让你输入 flag,并将你输入的文本传给一个加密算法,如果验证和已加密文本v5
吻合,则提示Yeah,You get what you want!!!
我们可以观察到,验证结果在v2
上,如果v2
为True
,则通过验证。
if ( v2 )
v1 = "Yeah,You get what you want!!!";
我们继续查看v2
v2 = sub_140011217(v6, (unsigned int)v0, v5);
追踪该函数可得:
__int64 __fastcall sub_140011860(__int64 a1, int a2, _BYTE *a3)
{
__int64 v4; // rbx
_BYTE *v6; // rax
__int64 v7; // rdi
v4 = a2;
sub_1400112C1(&unk_14001E00F);
if ( (int)v4 <= 0 )
return 1LL;
v6 = a3;
v7 = a1 - (_QWORD)a3;
while ( v6[v7] == *v6 )
{
if ( ++v6 - a3 >= v4 )
return 1LL;
}
return 0LL;
}
这是一个比较函数,用于比对字符串是否符合要求。将v6
和v5
进行比对。
我们继续向上分析,v6
为我们输入的文本,
sub_140011073("%s", (const char *)v6);
然后会传入
sub_1400112E9(v6, (unsigned int)v0, v4);
推测这个就是加密函数,v4
就是密钥:
strcpy(v4, "ISCTF");
追踪sub_1400112E9
函数可得:
__int64 __fastcall sub_1400117A0(_BYTE *a1, int a2, __int64 a3)
{
__int64 result; // rax
int i; // r9d
int v8; // r8d
result = sub_1400112C1((__int64)&unk_14001E00F);
for ( i = 0; i < a2; ++a1 )
{
v8 = (char)*a1;
result = (unsigned int)(v8 - 65);
if ( (unsigned __int8)(*a1 - 65) <= 0x19u )
{
v8 += *(char *)(i % 5u + a3);
result = (unsigned int)(26 * (v8 / 26));
LOBYTE(v8) = v8 % 26 + 65;
}
*a1 = v8;
++i;
}
return result;
}
将加密模块用 Python 复现:
def generate_payload(target_text, key):
payload = ""
key_length = len(key)
for i, char in enumerate(target_text):
if 'A' <= char <= 'Z':
shift = ord(key[i % key_length])
original_char = (ord(char) - 65 - shift + 65) % 26 + 65
payload += chr(original_char)
else:
payload += char
return payload
target_text = "QKEMK{7JB5_i5_W3SllD_3z_W3}"
key = "ISCTF"
payload = generate_payload(target_text, key)
print("Generated Payload:", payload)
运行即可得到 flag.