首页
社区
课程
招聘
2
[原创]看雪.京东 2018CTF-第十三题分析
发表于: 2018-7-11 12:02 3419

[原创]看雪.京东 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编辑 ,原因:
收藏
免费 2
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2022-7-27 01:59
心游尘世外
为你点赞~
2022-7-27 00:01
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册