Loading... # Reverse(五) BUUCTF ## 1. xor exeinfope查看无壳64位,ida64位打开,定位到main的伪C代码 ~~~c int __cdecl main(int argc, const char **argv, const char **envp) { int i; // [rsp+2Ch] [rbp-124h] char __b[264]; // [rsp+40h] [rbp-110h] BYREF memset(__b, 0, 0x100uLL); printf("Input your flag:\n"); get_line(__b, 256LL); if ( strlen(__b) != 33 ) goto LABEL_7; for ( i = 1; i < 33; ++i ) __b[i] ^= __b[i - 1]; if ( !strncmp(__b, global, 0x21uLL) ) printf("Success"); else LABEL_7: printf("Failed"); return 0; } ~~~ 可以看到输入的__b经过各位异或后和global对比,相同即可成功 查看global变量,正好33位,写出python逆向解密的脚本 ~~~python data = ['f', 0xA, 'k', 0xC, 'w', '&', 'O', '.', '@', 0x11, 'x', 0xD, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v', '"', 'M', '#', 'D', 0xE, 'g', 6, 'h', 0xF, 'G', '2', 'O'] flag = 'f' for i in range(0, len(data)): if isinstance(data[i], str): data[i] = ord(data[i]) for i in range(1, len(data)): flag += chr(data[i] ^ data[i - 1]) print(flag) ~~~ 得到flag{QianQiuWanDai_YiTongJiangHu} 也可以shift+E选中C unsigned char array(hex),可以直接 全部复制为十或十六进制 ## 2. helloworld 使用ida打开apk文件时,开始要注意选择文件格式 ![image-20220328151036869.png](http://xherlock.top/usr/uploads/2022/03/766694811.png) shift+F12查找跟flag相关的字符串即可 ## 3. reverse3 无壳32位,ida打开查看字符串,看到了和base64相关的信息,初步猜想有这方面的加密解密 ![image-20220328153148029.png](http://xherlock.top/usr/uploads/2022/03/543461412.png) ~~~c int __cdecl main_0(int argc, const char **argv, const char **envp) { size_t v3; // eax const char *v4; // eax size_t v5; // eax char v7; // [esp+0h] [ebp-188h] char v8; // [esp+0h] [ebp-188h] signed int j; // [esp+DCh] [ebp-ACh] int i; // [esp+E8h] [ebp-A0h] signed int v11; // [esp+E8h] [ebp-A0h] char Destination[108]; // [esp+F4h] [ebp-94h] BYREF char Str[28]; // [esp+160h] [ebp-28h] BYREF char v14[8]; // [esp+17Ch] [ebp-Ch] BYREF for ( i = 0; i < 100; ++i ) { if ( i >= 0x64 ) j____report_rangecheckfailure(); Destination[i] = 0; } sub_41132F("please enter the flag:", v7); sub_411375("%20s", Str); v3 = j_strlen(Str); v4 = sub_4110BE(Str, v3, v14); strncpy(Destination, v4, 0x28u); v11 = j_strlen(Destination); for ( j = 0; j < v11; ++j ) Destination[j] += j; v5 = j_strlen(Destination); if ( !strncmp(Destination, Str2, v5) ) sub_41132F("rigth flag!\n", v8); else sub_41132F("wrong flag!\n", v8); return 0; } ~~~ `v4 = sub_4110BE(Str, v3, v14);`中的sub_4110BE是base64加密函数,然后for循环对每一位进行了移位操作后与Str2对比,查看Str2 ![image-20220328155715289.png](http://xherlock.top/usr/uploads/2022/03/3542338878.png) 首先脚本解密移位 ~~~python data = 'e3nifIH9b_C@n@dH' k = 0 flag = '' for i in data: flag += chr(ord(i) - k) k += 1 print(flag) ~~~ 得e2lfbDB2ZV95b3V9,再base64解密得{i_l0ve_you} ## 4. 不一样的flag 32位无壳, ~~~c int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { _BYTE v3[29]; // [esp+17h] [ebp-35h] BYREF int v4; // [esp+34h] [ebp-18h] int v5; // [esp+38h] [ebp-14h] BYREF int i; // [esp+3Ch] [ebp-10h] _BYTE v7[12]; // [esp+40h] [ebp-Ch] BYREF __main(); v3[26] = 0; *(_WORD *)&v3[27] = 0; v4 = 0; strcpy(v3, "*11110100001010000101111#"); while ( 1 ) { puts("you can choose one action to execute"); puts("1 up"); puts("2 down"); puts("3 left"); printf("4 right\n:"); scanf("%d", &v5); if ( v5 == 2 ) { ++*(_DWORD *)&v3[25]; } else if ( v5 > 2 ) // 大于2的输入为3、4才可 { if ( v5 == 3 ) { --v4; } else { if ( v5 != 4 ) LABEL_13: exit(1); ++v4; } } else { if ( v5 != 1 ) goto LABEL_13; --*(_DWORD *)&v3[25]; } for ( i = 0; i <= 1; ++i ) { if ( *(int *)&v3[4 * i + 25] < 0 || *(int *)&v3[4 * i + 25] > 4 ) exit(1); } if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == 49 ) exit(1); if ( v7[5 * *(_DWORD *)&v3[25] - 41 + v4] == 35 ) { puts("\nok, the order you enter is the flag!"); exit(0); } } } ~~~ 转换十进制数为char,可以看出最后要到#位置,如果到了1就会失败退出 ![image-20220328160934010.png](http://xherlock.top/usr/uploads/2022/03/2190400427.png) 呃,貌似是走迷宫,就是这串字符`*11110100001010000101111#`排列成5*5 | * | 1 | 1 | 1 | 1 | | --- | --- | --- | --- | --- | | 0 | 1 | 0 | 0 | 0 | | 0 | 1 | 0 | 1 | 0 | | 0 | 0 | 0 | 1 | 0 | | 1 | 1 | 1 | 1 | # | 这么走flag就是222441144222 ![image-20220328162107313.png](http://xherlock.top/usr/uploads/2022/03/1496228106.png) ## 5. SimpleRev 无壳64位,ida64查看伪代码 ![image-20220328171205967.png](http://xherlock.top/usr/uploads/2022/03/2569703670.png) 第一页没什么线索,关键在于进入了Decry的函数,这个函数里有了flag和输入的对比 ~~~c unsigned __int64 Decry() { char v1; // [rsp+Fh] [rbp-51h] int v2; // [rsp+10h] [rbp-50h] int v3; // [rsp+14h] [rbp-4Ch] int i; // [rsp+18h] [rbp-48h] int v5; // [rsp+1Ch] [rbp-44h] char src[8]; // [rsp+20h] [rbp-40h] BYREF __int64 v7; // [rsp+28h] [rbp-38h] int v8; // [rsp+30h] [rbp-30h] __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF int v10; // [rsp+50h] [rbp-10h] unsigned __int64 v11; // [rsp+58h] [rbp-8h] v11 = __readfsqword(0x28u); *(_QWORD *)src = 0x534C43444ELL; v7 = 0LL; v8 = 0; v9[0] = 0x776F646168LL; v9[1] = 0LL; v10 = 0; text = (char *)join(key3, v9); strcpy(key, key1); strcat(key, src); v2 = 0; v3 = 0; getchar(); v5 = strlen(key); for ( i = 0; i < v5; ++i ) { if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 ) key[i] = key[v3 % v5] + 32; ++v3; } printf("Please input your flag:"); while ( 1 ) { v1 = getchar(); if ( v1 == 10 ) break; if ( v1 == 32 ) { ++v2; } else { if ( v1 <= 96 || v1 > 122 ) { if ( v1 > 64 && v1 <= 90 ) { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } } else { str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97; ++v3; } if ( !(v3 % v5) ) putchar(32); ++v2; } } if ( !strcmp(text, str2) ) puts("Congratulation!\n"); else puts("Try again!\n"); return __readfsqword(0x28u) ^ v11; } ~~~ 定位到对比的是text和str2 先看`text = (char *)join(key3, v9);`,由key3和v9组成 ![image-20220328172137704.png](http://xherlock.top/usr/uploads/2022/03/3054537329.png) key3='kills',`v9[0] = 0x776F646168LL;`转换为char同时大端改小端,v9=hadow,合起来**text='killshadow'**,挺对头的 再看str2,定位到包含str2的部分代码 ![image-20220328171459233.png](http://xherlock.top/usr/uploads/2022/03/996449982.png) 看到了97、26等貌似和大小写有关的字眼,同时关键在key字符串,定位到key ![image-20220328174022769.png](http://xherlock.top/usr/uploads/2022/03/406083258.png) key1先复制到key,key再和src组合起来,查看key1和src的值 ![image-20220328173627938.png](http://xherlock.top/usr/uploads/2022/03/1553828375.png) key1='ADSFK' ![image-20220328173704938.png](http://xherlock.top/usr/uploads/2022/03/2309108608.png) src='SLCDN',结合大端改小端,得到key='ADSFKNDCLS',又经过28-34行转换为小写**key='adsfkndcls'** 下面分析如何输入生成str2,str2就是text的值 ![image-20220328174937604.png](http://xherlock.top/usr/uploads/2022/03/653770128.png) ~~~python str2 = 'killshadow' key = 'adsfkndcls' input = '' for i in range(len(str2)): for j in range(26): if str2[i] == chr((j + 65 - 39 - ord(key[i % len(key)]) + 97) % 26 + 97): input += chr(j+65) print(input) ~~~ flag{KLDQCUDFZO} 最后修改:2023 年 12 月 14 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏