首页
社区
课程
招聘
[原创]GKCTF2021 KillerAid
2022-1-17 17:58 17142

[原创]GKCTF2021 KillerAid

2022-1-17 17:58
17142

逻辑分析

题目附件为exe和dll,拖进DIE分析可知exe为c#编写,dll为c++编写。

 

 

 

将exe丢进dnspy即可查看主要逻辑。

 

 

当输入的code和id满足条件的时候就会调用dll里的checkcode进行逻辑判断,运行调试时,程序窗口不会出现,应该是有反调试。

 

用ida打开dll的CheckCode函数,Findcrypt插件发现这个函数使用了AES的sbox,函数最后将加密之后的输入和一个32字节的数据进行比较并返回结果。

总结

  1. 前端为c#编写,如果输入的id和code满足条件就调用dll中的CheckCode进行判断,并且程序存在反调试功能
  2. dll中的CheckCode先将输入进行加密,之后和某32字节的数据进行比较

动态调试

反调试

首先可以用x64dbg打开程序,用api断点断到IsDebuggerPresent函数,并将PEB->BeingDebugged改为0(详解去查找Windows反调试技术),然后就可以跟踪到dll中的某个反调试函数

 

 

复制当前指令的首字节地址,用ida打开dll并跳转到复制的地址

 

 

查看函数的引用,发现最开始是CreateThread调用了相关函数,所以这个程序是启动了一个新线程进行反调试

 

 

将CreateThread函数调用的函数内容patch为ret(简单粗暴),即可进行动态调试。

外层逻辑判断

输入的id再与code进行异或之后等于给定的arrary即可,异或次数为MAX(len(id),len(code)),长度不够的与自身长度进行取模操作。

 

id固定为9个字节,假定code比id长(aes需要16字节),得出脚本

1
2
3
4
5
6
7
8
9
array=[7,90,115,1,117,99,114,97,24]
id=array
code=list(b'))baa!!!(@@###qq')
for i in range(len(code)):
    id[i%9]=code[i]^id[i%9]
idstr=''
for i in range(9):
    idstr+=chr(id[i])
print(idstr)

CheckCode逻辑

基于AES进行的魔改,但是AES内部没改,初始的key和iv都是全局变量。

 

大体逻辑为

1
2
3
4
5
6
7
8
for(int i=0;i<32;i++){
    keyexpantion(key)
    AES_CBC(code,key,iv)
    iv=SubBytes(iv)
    key^=iv
    key=SbuBytes(key)
    iv^=key
}

用x64dbg提取出iv和key的初始值和最后比较用的数据,然后用python实现SubBytes即可写出解密脚本

 

iv和key的初始赋值,可以用偏移在x64dbg中定位

 

最后比较用的字节

exp

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
from Crypto.Cipher import AES
sbox = [[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76],
        [0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0],
        [0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15],
        [0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75],
        [0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84],
        [0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF],
        [0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8],
        [0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2],
        [0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73],
        [0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB],
        [0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79],
        [0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08],
        [0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A],
        [0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E],
        [0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF],
        [0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]]
def SubBytes(state):
    return [sbox[i][j] for i,j in [(t>>4,t&0xf) for t in state]]
def Bytesxor(data1,data2):
    data1=list(data1)
    data2=list(data2)
    res=[]
    for i in range(len(data1)):
        res.append(data1[i]^data2[i])
    return bytearray(res)
key=bytearray(b'\x29\x23\xBE\x84\xE1\x6C\xD6\xAE\x52\x90\x49\xF1\xF1\xBB\xE9\xEB')
iv=bytearray(b'\xB3\xA6\xDB\x3C\x87\x0C\x3E\x99\x24\x5E\x0D\x1C\x06\xB7\x47\xDE')
keyarray=[]
keyarray.append(key)
ivarray=[]
ivarray.append(iv)
data=b'\xF6\x1C\xE3\xD7\xF9\xFB\x0B\x1A\x8B\xA2\x1D\xD8\x97\x94\x05\xC4\x6D\x97\xE7\x62\xB6\x7C\xEF\x9A\x88\x1B\xA4\x4D\xFD\xB0\xE4\x6E'
for i in range(31):
    iv=bytearray(SubBytes(iv))
    key=Bytesxor(key, iv)
    key=bytearray(SubBytes(key))
    keyarray.append(key)
    iv=Bytesxor(key, iv)
    ivarray.append(iv)
keyarray.reverse()
ivarray.reverse()
print(len(keyarray))
for i in range(32):
    key=keyarray[i]
    iv=ivarray[i]
    aes=AES.new(bytes(key), AES.MODE_CBC,bytes(iv))
    data=aes.decrypt(data)
print(data)
'''
iv=subbytes(iv)
key=key^iv
key=subbytes(key)
iv^=key
'''
'''
key
29 23 BE 84 E1 6C D6 AE 52 90 49 F1 F1 BB E9 EB
1B C5 C5 A8 42 4F 43 09 43 E8 0B 3C 0B C9 3B 42
26 27 03 37 AE 17 98 5E 1D 76 5D 86 52 D4 15 5D
20 56 F3 DF E4 A7 7E E5 70 68 69 D5 70 F7 F9 C9
'''

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2022-1-18 21:29 被/x01编辑 ,原因:
上传的附件:
收藏
点赞2
打赏
分享
最新回复 (2)
雪    币: 17842
活跃值: (59828)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2022-1-17 22:05
2
0
能否将题目上传到本地一份?
雪    币: 1243
活跃值: (1488)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
/x01 2022-1-18 21:30
3
0
Editor 能否将题目上传到本地一份?

好嘞,已上传

最后于 2022-1-18 21:31 被/x01编辑 ,原因:
游客
登录 | 注册 方可回帖
返回