-
-
[原创]2018看雪CTF第十二题WP
-
2018-7-10 01:06 2714
-
命令行参数
直接打开CM,程序闪退。用命令行打开,CM会输出一句话然后退出。
λ Desktop\kanxueCTF2018\12\CrackMe\CrackMe.exe input like this:crackme.exe mykey
原来要用命令行参数的形式输入flag。(IDA调试时,在Debugger->Process Option->Parameter处输入)
λ Desktop\kanxueCTF2018\12\CrackMe\CrackMe.exe 123456 registration failed
随便传了一个flag,回显失败就退出了。
IDA反编译
main函数中:
if ( argc == 2 ) { sub_14000E55C(key, 260i64, (char *)argv[1], 260i64); sub_140002E00(&retaddr); result = 0; }
sub_14000E55C作用是把我们输入的flag(argv[1]指向的)复制到全局变量key处。
第二个call是验证函数。
这里值得一提的是,else分支中有大量的垃圾代码(验证函数中也有大量的垃圾代码,其实是一些常量经过各种变换,生成另一些常量,作用是阻挠分析,分析时需要无视它们),比如以下:
else { v30 = (unsigned __int16)((((dword_140038020 << 16) + (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020) + (unsigned __int16)(7 - (HIWORD(dword_140038020) - dword_140038020)) - (unsigned int)(unsigned __int16)(HIWORD(dword_140038020) - dword_140038020)) >> 16) - (HIWORD(dword_140038020) - dword_140038020 + 7 - (HIWORD(dword_140038020) - dword_140038020) - (HIWORD(dword_140038020) - dword_140038020)) * (HIWORD(dword_140038020) - dword_140038020 + 7 - (HIWORD(dword_140038020) - dword_140038020) - (HIWORD(dword_140038020) - dword_140038020))) + (((dword_140038020 << 16) + (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020) + (unsigned __int16)(7 - (HIWORD(dword_140038020) - dword_140038020)) - (unsigned __int16)(HIWORD(dword_140038020) - dword_140038020)) << 16); v31 = 31 * ((unsigned __int16)((BYTE1(dword_140038024) << 8) - 7 + (unsigned __int8)(101 * dword_140038024 + 51)) + ((unsigned __int16)(-7 * (unsigned __int8)(35 - 101 * BYTE2(dword_140038024)) - 1792 * (unsigned __int8)(101 * HIBYTE(dword_140038024) + 108) + 35) << 16)) - 961; v32 = (unsigned __int16)((((unsigned __int16)(((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) + ((unsigned int)(unsigned __int16)(((unsigned __int16)-HIWORD(dword_140038028) >> 8) + ((unsigned __int8)(-7 * BYTE2(dword_140038028)) << 8)) << 16)) >> 16) - (((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) * (((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8))) + (((unsigned __int16)(((unsigned __int16)(7 * ((unsigned __int8)dword_140038028 + (BYTE1(dword_140038028) << 8)) - 35) >> 8) - 31 + ((unsigned __int8)(7 * dword_140038028 - 40) << 8)) + ((unsigned __int16)(((unsigned __int16)-HIWORD(dword_140038028) >> 8) + ((unsigned __int8)(-7 * BYTE2(dword_140038028)) << 8)) << 16)) << 16); v3 = ((((unsigned __int16)(-31 * HIWORD(dword_14003802C)) >> 8) - abs((char)(-31 * BYTE2(dword_14003802C)))) & 0xFF) - 7936 * HIWORD(dword_14003802C); v4 = (unsigned __int8)(4 * dword_14003802C + dword_14003802C - 35) + (BYTE1(dword_14003802C) << 8); v5 = (v4 << 8) + (((v4 >> 8) - v4 * v4) & 0xFF); v6 = -7936 * v5 - 31 * (((v5 >> 8) - v5 * v5) & 0xFF) + 7; v7 = (unsigned __int8)(76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8)) - (unsigned __int8)(-58 - 111 * (76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8))) - ((unsigned __int8)(76 - 7 * ((unsigned __int16)(5 * ((unsigned __int8)(5 - HIBYTE(v6)) + ((unsigned __int8)(-7 * v6 - 1) << 8))) >> 8)) + ((unsigned __int8)(-81 * (5 - HIBYTE(v6)) - 96) << 8)) + 7; v8 = v7 + (unsigned __int8)(v7 - 7) - (unsigned __int8)v7; v33 = (unsigned __int16)((v8 << 8) + (((v8 >> 8) - abs((char)(v7 - 7))) & 0xFF)) + ((unsigned __int16)(-31 * (1280 * v3 + ((((unsigned __int16)(5 * v3) >> 8) - abs((char)(5 * (((unsigned __int16)(-31 * HIWORD(dword_14003802C)) >> 8) - abs(-31 * BYTE2(dword_14003802C)))))) & 0xFF))) << 16); v41 = dword_140038030; v34 = 5 * ((unsigned __int16)(1 - dword_140038030) + ((unsigned __int16)(HIWORD(dword_140038030) - 5) << 16)); _mm_storeu_si128((__m128i *)&v38, _mm_load_si128((const __m128i *)&xmmword_140024850)); v37 = 0; sub_140002720(&v37, &v30, 17i64); v26 = (unsigned __int16)((unsigned __int8)(59 * dword_140038010 + 63) + (BYTE1(dword_140038010) << 8)) + ((unsigned __int16)(25 * (((unsigned __int8)(5 - HIBYTE(dword_140038010)) << 8) + BYTE2(dword_140038010)) - 155 + (unsigned __int8)(5 - (25 * BYTE2(dword_140038010) + 101)) - (unsigned __int8)(25 * BYTE2(dword_140038010) + 101)) << 16); v9 = 31 - ((unsigned __int8)(BYTE2(dword_140038014) - 5) << 8) - ((unsigned __int16)(HIWORD(dword_140038014) - 5) >> 8); v10 = abs((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF)); v11 = (unsigned __int16)((((unsigned __int16)((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF)) + ((unsigned int)v9 << 16)) >> 16) - v10); v12 = (((unsigned __int16)((((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) >> 8) - ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8)) * ((unsigned __int8)(-36 - 101 * ((unsigned __int16)(31 * (((unsigned __int16)(31 * dword_140038014 - 155) >> 8) + ((unsigned __int8)(31 * dword_140038014 + 101) << 8))) >> 8)) + ((unsigned __int8)(31 * ((unsigned __int16)(31 * dword_140038014 - 155) >> 8)) << 8))) & 0xFF)) + (v9 << 16)) << 16) + v11; v13 = v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned __int16)v12; v14 = 7 * ((v13 << 16) + (unsigned __int16)(((v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned int)(unsigned __int16)v12) >> 16) - v13 * v13)); v15 = 7 * ((v14 << 16) + (unsigned __int16)(HIWORD(v14) - abs(7 * (((v12 + (unsigned __int16)((((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) << 8) + ((((unsigned __int16)((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) >> 8) - ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8)) * ((unsigned __int8)(4 * ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8) - 25 + ((unsigned __int16)(((_WORD)v12 << 8) + ((((unsigned __int16)v12 >> 8) - v12) & 0xFF)) >> 8)) + ((unsigned __int8)(7 * (BYTE1(v12) - v12)) << 8))) & 0xFF)) - (unsigned int)(unsigned __int16)v12) >> 16) - v13 * v13)))); v27 = 7 * ((v15 << 16) + (unsigned __int16)(HIWORD(v15) - v15 * v15)); v41 = dword_140038018; v16 = (unsigned __int16)-((7 - ((unsigned __int16)dword_140038018 + (dword_140038018 & 0xFFFF0000))) >> 16) + (((unsigned __int8)(7 - dword_140038018) + ((unsigned __int8)-((unsigned __int16)(7 - dword_140038018) >> 8) << 8)) << 16); v28 = 5 * (((v16 + 4 * v16 - 1) << 16) + (unsigned __int16)(((unsigned int)(v16 + 4 * v16 - 1) >> 16) - (v16 + 4 * v16 - 1) * (v16 + 4 * v16 - 1))); v17 = ((unsigned __int16)(dword_14003801C - 31) << 16) + (unsigned __int16)(HIWORD(dword_14003801C) - 1); v18 = (v17 << 16) + (unsigned __int16)(HIWORD(v17) - v17 * v17); v19 = (((unsigned __int8)(BYTE2(v17) - v17 * v17) + ((unsigned __int8)-BYTE1(v18) << 8)) << 16) + (unsigned __int16)((v18 >> 16) - 1); v20 = (v19 << 16) + (unsigned __int16)(HIWORD(v19) - v19 * v19); v21 = 7 * (unsigned __int16)v20 - 7 * (v20 + (unsigned __int16)(31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8)))) + 31; LOWORD(v20) = -256 * ((unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) + ((((unsigned __int16)-(signed __int16)((unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) >> 8) + (unsigned __int8)(7 * v20 - 7 * (v20 + 31 * (11 * (BYTE2(v19) - v19 * v19) - 5)) + 31) + ((7 * v20 - 7 * (v20 + 31 * ((unsigned __int8)(11 * (BYTE2(v19) - v19 * v19) - 5) + ((unsigned __int8)(96 - 35 * ((unsigned __int16)(HIWORD(v19) - v19 * v19) >> 8)) << 8))) + 31) & 0xFF00)) & 0xFF); v29 = v21 + (unsigned __int16)(v20 + (unsigned __int8)(-101 - 5 * v20) - (unsigned __int8)v20) - (unsigned __int16)v21; _mm_storeu_si128((__m128i *)&v36, _mm_load_si128((const __m128i *)&xmmword_140024850)); v35 = 0; sub_140002720(&v35, &v26, 16i64); v22 = (_QWORD *)sub_1400011A0(&v40, &v35, &v37); v23 = v22[2]; if ( v22[3] >= 0x10ui64 ) v22 = (_QWORD *)*v22; v24 = sub_140001340(&qword_140039930, v22, v23); sub_1400018B0(v24); sub_140001FD0(&v40); sub_140001FD0(&v35); sub_140001FD0(&v37); result = -1; }
验证函数
由于是静态链接的运行库,还有大量的垃圾代码。验证函数静态并不好分析。我采用的是猜测加上调试来验证的方法。
下面是几个关键的判断(已去除了参杂其中的垃圾代码):
flag长度为30:
do ++v6; while ( key[v6] ); if ( (v6 & 0xFFF) + (v529 << 12) == 30 )
flag至少有3个'9'(比较的是字符的hash值):
v10 = key; do { v184 = 0; v11 = *v10; LOBYTE(v184) = v11; v12 = &v184; for ( i = -3750763034362895579i64; *(_BYTE *)v12; v11 = *(_BYTE *)v12 ) { i = 1099511628211i64 * (i ^ v11); v12 = (__int16 *)((char *)v12 + 1); } v14 = v8 + 1; if ( i != -5808600853619038060i64 ) v14 = v8; v8 = v14; ++v9; ++v10; } while ( v9 < v6 ); v1 = 32i64; if ( v14 >= 3 )
这里用了一个hash函数(后面的判断中也被多次用到):
signed __int64 __fastcall hash(char *a1) { char v1; // dl signed __int64 result; // rax signed __int64 v3; // rax v1 = *a1; for ( result = 0xCBF29CE484222325i64; *a1; result = 0x100000001B3i64 * v3 ) { ++a1; v3 = result ^ v1; v1 = *a1; } return result; }
flag由'KXCTF2018'开头(也是用的hash函数来比较):
LOWORD(v183) = 0; LOBYTE(v183) = key[0]; if ( hash((char *)&v183) == -5808510693665524758i64 ) { LOBYTE(v183) = byte_140039301; if ( hash((char *)&v183) == -5808494200991101593i64 ) { LOBYTE(v183) = byte_140039302; if ( hash((char *)&v183) == -5808519489758550446i64 ) { LOBYTE(v183) = byte_140039303; if ( hash((char *)&v183) == -5808507395130640125i64 ) { LOBYTE(v183) = byte_140039304; if ( hash((char *)&v183) == -5808522788293435079i64 ) { LOBYTE(v183) = byte_140039305; if ( hash((char *)&v183) == -5808606351177179115i64 ) { LOBYTE(v183) = byte_140039306; if ( hash((char *)&v183) == -5808608550200435537i64 ) { LOBYTE(v183) = byte_140039307; if ( hash((char *)&v183) == -5808609649712063748i64 ) { LOBYTE(v183) = byte_140039308; if ( hash((char *)&v183) == -5808599754107409849i64 )
整个flag的hash值(此处调试时无法判断,需要手动设置EIP绕过):
if ( hash(key) == 0x4F8075587499C0FFi64 ) { LODWORD(v46) = 31; LODWORD(v47) = 0; }
第一个'9'后面5个字符连接上'.DLL'为part1:
sub_14000B7D0(&part1, 0i64, 260i64); v80 = (_BYTE *)sub_14000BDD8(key, "9"); v81 = v80; part1 = v80[1]; v702 = v80[2]; v703 = v80[3]; v704 = v80[4]; v705 = v80[5]; sub_14000E46C(&part1, 260i64, ".DLL");
第二个'9'和第三个'9'之间的部分为part2:
v82 = sub_14000BDD8(v81 + 1, "9"); v83 = v82; *(_BYTE *)sub_14000BDD8(v82 + 1, "9") = 0; sub_14000B7D0(&part2, 0i64, 260i64); sub_14000E55C(&part2, 260i64, (char *)(v83 + 1), 260i64);
最后的验证(伪代码表示,CM中是通过PEB来获取这些函数的地址的):
hModule = GetModuleHandle(part1); pFunc = GetProcAddress(hModule,part2); if(pFunc(0,30)<0) Success! else Fail!
穷举
利用hash(flag)==0x4F8075587499C0FF来穷举:
这里比较坑。。。
1、CM中没有限定分隔符9的位置,穷举空间太大,我只能假设3个9把剩下的21的字符恰好分成2部分,第一部分长度为5,第二部分的长度为13。
2、dll名称的大小写不确定,比如GetModuleHandle("nTdlL.dll")也是能成功返回的。根据连接串'.DLL'为大写再次假设dll的名称(前5个字符)为大写的。
代码如下:(其中export文件为提取出来ntdll的导出表)
def f(s): r = 0xCBF29CE484222325 for c in s: r = (0x100000001B3*(ord(c)^r))%(2**64) return r path = r'\Desktop\kanxueCTF2018\12\export' with open(path) as fp: data = fp.read() l = data.split() for a in l: if len(a)==13: s = 'KXCTF20189NTDLL9' + a + '9' print(s) if f(s)==0x4F8075587499C0FF: print('!!!') break
最后flag为KXCTF20189NTDLL9DbgUiContinue9
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。