测试链接:https://adworld.xctf.org.cn/media/task/attachments/33009710e3f44f04b5a4cdbaaa46f00a
1.准备获取信息
- 64位文件
__int64 __fastcall sub_400F8E(__int64 a1, __int64 a2) { char v3[136]; // [rsp+10h] [rbp-B0h] int v4; // [rsp+98h] [rbp-28h] char v5; // [rsp+9Fh] [rbp-21h] int v6; // [rsp+A0h] [rbp-20h] unsigned __int8 v7; // [rsp+A6h] [rbp-1Ah] char v8; // [rsp+A7h] [rbp-19h] int v9; // [rsp+A8h] [rbp-18h] int v10; // [rsp+ACh] [rbp-14h] int v11; // [rsp+B0h] [rbp-10h] int v12; // [rsp+B4h] [rbp-Ch] _BOOL4 v13; // [rsp+B8h] [rbp-8h] int i; // [rsp+BCh] [rbp-4h] sub_407470((__int64)"Give me the password: ", a2); sub_4075A0((__int64)"%s", v3); for ( i = 0; v3[i]; ++i ) ; v13 = i == 22; v12 = 10; do { v9 = (signed int)sub_406D90("%s", v3) % 22; v11 = 0; v8 = byte_6B4270[v9]; v7 = v3[v9]; v6 = v9 + 1; v10 = 0; while ( v10 < v6 ) { ++v10; v11 = 1828812941 * v11 + 12345; } v5 = v11 ^ v7; if ( v8 != ((unsigned __int8)v11 ^ v7) ) v13 = 0; --v12; } while ( v12 ); if ( v13 ) v4 = sub_407470((__int64)"Congras\n"); else v4 = sub_407470((__int64)"Oh no!\n"); return 0LL; }
3.代码分析
这道题主要是sub_406D90函数,对于第33行代码,我们能够知道v9是0~21的整数,在这道题中,v9的在循环当中值的顺序不会影响判断,因为v9用到的地方就两个,一个在已知数组byte_6B4270和输入字符串v3的取值中,另一个在v11的循环中,因为v11最终影响的是v11^v7!=v8,又因为v7和v3[v9]有关,v8和byte_6B4270[v9]有关,因此v11,byte_6B4270[v9]和v3[v9]都应该是固定的对应关系。
我们只需要让v9的值小于22即可,通过观察byte_6B4270,我们知道byte_6B4270数组实际长度应该就是22,又通过观察第36行代码,我们能够知道这道题实际就是取10位输入的字符,异或后,与byte_6B4270比较是否相同。
我们只需要逆向操作就行。
index = [0x5F,0xF2,0x5E,0x8B,0x4E,0x0E,0xA3,0xAA,0xC7,0x93,0x81,0x3D,0x5F,0x74,0xA3,0x09, 0x91,0x2B,0x49,0x28,0x93,0x67] flag = '' for i in range(22): v6 = i + 1 v10 = 0 v11 = 0 while v10 < v6: v10 = v10 + 1 v11 = 1828812941 * v11 + 12345 flag += chr((index[i]^v11)&0xff) print (flag)
#include <iostream> #pragma warning(disable:4996) using namespace std; int main() { int index[] = { 0x5F,0xF2,0x5E,0x8B,0x4E,0x0E,0xA3,0xAA,0xC7,0x93,0x81,0x3D,0x5F,0x74,0xA3,0x09, 0x91,0x2B,0x49,0x28,0x93,0x67 }; for (int i = 0; i < 22; ++i) { int v6 = i + 1; int v10 = 0; int v11 = 0; while (v10 < v6) { v10++; v11 = 1828812941 * v11 + 12345; } printf("%c", index[i] ^ v11); } system("PAUSE"); return 0; }
5.get flag!
flag{d826e6926098ef46}