首页
论坛
课程
招聘
[原创]KCTF2021[秋季赛][第九题][万事俱备]wp
2021-12-8 10:04 15867

[原创]KCTF2021[秋季赛][第九题][万事俱备]wp

ccfer 活跃值
16
2021-12-8 10:04
15867

运行CrackMe.exe,发现会在临时目录创建python27进程,把临时目录打包拷贝出来,直接研究check.py
发现check.py是编译过的,且不是标准opcode
IDA打开python27.dll找到PyEval_EvalFrameEx,找到到这里:

1
2
3
4
5
6
.text:000000001E1678D0                 cmp     esi, 93h        ; switch 148 cases
.text:000000001E1678D6                 ja      def_1E1678EA    ; jumptable 000000001E1678EA default case, cases 12,21,27,34-36,38,43,44,47,49,55,58,61,68,75,78-80,82,84,91,96,97,103,104,117,121,129,144
.text:000000001E1678DC                 movsxd  rax, esi
.text:000000001E1678DF                 mov     ecx, ds:(jpt_1E1678EA - 1E000000h)[r11+rax*4]
.text:000000001E1678E7                 add     rcx, r11
.text:000000001E1678EA                 jmp     rcx             ; switch jump

对应源码ceval.c的PyEval_EvalFrameEx中的:switch (opcode) {}
把opcode定义整理出来,更新到opcode.h文件中,把每条opcode写log输出记录,注意做下模块过滤,减少无用输出
然后编译得到带log输出的python27环境,运行自己的python27:
python27 check.py
得到全部log有900多M,搜索到"input username",把前面的全删掉,还剩200多M
然后发现很多类似这样的组合序列:

1
2
3
4
off=0021, [op=6D LOAD_FAST]:push 65826766491753696159103395487087L
off=0024, [op=83 LOAD_CONST]:push 86714445000368537639824468062475L
off=0027, [op=5F COMPARE_OP]:
off=002D, [op=76 JUMP_ABSOLUTE]

感觉像是加的混淆,写个脚本清理掉,可以大胆清理,主要保留逻辑和数学运算即可,最后还剩下2M多,1万多行了
比如我输入的名字是:KCTF,序列号是:00000000000000000000000000000000
观察前面一段log:

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
off=1032, [op=77 STORE_FAST]:pop 'KCTF'
off=0C46, [op=83 LOAD_CONST]:push 10
off=10D6, [op=5A CALL_FUNCTION]:
off=0C59, [op=77 STORE_FAST]:pop '00000000000000000000000000000000'
off=093F, [op=83 LOAD_CONST]:push 220
off=0C8D, [op=6D LOAD_FAST]:push 'KCTF'
off=0EC9, [op=5F COMPARE_OP]:
off=0F10, [op=6D LOAD_FAST]:push '00000000000000000000000000000000'
off=090C, [op=83 LOAD_CONST]:push 446
off=116D, [op=5A CALL_FUNCTION]:
off=0D99, [op=5A CALL_FUNCTION]:
off=0C04, [op=6D LOAD_FAST]:push '00000000000000000000000000000000'
off=0CC1, [op=5F COMPARE_OP]:
off=091F, [op=6D LOAD_FAST]:push 'KCTF'
off=0D87, [op=5A CALL_FUNCTION]:
off=0E93, [op=83 LOAD_CONST]:push 16
off=0983, [op=5F COMPARE_OP]:
off=0F73, [op=83 LOAD_CONST]:push 26
off=117E, [op=77 STORE_FAST]:pop 'kctf2021GoodLuck'
off=0EDA, [op=6D LOAD_FAST]:push 'KCTF'
off=0CF9, [op=5A CALL_FUNCTION]:
off=0996, [op=83 LOAD_CONST]:push 16
off=0E17, [op=5F COMPARE_OP]:
off=0BD0, [op=6D LOAD_FAST]:push 'KCTF'
off=0A36, [op=83 LOAD_CONST]:push 178
off=0D1C, [op=6D LOAD_FAST]:push 'kctf2021GoodLuck'
off=0FB7, [op=6D LOAD_FAST]:push 'KCTF'
off=09BA, [op=5A CALL_FUNCTION]:
off=0AEF, [op=83 LOAD_CONST]:push 1
off=0D75, [op=51 BINARY_ADD]:1 + 4 = 5
off=1192, [op=77 STORE_FAST]:pop 'KCTF@021GoodLuck'
off=0D53, [op=77 STORE_FAST]:pop []
off=10B5, [op=6D LOAD_FAST]:push []
off=0A24, [op=6D LOAD_FAST]:push 'helloctf_pediy_Archaia'
off=08D3, [op=5A CALL_FUNCTION]:
off=09A6, [op=83 LOAD_CONST]:push 0
off=0930, [op=77 STORE_FAST]:pop 0
off=082F, [op=83 LOAD_CONST]:push 507
off=0BDE, [op=5A CALL_FUNCTION]:
off=06A5, [op=6D LOAD_FAST]:push 'helloctf_pediy_Archaia'
off=0B3C, [op=5A CALL_FUNCTION]:
off=09E2, [op=5A CALL_FUNCTION]:
off=0BF2, [op=77 STORE_FAST]:pop 'bfdc823fca7d85034d70f650df268108'

能看出是把名字KTCF替换掉kctf2021GoodLuck的前几个字符得到KCTF@021GoodLuck
从helloctf_pediy_Archaia到bfdc823fca7d85034d70f650df268108,用hash计算器对比一下是md5
直接看序列号后续怎么处理的把,一搜就跳到了9000多行的地方,后面只剩2000多行了,估计可以看下去了:

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
off=1057, [op=6D LOAD_FAST]:push '00000000000000000000000000000000'
off=0CD5, [op=5A CALL_FUNCTION]:
off=13C2, [op=83 LOAD_CONST]:push 0
off=123A, [op=77 STORE_FAST]:pop 0
off=0CBC, [op=77 STORE_FAST]:pop 0
off=11CC, [op=6D LOAD_FAST]:push '00000000000000000000000000000000'
off=0EBD, [op=83 LOAD_CONST]:push 421
off=0F11, [op=5A CALL_FUNCTION]:
off=0C26, [op=83 LOAD_CONST]:push 694
off=0C5E, [op=5A CALL_FUNCTION]:
off=0F9B, [op=77 STORE_FAST]:pop '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
off=0C05, [op=83 LOAD_CONST]:push ''
off=0FF6, [op=77 STORE_FAST]:pop ''
off=0EF0, [op=83 LOAD_CONST]:push ''
off=0BDF, [op=77 STORE_FAST]:pop ''
off=0B89, [op=6D LOAD_FAST]:push '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
off=0FAF, [op=77 STORE_FAST]:pop '\x00'
off=0ED0, [op=6D LOAD_FAST]:push 0
off=102A, [op=83 LOAD_CONST]:push 1
off=1316, [op=51 BINARY_ADD]:1 + 0 = 1
off=144F, [op=83 LOAD_CONST]:push 256
off=0C81, [op=0E BINARY_MODULO]:1 % 256 = 1
off=0B1C, [op=77 STORE_FAST]:pop 1
off=12DB, [op=6D LOAD_FAST]:push 0
off=15FA, [op=6D LOAD_FAST]:push [98, 30, 106, 149, 9, 136, 33, 174, 26, 128, 32, 48, 116, 69, 244, 5, 122, 239, 79, 147, 197, 64, 16, 10, 53, 188, 135, 89, 120, 12, 73, 160, 34, 169, 96, 179, 54, 29, 191, 76, 215, 180, 70, 84, 181, 15, 211, 157, 59, 75, 218, 133, 132, 161, 242, 237, 99, 18, 199, 162, 83, 183, 102, 156, 137, 163, 61, 190, 110, 227, 3, 94, 142, 201, 158, 27, 184, 178, 39, 77, 74, 62, 115, 22, 126, 95, 234, 186, 38, 243, 103, 203, 107, 101, 219, 36, 41, 4, 196, 140, 165, 200, 93, 145, 45, 195, 141, 185, 249, 155, 8, 117, 113, 65, 224, 63, 170, 233, 60, 23, 131, 111, 35, 52, 80, 166, 212, 146, 204, 228, 100, 2, 238, 235, 88, 189, 58, 17, 114, 44, 47, 214, 171, 6, 209, 207, 121, 21, 182, 194, 91, 150, 192, 25, 139, 252, 7, 173, 86, 28, 104, 11, 223, 127, 125, 14, 251, 124, 40, 87, 231, 246, 50, 82, 20, 221, 130, 241, 172, 42, 97, 129, 205, 220, 144, 225, 49, 138, 57, 222, 250, 193, 206, 43, 13, 217, 164, 245, 148, 1, 202, 90, 109, 248, 253, 92, 187, 226, 19, 46, 67, 31, 105, 143, 153, 78, 123, 236, 56, 208, 66, 176, 118, 51, 175, 85, 255, 177, 254, 112, 213, 37, 210, 167, 72, 24, 232, 0, 168, 216, 230, 198, 134, 154, 240, 229, 152, 159, 151, 55, 81, 119, 108, 71, 247, 68]
off=0B41, [op=6D LOAD_FAST]:push 1
off=12F6, [op=51 BINARY_ADD]:30 + 0 = 30
off=0DC2, [op=83 LOAD_CONST]:push 256
off=15C6, [op=0E BINARY_MODULO]:30 % 256 = 30
off=1093, [op=77 STORE_FAST]:pop 30
off=0CE1, [op=6D LOAD_FAST]:push [98, 30, 106, 149, ...]
off=0F77, [op=6D LOAD_FAST]:push 30
off=12C9, [op=6D LOAD_FAST]:push [98, 30, 106, 149, ...]
off=0CA8, [op=6D LOAD_FAST]:push 1
off=1583, [op=6D LOAD_FAST]:push [98, 30, 106, 149, ...]
off=0F23, [op=6D LOAD_FAST]:push 1
off=0FE4, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=0E85, [op=6D LOAD_FAST]:push 30
off=141B, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=0F66, [op=6D LOAD_FAST]:push 1
off=0C4B, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=15D8, [op=6D LOAD_FAST]:push 30
off=0F55, [op=51 BINARY_ADD]:30 + 73 = 103
off=124C, [op=83 LOAD_CONST]:push 256
off=155D, [op=0E BINARY_MODULO]:103 % 256 = 103
off=0D37, [op=77 STORE_FAST]:pop 103
off=10C7, [op=6D LOAD_FAST]:push '\x00'
off=10E9, [op=5A CALL_FUNCTION]:
off=12B6, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=1507, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=0CD0, [op=6D LOAD_FAST]:push 1
off=0E73, [op=6D LOAD_FAST]:push [98, 73, 106, 149, ...]
off=153A, [op=6D LOAD_FAST]:push 30
off=1173, [op=51 BINARY_ADD]:30 + 73 = 103
off=137B, [op=83 LOAD_CONST]:push 256
off=1182, [op=0E BINARY_MODULO]:103 % 256 = 103
off=1005, [op=58 BINARY_XOR]:145 ^ 0 = 145

上面这一段是将输入字节化,结合一个256字节的表,以及后面的加法和异或,就可以联想的rc4了
这就不用细看了,直接往后翻到最后一次试用256字节密钥表的地方,又跳过了1500行左右,后面只剩几百行了:

1
2
3
4
5
6
7
8
9
10
11
12
off=0D16, [op=6D LOAD_FAST]:push 32
off=113E, [op=6D LOAD_FAST]:push [98, 73, 58, 12, 191, 20, 226, 166, 150, 10, 237, 145, 208, 160, 197, 188, 21, 100, 46, 165, 38, 192, 40, 215, 101, 196, 167, 61, 49, 77, 155, 34, 115, 169, 96, 179, 54, 29, 9, 76, 128, 180, 70, 84, 181, 15, 211, 157, 59, 75, 218, 133, 132, 161, 242, 32, 99, 18, 199, 162, 83, 183, 102, 156, 137, 163, 89, 190, 110, 227, 3, 94, 142, 201, 158, 27, 184, 178, 39, 149, 74, 62, 69, 22, 126, 95, 234, 186, 244, 243, 103, 203, 107, 53, 219, 36, 41, 4, 5, 140, 147, 200, 93, 48, 45, 195, 141, 185, 249, 30, 8, 117, 113, 65, 224, 63, 170, 233, 60, 23, 131, 111, 35, 52, 80, 174, 212, 146, 204, 228, 239, 2, 238, 235, 88, 189, 106, 17, 114, 44, 47, 214, 171, 6, 209, 207, 121, 122, 182, 194, 91, 26, 64, 25, 139, 252, 7, 173, 86, 28, 104, 11, 223, 127, 125, 14, 251, 124, 16, 87, 231, 246, 50, 82, 136, 221, 130, 241, 172, 42, 97, 129, 205, 220, 144, 225, 120, 138, 57, 222, 250, 193, 206, 43, 13, 217, 164, 245, 148, 1, 202, 90, 109, 248, 253, 92, 187, 33, 19, 79, 67, 31, 105, 143, 153, 78, 123, 236, 56, 116, 66, 176, 118, 51, 175, 85, 255, 177, 254, 112, 213, 37, 210, 135, 72, 24, 232, 0, 168, 216, 230, 198, 134, 154, 240, 229, 152, 159, 151, 55, 81, 119, 108, 71, 247, 68]
off=0DEA, [op=6D LOAD_FAST]:push 82
off=0E10, [op=51 BINARY_ADD]:69 + 115 = 184
off=0DB1, [op=83 LOAD_CONST]:push 256
off=15E8, [op=0E BINARY_MODULO]:184 % 256 = 184
off=1592, [op=58 BINARY_XOR]:144 ^ 167 = 55
off=10D8, [op=83 LOAD_CONST]:push 61
off=154C, [op=58 BINARY_XOR]:61 ^ 55 = 10
off=138C, [op=5A CALL_FUNCTION]:
off=0DD6, [op=77 STORE_FAST]:pop '\n'
off=1227, [op=6D LOAD_FAST]:push '\x1bO\xf4\xd1\xf9\xf3X\x95\xb4\n\xec\xa5S\x9c\xba'

看到这个:'\x1bO\xf4\xd1\xf9\xf3X\x95\xb4\n\xec\xa5S\x9c\xba'
应该是rc4的最终结果了,为了证实,这次用1B4FF4D1F9F35895B40AECA5539CBA0A作为序列号输入重新log一遍
再观察这里确实得到'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
所以这一段rc4只要用{0x1B,0x4F,0xF4,0xD1,0xF9,0xF3,0x58,0x95,0xB4,0x0A,0xEC,0xA5,0x53,0x9C,0xBA,0x0A}做一次异或即可求解

 

最后几百行慢慢整理:

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
off=1F98, [op=45 BINARY_MULTIPLY]:0 * 2 = 0
off=22F2, [op=51 BINARY_ADD]:0 + 14 = 14
off=19AD, [op=58 BINARY_XOR]:14 ^ 5 = 11
off=2F94, [op=83 LOAD_CONST]:push 16
off=2504, [op=0E BINARY_MODULO]:11 % 16 = 11
off=2159, [op=5A CALL_FUNCTION]:
off=2C18, [op=83 LOAD_CONST]:push 8
off=25E8, [op=42 BINARY_LSHIFT]:8 << 165 = 42240
off=1D21, [op=6D LOAD_FAST]:push '\x1bO\xf4\xd1\xf9\xf3X\x95\xb4\n\xec\xa5S\x9c\xba\n'
off=2D5C, [op=6D LOAD_FAST]:push 5
off=2FCB, [op=6D LOAD_FAST]:push 14
off=2C4B, [op=83 LOAD_CONST]:push 2
off=2262, [op=6D LOAD_FAST]:push 0
off=1C92, [op=45 BINARY_MULTIPLY]:0 * 2 = 0
off=256D, [op=51 BINARY_ADD]:0 + 14 = 14
off=2103, [op=83 LOAD_CONST]:push 1
off=2B25, [op=51 BINARY_ADD]:1 + 14 = 15
off=2000, [op=58 BINARY_XOR]:15 ^ 5 = 10
off=1FBD, [op=83 LOAD_CONST]:push 16
off=2464, [op=0E BINARY_MODULO]:10 % 16 = 10
off=1F11, [op=5A CALL_FUNCTION]:
off=2499, [op=51 BINARY_ADD]:236 + 42240 = 42476
off=26EA, [op=77 STORE_FAST]:pop 42476
off=1FCE, [op=6D LOAD_FAST]:push []
off=24F4, [op=6D LOAD_FAST]:push 42476
off=28E7, [op=11 INPLACE_ADD]:[42476] + [42476] = [42476]
...中间省略600多行
off=2817, [op=6D LOAD_FAST]:push '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6['
off=2208, [op=6D LOAD_FAST]:push [34821, 56848, 41409, 17074, 3004, 54811, 30811, 30763]
off=2CCD, [op=6D LOAD_FAST]:push 6
off=304F, [op=83 LOAD_CONST]:push 8
off=1DE3, [op=13 BINARY_RSHIFT]:8 >> 30811 = 120
off=2FB9, [op=5A CALL_FUNCTION]:
off=2C2A, [op=77 STORE_FAST]:pop '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x'
off=2E59, [op=77 STORE_FAST]:pop 7
off=1FA9, [op=6D LOAD_FAST]:push '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x'
off=2DB8, [op=6D LOAD_FAST]:push [34821, 56848, 41409, 17074, 3004, 54811, 30811, 30763]
off=25A0, [op=6D LOAD_FAST]:push 7
off=24E1, [op=83 LOAD_CONST]:push 255
off=20CF, [op=12 BINARY_AND]:255 & 30763 = 43
off=190D, [op=5A CALL_FUNCTION]:
off=2AC6, [op=77 STORE_FAST]:pop '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+'
off=2817, [op=6D LOAD_FAST]:push '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+'
off=2208, [op=6D LOAD_FAST]:push [34821, 56848, 41409, 17074, 3004, 54811, 30811, 30763]
off=2CCD, [op=6D LOAD_FAST]:push 7
off=304F, [op=83 LOAD_CONST]:push 8
off=1DE3, [op=13 BINARY_RSHIFT]:8 >> 30763 = 120
off=2FB9, [op=5A CALL_FUNCTION]:
off=2C2A, [op=77 STORE_FAST]:pop '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+x'
off=1AEF, [op=6D LOAD_FAST]:push '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+x'
off=0970, [op=77 STORE_FAST]:pop '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+x'
off=0FF9, [op=6D LOAD_FAST]:push '\x05\x88\x10\xde\xc1\xa1\xb2B\xbc\x0b\x1b\xd6[x+x'
off=0A10, [op=6D LOAD_FAST]:push 'KCTF@021GoodLuck'

上面一段WORD操作的算法整出来这样的:

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
void decode(WORD *t,WORD *o)
{
    WORD u,v,w,y;
    WORD k,e;
    WORD n,h;
 
    u = t[5] ^ t[2];
    v = t[3] + t[0];
    y = t[1] - t[6];
 
    w = u & v;
    h = ((~u & y) | w);
 
    k = get_bits1(t[7] ^ t[4]);
    o[7] = rotl16(h ^ t[4], k);
    o[6] = rotl16(h ^ t[7], k);
 
    n = (h * u >> k) + 0x18;
 
    o[5] = t[6] + n;
    o[4] = t[1] + n;
 
    o[3] = t[0] - (y ^ n);
    o[2] = t[3] + (y ^ n);
 
    e = (h | n) & (y ^ n) | (h & n);
    o[1] = e ^ t[2];
    o[0] = e ^ t[5];
}

8个WORD拼起来等于'KCTF@021GoodLuck'就OK了,keygen:

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
void encode(WORD *t,WORD *o)
{
    DWORD i;
    WORD u,v,w,y,k,e,n,h;
 
    y = t[4] - t[5];
    v = t[2] + t[3];
    u = t[0] ^ t[1];
    w = u & v;
    h = ((~u & y) | w);
    k = get_bits1(t[6] ^ t[7]);
    n = (h * u >> k) + 0x18;
    e = (h | n) & (y ^ n) | (h & n);
 
    o[4] = rotl16(t[7], 16 - k) ^ h;
    o[7] = rotl16(t[6], 16 - k) ^ h;
 
    o[6] = t[5] - n;
    o[1] = t[4] - n;
 
    o[0] = t[3] + (y ^ n);
    o[3] = t[2] - (y ^ n);
 
    o[2] = e ^ t[1];
    o[5] = e ^ t[0];
}
 
void kg()
{
    BYTE sn[16] = {0x1B,0x4F,0xF4,0xD1,0xF9,0xF3,0x58,0x95,0xB4,0x0A,0xEC,0xA5,0x53,0x9C,0xBA,0x0A};
    BYTE x[16] = {0};
    WORD y[8] = {0};
    int i;
 
    memcpy(y, "KCTF@021GoodLuck", 16);
    encode(y, (WORD *)x);
    for (i=0;i<16;i++)
    {
        sn[i] ^= x[i];
    }
}

编译运行得到:AD0A1F8179ABE48ED3B073F840DA52A7


【公告】看雪招聘大学实习生!看雪20年安全圈的口碑,助你快速成长!

最后于 2021-12-8 10:09 被ccfer编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回