首页
社区
课程
招聘
[原创]2019KCTF总决赛 第六题:三道八佛 WP
发表于: 2019-12-14 22:11 4286

[原创]2019KCTF总决赛 第六题:三道八佛 WP

2019-12-14 22:11
4286
先拉到x32dbg粗略分析下。

注意到用户名后面有填充数据。

密码则是从十六进制文本转换成字节数据,然后程序开始自解码。
$calleax = 0
$num = 0
$jnzaddr = 0
$f = 0
$prevaddr = 0
$retaddr=0
$hasj=0
bph 004014DF
run
//input the username and password
bphc
start:
find cip,FFD0,0x200
cmp $result,0
je over
mov $calleax,$result
bph $calleax
run
bphc
inc $num
StepInto
StepInto
StepOver
mov $jnzaddr,cip
find_jnz:
find cip,8BE55DC3,0x220
cmp $result,0
je nobp
mov $retaddr,$result
bph $retaddr+3
run
bphc
StepInto
StepInto
inc $num
mov $jnzaddr,cip
nobp:
find jnzaddr,75??,0x200
cmp $result,0
jnz isjnz
jnzs:
find cip,0F85????????,0x200
cmp $result,0
jnz isjnzs
jmp nofound
runtojnz:
mov f,0
bph $jnzaddr+2
mov $hasj,1
jmp jnzs
runtojnzs:
mov f,0
mov $jnzaddr,$result
bph $jnzaddr+6
run
bphc 
mov $hasj,0
nofound:
cmp $hasj,1
jnz nojump
mov $hasj,0
run
bphc
nojump:
jmp start
isjnz:
mov $jnzaddr,$result
$prevaddr = dis.prev($jnzaddr)
$prevaddr = $prevaddr + dis.len($prevaddr)
cmp $prevaddr,$jnzaddr
je runtojnz
add $jnzaddr,2
jmp find_jnz
isjnzs:
mov $jnzaddr,$result
$prevaddr = dis.prev($jnzaddr)
$prevaddr = $prevaddr + dis.len($prevaddr)
cmp $prevaddr,$jnzaddr
je runtojnzs
cmp $hasj,1
jnz noj
jmp nofound
noj:
add $jnzaddr,2
jmp find_jnz
over:
cmp f,0
jnz end
mov f,1
jnzaddr=cip
jmp find_jnz
end:
log decryptnum:{$num}
msg "over"

$calleax = 0
$num = 0
$jnzaddr = 0
$f = 0
$prevaddr = 0
$retaddr=0
$hasj=0
bph 004014DF
run
//input the username and password
bphc
start:
find cip,FFD0,0x200
cmp $result,0
je over
mov $calleax,$result
bph $calleax
run
bphc
inc $num
StepInto
StepInto
StepOver
mov $jnzaddr,cip
find_jnz:
find cip,8BE55DC3,0x220
cmp $result,0
je nobp
mov $retaddr,$result
bph $retaddr+3
run
bphc
StepInto
StepInto
inc $num
mov $jnzaddr,cip
nobp:
find jnzaddr,75??,0x200
cmp $result,0
jnz isjnz
jnzs:
find cip,0F85????????,0x200
cmp $result,0
jnz isjnzs
jmp nofound
runtojnz:
mov f,0
bph $jnzaddr+2
mov $hasj,1
jmp jnzs
runtojnzs:
mov f,0
mov $jnzaddr,$result
bph $jnzaddr+6
run
bphc 
mov $hasj,0
nofound:
cmp $hasj,1
jnz nojump
mov $hasj,0
run
bphc
nojump:
jmp start
isjnz:
mov $jnzaddr,$result
$prevaddr = dis.prev($jnzaddr)
$prevaddr = $prevaddr + dis.len($prevaddr)
cmp $prevaddr,$jnzaddr
je runtojnz
add $jnzaddr,2
jmp find_jnz
isjnzs:
mov $jnzaddr,$result
$prevaddr = dis.prev($jnzaddr)
$prevaddr = $prevaddr + dis.len($prevaddr)
cmp $prevaddr,$jnzaddr
je runtojnzs
cmp $hasj,1
jnz noj
jmp nofound
noj:
add $jnzaddr,2
jmp find_jnz
over:
cmp f,0
jnz end
mov f,1
jnzaddr=cip
jmp find_jnz
end:
log decryptnum:{$num}
msg "over"

跑完发现有1403层smc,相比之前的题算是手下留情了吧。
用脚本跑到最后一层,发现下面的代码是完整的函数,代码很长,还有很多重定位和混淆,故先全部提取到code文件并修正一下esi。
用IDA分析code文件,先修改基址为0x1A1857E,F5代码如下。

代码比较清晰了,serial经过计算,跟用户名比较,如果相同则成功。
注意KCTF用户名不足16位,后面的填充数据也是要比较的。也就是说实际上比较的是
4B 43 54 46 00 1A 19 18 17 16 15 14 13 12 11 10 00
提取反编译以后的代码,重新编译成exe以后使用angr跑出来flag。 这部分交给队友FiveEyes处理了。 python代码如下
# coding=utf-8
import angr
import claripy
import base64
def main():
    load_option = {}
    b = angr.Project("./ConsoleApplication21.exe", load_options=load_option)
    state = b.factory.blank_state(addr=0x401040)
    concrete_addr = 0x404378
    flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(30)]
    flag = claripy.Concat(*flag_chars)
    state.memory.store(concrete_addr, flag)
    sm = b.factory.simulation_manager(state)
    print sm.explore(find=0x4013A3)
    found = sm.found[0]
    temp = (found.posix.dumps(0))
    print temp
    solution = found.solver.eval(flag, cast_to=str)
    s = []
    for i in solution:
        s.append(ord(i))
    print s
    print solution.encode("hex").upper()
    print(solution)
    print flag, found
if __name__ == '__main__':
    main()

运行结果
 
得到flag:6CCDE9D2EC1D469DC67C647E66B4C565
用脚本跑到最后一层,发现下面的代码是完整的函数,代码很长,还有很多重定位和混淆,故先全部提取到code文件并修正一下esi。
用IDA分析code文件,先修改基址为0x1A1857E,F5代码如下。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-12-15 00:24 被梦游枪手编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//