幻想成为ctf糕手的第七天insanity32位无壳ida打开查看字符串看到9447{This_is_a_flag}game刚打开运行按顺序输入1-8就得到flag了。。。32位无壳ida打开字符串中找到关键词双击进入找到该函数在最下面for循环中可以看到有异或v222字节的数组前2字节是{ “后续字节为硬编码值v332字节的数组前12字节是S,yhn _uec{”后续字节为硬编码值循环56次i从0到55对v2[i]进行两次异或操作v2[i] ^ v5[i]用v5的对应字节解密v2[i] ^ 0x13再次异或固定值0x13最后调用sub_45A7BE(“%s\n”)输出解密后的v2int sub_45E940() { int i; // [espD0h] [ebp-94h] char v2[22]; // [espDCh] [ebp-88h] BYREF char v3[32]; // [espF2h] [ebp-72h] BYREF char v4[4]; // [esp112h] [ebp-52h] BYREF char v5[64]; // [esp120h] [ebp-44h] sub_45A7BE(done!!! the flag is ); v5[0] 18; v5[1] 64; v5[2] 98; v5[3] 5; v5[4] 2; v5[5] 4; v5[6] 6; v5[7] 3; v5[8] 6; v5[9] 48; v5[10] 49; v5[11] 65; v5[12] 32; v5[13] 12; v5[14] 48; v5[15] 65; v5[16] 31; v5[17] 78; v5[18] 62; v5[19] 32; v5[20] 49; v5[21] 32; v5[22] 1; v5[23] 57; v5[24] 96; v5[25] 3; v5[26] 21; v5[27] 9; v5[28] 4; v5[29] 62; v5[30] 3; v5[31] 5; v5[32] 4; v5[33] 1; v5[34] 2; v5[35] 3; v5[36] 44; v5[37] 65; v5[38] 78; v5[39] 32; v5[40] 16; v5[41] 97; v5[42] 54; v5[43] 16; v5[44] 44; v5[45] 52; v5[46] 32; v5[47] 64; v5[48] 89; v5[49] 45; v5[50] 32; v5[51] 65; v5[52] 15; v5[53] 34; v5[54] 18; v5[55] 16; v5[56] 0; qmemcpy(v2, { , 2); v2[2] 18; v2[3] 98; v2[4] 119; v2[5] 108; v2[6] 65; v2[7] 41; v2[8] 124; v2[9] 80; v2[10] 125; v2[11] 38; v2[12] 124; v2[13] 111; v2[14] 74; v2[15] 49; v2[16] 83; v2[17] 108; v2[18] 94; v2[19] 108; v2[20] 84; v2[21] 6; qmemcpy(v3, S,yhn _uec{, 12); v3[12] 127; v3[13] 119; v3[14] 96; v3[15] 48; v3[16] 107; v3[17] 71; v3[18] 92; v3[19] 29; v3[20] 81; v3[21] 107; v3[22] 90; v3[23] 85; v3[24] 64; v3[25] 12; v3[26] 43; v3[27] 76; v3[28] 86; v3[29] 13; v3[30] 114; v3[31] 1; strcpy(v4, u~); for ( i 0; i 56; i ) { v2[i] ^ v5[i]; v2[i] ^ 0x13u; } return sub_45A7BE(%s\n); }使用python代码得到flagv6[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0]v3([123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6]list(bS,yhn _uec{)[127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1]list(bu~))flag_bytes[]foriinrange(56):decryptedv3[i]^v6[i]^0x13flag_bytes.append(decrypted)print(bytes(flag_bytes).decode())#zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}open-source打开可以看到代码在主函数中可以看到argc4会输出 what? 应该是报错的意思吧所以arcg应该4但是这个arcg在后面的hash运算时用不上第二段if也是一样 的道理可以看出first应该0xcafe第三段if则需要两个式子都为假 second % 5 3为假或者second % 17 ! 8为假即second % 5 ! 3 and second % 17 8第三段是和h4cky0u比较所以 argv[3]h4cky0u最后再经过运算 first * 31337 (second % 17) * 11 strlen(argv[3]) - 1615810207即可得到flag#includestdio.h#includestring.hintmain(intargc,char*argv[]){if(argc!4){printf(what?\n);exit(1);}unsignedintfirstatoi(argv[1]);if(first!0xcafe){printf(you are wrong, sorry.\n);exit(2);}unsignedintsecondatoi(argv[2]);if(second%53||second%17!8){printf(ha, you wont get it!\n);exit(3);}if(strcmp(h4cky0u,argv[3])){printf(so close, dude!\n);exit(4);}printf(Brr wrrr grr\n);unsignedinthashfirst*31337(second%17)*11strlen(argv[3])-1615810207;printf(Get your key: );printf(%x\n,hash);return0;}脚本如下second也可以只取随便一个满足条件的数first0xcafethirdh4cky0uflag[]forsecondinrange(101):ifsecond%5!3andsecond%178:hash_valuefirst*31337(second%17)*11len(third)-1615810207flag.append(hex(hash_value)[2:])print(flag)#[c0ffee, c0ffee, c0ffee, c0ffee]simple-unpack32位upx壳使用upx脱壳丢到ida里面进入直接能看到flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}