pwnable.kr codemap writeup / OD 脚本解题

核心考察点

  • IDA静态分析能力
  • OD脚本编写能力

问题

运行nc 0 9021,程序要求输入第二大内存块中的字串和第三大内存块中的字串。

这里写图片描述

本地运行codemap,程序声称生成了1000个随机大小的堆块,每个堆块中存放一个随机的字符串,并且输出了最大长度字符串。

这里写图片描述

解题过程

IDA打开codemap,找到提示的0x403E65地址处代码。

这里写图片描述

在反编译代码中我们可以看到程序的随机种子是固定的,因此产生的伪随机字串以及伪随机大小每次程序运行都是一定的。(多运行两次codemap也能通过最大size的大小和字串发现)

这里写图片描述

在OD中对提示的地址下断(程序启用了ASLR,在相对同样地址下断即可)。运行发现eax与ebx即为随机内存size和随机字串(IDA中静态分析也能获知)。(实际下断在前一条指令,效果一样,因为此时eax与ebx值已指向内存size和随机字串)

这里写图片描述

因为有1000次分配,人工不现实,直接想到了OD的脚本插件ODBGScript。(第一次写的OD脚本,虽然最后很简单,还是费了好大劲QwQ)

bp 1013E62 //(根据载入地址变化)
loop:
    run
    log eax
    log ebx
    jmp loop

注:eax与ebx的值已及提示信息将输出到log窗口。在log窗口提前右击选择”log to file”,将输出到文件。(log窗口缓存不够)

这里写图片描述

接下来就用python脚本处理,对内存size大小排序,找到第二大和第三大内存块存储的字串就好了。(python脚本处理时,发现OD脚本只获取到999个数据!!差一个最后也不知道咋回事,还好1/500的概率没撞上QwQ)

import re
f = open("resss.txt","r") #log重定向的文件
re1 = re.compile(r'[0-9A-Fa-f]{8}')
re2 = re.compile(r'[0-9a-zA-Z]{15}')
lis = []
sizeLis = []
for line in f.readlines():
    if "eax" in line:
        res = re1.findall(line)
        sizeLis.append(int(res[0],16))
        #print res
        lis.append(int(res[0],16))
    elif "ebx" in line:
        res = re2.findall(line)
        #print res
        #print lis
        lis = lis + res
#print len(lis)
#print len(sizeLis)
sizeLis.sort()
secondBigSiz = sizeLis[-2]
thirdBigSiz = sizeLis[-3]
print "second Biggest size string:",lis[lis.index(secondBigSiz)+1]
print "third Biggest size string:",lis[lis.index(thirdBigSiz)+1]

程序运行结果:

这里写图片描述

在远程服务器上提交即获得flag:

这里写图片描述

总结

  • 解题的过程并非一帆风顺,初始准备用bpl来获取0x403E65处eax的值以及ebx指向的字串:
bpl 403e62,"eax"
bpl 403e65,"string [ebx]"
run

string [ebx] 表达式得到的值是???,地址解析失败。单点调试的时候是能够获取到字串值的,脚本连续运行可能导致ebx值迅速变化取值错误。(这是我的猜测)
bpl命令是利用设置条件记录断点(shift+F4)。此处eax值在后面与第二个脚本的结果相同,取值正确。
可能这是OD的一个待完善的地方。大神可留言帮助我理解。

这里写图片描述

  • 解题后在网上搜题解,才发现自己的想法并不是标准解题思路。网上大多数解题思路是使用IDA脚本(IDC或IDAPython)。也看到一种比较另类的解法,利用vs2015的追踪堆分配情况的功能来解题(https://www.52pojie.cn/forum.php?mod=viewthread&tid=593201)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值