-
-
[原创]看雪.京东 2018CTF-第十三题分析
-
发表于: 2018-7-11 12:02 3283
-
// local variable allocation has failed, the output may be wrong! int __cdecl main(int argc, const char **argv, const char **envp) { double v3; // xmm1_8 __int64 v4; // rdx __int64 v5; // rax __int64 v6; // rdx __int64 v7; // rax __int64 v8; // rdx __int64 v10; // rax __int64 v11; // rax double v12; // xmm1_8 __int64 v13; // rax int newKey1; // [rsp+20h] [rbp-198h] char v15; // [rsp+24h] [rbp-194h] char Format[4]; // [rsp+30h] [rbp-188h] char v17; // [rsp+34h] [rbp-184h] double v18; // [rsp+40h] [rbp-178h] double low4Byte_newKey; // [rsp+50h] [rbp-168h] double high5_newKey1; // [rsp+58h] [rbp-160h] double low4Byte_newKey_1; // [rsp+60h] [rbp-158h] double high5_newKey1_1; // [rsp+68h] [rbp-150h] __int64 v23; // [rsp+70h] [rbp-148h] __int64 v24; // [rsp+78h] [rbp-140h] __int64 v25; // [rsp+80h] [rbp-138h] __int64 v26; // [rsp+88h] [rbp-130h] char inputKey[256]; // [rsp+90h] [rbp-128h] int v28; // [rsp+190h] [rbp-28h] sub_401F00(*(__int64 *)&argc, (__int64 *)argv); v15 = 0; memset(inputKey, 0, sizeof(inputKey)); v17 = 0; low4Byte_newKey = 0.0; high5_newKey1 = 0.0; low4Byte_newKey_1 = 0.0; high5_newKey1_1 = 0.0; v18 = 0.0; v28 = 0; newKey1 = 0; *(_DWORD *)Format = 0; v23 = 0LL; v24 = 0LL; v25 = 0LL; v26 = 0LL; sub_401790(); sub_401C50((__int64)&v28, (__int64)inputKey, v4, 252); v5 = 0LL; do { v6 = (byte_408D00[v5] ^ 0x19) - (unsigned int)v5; *((_BYTE *)&v23 + v5) = (byte_408D00[v5] ^ 0x19) - v5; ++v5; } while ( v5 != 16 ); printf(Format, inputKey, v6, &v23); Format[0] = byte_408D70 ^ 0x25; Format[1] = (byte_408D71 ^ 0x25) - 1; scanf(Format, inputKey, inputKey, Format); if ( strlen(inputKey) != 10 ) // 条件1:长度为10 { v7 = 0LL; do { v8 = (byte_408D10[v7] ^ 0xF) - (unsigned int)v7; *((_BYTE *)&v23 + v7) = (byte_408D10[v7] ^ 0xF) - v7; ++v7; } while ( v7 != 16 ); goto LABEL_6; } if ( (unsigned int)charToHex((__int64)Format, (__int64)inputKey, (__int64)&newKey1, (__int64)inputKey, 10) != 5 )// 将输入转换成整数 { v10 = 0LL; do { v8 = (byte_408D20[v10] ^ 0x21) - (unsigned int)v10; *((_BYTE *)&v23 + v10) = (byte_408D20[v10] ^ 0x21) - v10; ++v10; } while ( v10 != 16 ); goto LABEL_6; } HIWORD(low4Byte_newKey) = newKey1; // "1234" --> 3412000000000000 low4Byte_newKey_1 = low4Byte_newKey; *(_WORD *)((char *)&high5_newKey1 + 5) = HIWORD(newKey1); HIBYTE(high5_newKey1) = v15; // 123456789A --->9A78560000000000 high5_newKey1_1 = high5_newKey1; sub_4015E0((__int64)Format, (__int64)inputKey, &v18, &low4Byte_newKey);// if ( v17 <= 1.0 || v17 >= 10.0 || (v18 = v8[3], v18 <= 1.0) || v18 >= 10.0 ) Format[0] = byte_408D72 ^ 0x12; Format[1] = (byte_408D73 ^ 0x12) - 1; Format[2] = (byte_408D74 ^ 0x12) - 2; sprintf(Format, inputKey, Format, inputKey, *(_QWORD *)&v18, v18, v3, v18); if ( inputKey[1] != '.' ) { v11 = 0LL; // Ohhh.Try again do { v8 = (byte_408D40[v11] ^ 0x3F) - (unsigned int)v11; *((_BYTE *)&v23 + v11) = (byte_408D40[v11] ^ 0x3F) - v11; ++v11; } while ( v11 != 16 ); goto LABEL_6; } v12 = (double)(inputKey[3] - 0x30) * (double)(inputKey[3] - 0x30); if ( sub_403360( (__int64)Format, (__int64)inputKey, (double)(inputKey[0] - 0x30) * (double)(inputKey[0] - 0x30) + (double)(inputKey[2] - 0x30) * (double)(inputKey[2] - 0x30) + v12, v12) <= 15.5 || newKey1 & 0xF0000 ) { v13 = 0LL; } else { v13 = 0LL; if ( COERCE_DOUBLE(COERCE_UNSIGNED_INT64(low4Byte_newKey_1 + high5_newKey1_1 - v18) & xmmword_409080) < 0.003 ) { do // Congratulation { v8 = (byte_408D50[v13] ^ 0x47) - (unsigned int)v13; *((_BYTE *)&v23 + v13) = (byte_408D50[v13] ^ 0x47) - v13; ++v13; } while ( v13 != 16 ); goto LABEL_6; } } do { v8 = (byte_408D60[v13] ^ 0x37) - (unsigned int)v13;// comeon go on *((_BYTE *)&v23 + v13) = (byte_408D60[v13] ^ 0x37) - v13; ++v13; } while ( v13 != 16 ); LABEL_6: printf(Format, inputKey, v8, &v23); return 0; }
import subprocess import sys pname ="NNCrackme.exe" def getSn(): a=['0','0','0','0','0','0','0','0','0','0',0] i =0x3FF1 while i<0x4024: print('i='+ str(hex(i))) temp = i&0x000f a[1]= (i&0x000f) a[0]= ((i&0x00f0)>>4) a[3]= ((i&0x0f00)>>8) a[2]= ((i&0xf000)>>12) j = 0x3FF010 while j<0x402400: a[5]= (j&0x00000f) a[4]= ((j&0x0000f0)>>4) a[7]= ((j&0x000f00)>>8) a[6]= ((j&0x00f000)>>12) a[9]= ((j&0x0f0000)>>16) a[8]= ((j&0xf00000)>>20) k =0 keystr = '' while k <10: keystr=keystr+str(hex(a[k]))[2:].upper() k=k+1 print(keystr) arg =keystr io = subprocess.Popen(pname,stdin=subprocess.PIPE,stdout=subprocess.PIPE) ret=io.communicate(input=arg) res = ret[0].decode()[0:] print(res) if(res.find('Congratulation')>=0): print("the flag is:%s"%keystr) return else: j=j+0x10 i=i+1 return getSn()
爆破结果如下:
F13F802140 Input your KEY:Come on, go on F13F902140 Input your KEY:Come on, go on F13FA02140 Input your KEY:Come on, go on F13FB02140 Input your KEY:Come on, go on F13FC02140 Input your KEY:Come on, go on F13FD02140 Input your KEY:Come on, go on F13FE02140 Input your KEY:Congratulation the flag is:F13FE02140
F13F802140 Input your KEY:Come on, go on F13F902140 Input your KEY:Come on, go on F13FA02140 Input your KEY:Come on, go on F13FB02140 Input your KEY:Come on, go on F13FC02140 Input your KEY:Come on, go on F13FD02140 Input your KEY:Come on, go on F13FE02140 Input your KEY:Congratulation the flag is:F13FE02140
flag = F13FE02140
// local variable allocation has failed, the output may be wrong! int __cdecl main(int argc, const char **argv, const char **envp) { double v3; // xmm1_8 __int64 v4; // rdx __int64 v5; // rax __int64 v6; // rdx __int64 v7; // rax __int64 v8; // rdx __int64 v10; // rax __int64 v11; // rax double v12; // xmm1_8 __int64 v13; // rax int newKey1; // [rsp+20h] [rbp-198h] char v15; // [rsp+24h] [rbp-194h] char Format[4]; // [rsp+30h] [rbp-188h] char v17; // [rsp+34h] [rbp-184h] double v18; // [rsp+40h] [rbp-178h] double low4Byte_newKey; // [rsp+50h] [rbp-168h] double high5_newKey1; // [rsp+58h] [rbp-160h] double low4Byte_newKey_1; // [rsp+60h] [rbp-158h] double high5_newKey1_1; // [rsp+68h] [rbp-150h] __int64 v23; // [rsp+70h] [rbp-148h] __int64 v24; // [rsp+78h] [rbp-140h] __int64 v25; // [rsp+80h] [rbp-138h] __int64 v26; // [rsp+88h] [rbp-130h] char inputKey[256]; // [rsp+90h] [rbp-128h] int v28; // [rsp+190h] [rbp-28h] sub_401F00(*(__int64 *)&argc, (__int64 *)argv); v15 = 0; memset(inputKey, 0, sizeof(inputKey)); v17 = 0; low4Byte_newKey = 0.0; high5_newKey1 = 0.0; low4Byte_newKey_1 = 0.0; high5_newKey1_1 = 0.0; v18 = 0.0; v28 = 0; newKey1 = 0; *(_DWORD *)Format = 0; v23 = 0LL; v24 = 0LL; v25 = 0LL; v26 = 0LL; sub_401790(); sub_401C50((__int64)&v28, (__int64)inputKey, v4, 252); v5 = 0LL; do { v6 = (byte_408D00[v5] ^ 0x19) - (unsigned int)v5; *((_BYTE *)&v23 + v5) = (byte_408D00[v5] ^ 0x19) - v5; ++v5; } while ( v5 != 16 ); printf(Format, inputKey, v6, &v23); Format[0] = byte_408D70 ^ 0x25; Format[1] = (byte_408D71 ^ 0x25) - 1; scanf(Format, inputKey, inputKey, Format); if ( strlen(inputKey) != 10 ) // 条件1:长度为10 { v7 = 0LL; do { v8 = (byte_408D10[v7] ^ 0xF) - (unsigned int)v7; *((_BYTE *)&v23 + v7) = (byte_408D10[v7] ^ 0xF) - v7; ++v7; } while ( v7 != 16 ); goto LABEL_6; } if ( (unsigned int)charToHex((__int64)Format, (__int64)inputKey, (__int64)&newKey1, (__int64)inputKey, 10) != 5 )// 将输入转换成整数 { v10 = 0LL; do { v8 = (byte_408D20[v10] ^ 0x21) - (unsigned int)v10; *((_BYTE *)&v23 + v10) = (byte_408D20[v10] ^ 0x21) - v10; ++v10; } while ( v10 != 16 ); goto LABEL_6; } HIWORD(low4Byte_newKey) = newKey1; // "1234" --> 3412000000000000 low4Byte_newKey_1 = low4Byte_newKey; *(_WORD *)((char *)&high5_newKey1 + 5) = HIWORD(newKey1); HIBYTE(high5_newKey1) = v15; // 123456789A --->9A78560000000000 high5_newKey1_1 = high5_newKey1; sub_4015E0((__int64)Format, (__int64)inputKey, &v18, &low4Byte_newKey);// if ( v17 <= 1.0 || v17 >= 10.0 || (v18 = v8[3], v18 <= 1.0) || v18 >= 10.0 ) Format[0] = byte_408D72 ^ 0x12; Format[1] = (byte_408D73 ^ 0x12) - 1; Format[2] = (byte_408D74 ^ 0x12) - 2; sprintf(Format, inputKey, Format, inputKey, *(_QWORD *)&v18, v18, v3, v18); if ( inputKey[1] != '.' ) { v11 = 0LL; // Ohhh.Try again do { v8 = (byte_408D40[v11] ^ 0x3F) - (unsigned int)v11; *((_BYTE *)&v23 + v11) = (byte_408D40[v11] ^ 0x3F) - v11; ++v11; } while ( v11 != 16 ); goto LABEL_6; } v12 = (double)(inputKey[3] - 0x30) * (double)(inputKey[3] - 0x30); if ( sub_403360( (__int64)Format, (__int64)inputKey, (double)(inputKey[0] - 0x30) * (double)(inputKey[0] - 0x30) + (double)(inputKey[2] - 0x30) * (double)(inputKey[2] - 0x30) + v12, v12) <= 15.5 || newKey1 & 0xF0000 ) { v13 = 0LL; } else { v13 = 0LL; if ( COERCE_DOUBLE(COERCE_UNSIGNED_INT64(low4Byte_newKey_1 + high5_newKey1_1 - v18) & xmmword_409080) < 0.003 ) { do // Congratulation { v8 = (byte_408D50[v13] ^ 0x47) - (unsigned int)v13; *((_BYTE *)&v23 + v13) = (byte_408D50[v13] ^ 0x47) - v13; ++v13; } while ( v13 != 16 ); goto LABEL_6; } } do { v8 = (byte_408D60[v13] ^ 0x37) - (unsigned int)v13;// comeon go on *((_BYTE *)&v23 + v13) = (byte_408D60[v13] ^ 0x37) - v13; ++v13; } while ( v13 != 16 ); LABEL_6: printf(Format, inputKey, v8, &v23); return 0; }
import subprocess import sys pname ="NNCrackme.exe" def getSn(): a=['0','0','0','0','0','0','0','0','0','0',0] i =0x3FF1 while i<0x4024: print('i='+ str(hex(i))) temp = i&0x000f a[1]= (i&0x000f) a[0]= ((i&0x00f0)>>4) a[3]= ((i&0x0f00)>>8) a[2]= ((i&0xf000)>>12) j = 0x3FF010 while j<0x402400: a[5]= (j&0x00000f) a[4]= ((j&0x0000f0)>>4) a[7]= ((j&0x000f00)>>8) a[6]= ((j&0x00f000)>>12) a[9]= ((j&0x0f0000)>>16) a[8]= ((j&0xf00000)>>20) k =0 keystr = '' while k <10: keystr=keystr+str(hex(a[k]))[2:].upper() k=k+1 print(keystr) arg =keystr io = subprocess.Popen(pname,stdin=subprocess.PIPE,stdout=subprocess.PIPE) ret=io.communicate(input=arg) res = ret[0].decode()[0:] print(res) if(res.find('Congratulation')>=0): print("the flag is:%s"%keystr) return else: j=j+0x10 i=i+1 return getSn()
F13F802140 Input your KEY:Come on, go on F13F902140 Input your KEY:Come on, go on F13FA02140 Input your KEY:Come on, go on F13FB02140 Input your KEY:Come on, go on F13FC02140 Input your KEY:Come on, go on F13FD02140 Input your KEY:Come on, go on F13FE02140 Input your KEY:Congratulation the flag is:F13FE02140
IDA载入后发现有2个TlsCallback函数,初步看这两个函数,没发现特别的东西,暂时不管,先分析下main的代码。
一、main函数
1、获取输入sn,并判断sn长度如果不是10,则输出key error错误提示。(条件一)
2、调用401CE0函数,将sn字符串转换成一个64位16进制数称为keyValue,同时要求输入的字符必须在"0123456789ABCDEF"范围内。(条件二)
输入"123456789A",将转换成为0x9A78453412。
3、将64位16进制数,拆分成2个double数称为 keyValue_x和 keyValue_y,分别为低4字节和高6字节,为:0x3412000000000000, 0x9A78560000000000。
4、调用4015E0函数将上面的2个double数经过了一系列的浮点运算获得一个双精度值称之为:newKeyValue。同时判断上面的两个双精度数必须在
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-7-11 12:08
被oooAooo编辑
,原因:
赞赏
他的文章
- 看雪CTF 2019总决赛 第六题 三道八佛 IDA脱壳脚本 5669
- [原创]看雪CTF2019Q3第四题WP 5934
- [原创]看雪CTF2019Q3 第二题WP 6760
- [2019看雪CTF晋级赛Q3第九题WP 12491
- [原创]看雪CTF2019晋级赛Q2第三题 5022
看原图
赞赏
雪币:
留言: