-
-
[原创]看雪.京东 2018CTF-第十三题分析
-
发表于: 2018-7-11 12:02 3419
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | // 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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() |
爆破结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | // 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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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。同时判断上面的两个双精度数必须在
最后于 2018-7-11 12:08
被oooAooo编辑
,原因:
赞赏
他的文章
- 看雪CTF 2019总决赛 第六题 三道八佛 IDA脱壳脚本 5864
- [原创]看雪CTF2019Q3第四题WP 6132
- [原创]看雪CTF2019Q3 第二题WP 7037
- [2019看雪CTF晋级赛Q3第九题WP 12775
- [原创]看雪CTF2019晋级赛Q2第三题 5198
赞赏
雪币:
留言: