-
-
[原创] 京东-看雪 -2018 春季赛 - 第四题 - 密届寻踪
-
发表于: 2018-6-24 10:37 2855
-
逆向还是太菜了,还要走很长的路。。。
题目全程靠猜。。没什么时间,先占个坑,后面有时间再重新分析一遍
运行一下程序
************看雪-京东CTF2018************* serial:11111111 error请按任意键继续. . .
可以输入一个 字符串,输完会给你error 或者 success
逻辑大概是下面这样的
while ( (unsigned int)(v3 - v2) > 0xFFF ); *(_DWORD *)(a1 - 20) = 'g`wr'; *(_DWORD *)(a1 - 16) = 'tu`'; *(_WORD *)(a1 - 12) = 0; *(_DWORD *)(a1 - 32) = 'kqpd'; *(_WORD *)(a1 - 28) = 'w'; *(_DWORD *)(a1 - 26) = 0; *(_BYTE *)(a1 - 56) = 0; *(_DWORD *)(a1 - 55) = 0; *(_DWORD *)(a1 - 51) = 0; *(_DWORD *)(a1 - 47) = 0; *(_DWORD *)(a1 - 43) = 0; *(_DWORD *)(a1 - 39) = 0; *(_WORD *)(a1 - 35) = 0; *(_BYTE *)(a1 - 33) = 0; *(_BYTE *)(a1 - 60) = 0; *(_WORD *)(a1 - 59) = 0; printmsg(); j_startinfo(); msg_str(a1 - 20); // success msg_str(a1 - 32); // error scanf("%s", a1 - 56, 24); // a1-56 === input if ( strlen((const char *)(a1 - 56)) > 0x17 ) { printf((const char *)(a1 - 32)); // len(input) < 0x17 exit(0); } len_3_ = strlen((const char *)(a1 - 53)); // input[3:] tohex(a1 - 53, (int)&hex_3__495660, len_3_); *(_DWORD *)(a1 - 4) = sub_40125D(); // iamahandsomeguyhaha1 memcpy((void *)(a1 - 60), (const void *)(a1 - 56), 3u);// a1-60 == input[:3] if ( isdigit(a1 - 60) ) { // 判断前三位是不是 数字 *(_DWORD *)(a1 - 8) = sub_40128F(a1 - 60); // 对数字进行操作 if ( *(_DWORD *)(a1 - 8) + *(_DWORD *)(a1 - 4) == 2 )// 如果两次返回的都是1 即可 printf((const char *)(a1 - 20)); else printf((const char *)(a1 - 32)); system("pause"); result = 0; } else { printf((const char *)(a1 - 32)); result = 0; } return result; }
用 msg_str 这个函数来生成 success ,error 字符串
这个函数也比较简单,读入一段字符,按 (index+1) 异或即可
后面读取一段长度 <0x17 的 字符串
转换成 hex 编码放到 bss 段上
接下来就是 两个 函数,sub_40125D, sub_40128F ,如果两个函数返回都是1 的话就是正确的
第一个 函数 sub_40125d 传入的是 input[3:] 这段字符串
第二个函数 sub_40128f 传入的是 input[:3] ,并且三位都必须要是数字
看一下第一个函数,ida f5 有点问题,直接alt+k 改了一下sp, 但是代码很难看,主要逻辑在下面
BOOL __usercall rsa_some_402A3A@<eax>(int a1@<ebp>) { int v1; // eax ((void (*)(void))((char *)&loc_402A35 + 1))(); msg_str(a1 - 204); // ecx:"7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585" msg_str(a1 - 804); // edx:"208CBB7CD6ECC64516D07D978F5F0681F534EAD235D5C49ADD72D2DB840D5304" *(_DWORD *)(*(_DWORD *)(a1 - 4) + 564) = 16; *(_DWORD *)(a1 - 808) = malloc_409350(0); *(_DWORD *)(a1 - 812) = malloc_409350(0); *(_DWORD *)(a1 - 820) = malloc_409350(0); *(_DWORD *)(a1 - 816) = malloc_409350(0); copysome_40D1E0(*(_DWORD *)(a1 - 820), (int)&hex_3__495660); copysome_40D1E0(*(_DWORD *)(a1 - 808), a1 - 804);// enc str copysome_40D1E0(*(_DWORD *)(a1 - 812), (int)"3e9");// 3e9 if ( sub_40A2C0(*(_DWORD **)(a1 - 820), *(_DWORD **)(a1 - 808)) != -1 ) return 0; // (input[3:], 3e9, 7da_str,dst) main_enc_40C110(*(_DWORD *)(a1 - 820), *(_DWORD *)(a1 - 812), *(_DWORD *)(a1 - 808), *(_DWORD *)(a1 - 816)); sub_40B280(0, *(_DWORD **)(a1 - 816), (_BYTE *)(a1 - 404), 0); clean_409CA0(*(_DWORD *)(a1 - 808)); clean_409CA0(*(_DWORD *)(a1 - 812)); clean_409CA0(*(_DWORD *)(a1 - 820)); clean_409CA0(*(_DWORD *)(a1 - 816)); clean(); v1 = strlen((const char *)(a1 - 404)); tohex_40100F(a1 - 404, a1 - 604, v1); return strcmp((const char *)(a1 - 204), (const char *)(a1 - 604)) == 0; }
前面主要是 一些内存分配,copy 的操作,后面是 free 内存,转换成hex 比较的过程,主要是中间的过程
调用了 main_enc_40C110 这个函数
传入 参数
(input[3:],0x3e9, 7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585,dst)
对输入进行加密,加密之后得到的 dst hex 编码之后和
208CBB7CD6ECC64516D07D978F5F0681F534EAD235D5C49ADD72D2DB840D5304 比较,一样即返回1
不过这个函数太大了,可能是已有的什么加密,调试的时候 发现输入
111\x01 得到的是 01 , 改成 \x02 的话得到的是
(2^0x3e9)%/7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585
看起来是 rsa 加密,直接将 7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585 模数分解一下,然后就可以 求出 input了
import gmpy e=gmpy.mpz(0x3e9) p=208096057845685678782766058500526476379 q=273086345401562743300402731618892888991 n=0x7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585 p=gmpy.mpz(p) q=gmpy.mpz(q) phi_n=(p-1)*(q-1) d=gmpy.invert(e,phi_n) print hex(d) m=pow(c,d,n) print hex(m)
得到input
iamahandsomeguyhaha1
大帅锅haha
第一个函数过了,接下来第二层是个 3 位的数字,die 查看加密特征和发现这里用了 aes 加密,不过只是三位数字而已,爆破一下?
手动测试了一下,p一下输个 520 发现居然过了
完整flag
520iamahandsomeguyhaha1
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)