学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

116

积分

0

好友

25

主题
发表于 2020-6-15 00:47:55 | 查看: 2322| 回复: 0

相关题目:


前言  就我感觉angr比较适合用来解决混淆的题目,面对混淆题去混淆感觉自己能力不够,直接动态调试,又觉得非常浪费时间,那么这时angr可以成为非常好的帮手。
如何快速的寻找find和avoid  在解题时我们时常会遇到带有强混淆的程序,这类程序要找出所有的find和avoid是一件耗时耗力的事情,那么我们可以采取何种高效的办法进行寻找呢?
  这里以hackcon2016_angry-reverser为例。
  IDA载入

深入浅出angr(六)

深入浅出angr(六)
  很明显的混淆,如果自己分析一遍,然后去除混淆也是需要费点时间的,不过如果你掌握了angr,那么只需要几分钟就可以解决此题,根本不要关心其使用了何种加密方式。
  此题中,正确的路径只有一条find=0x405a6e,需要避免的路径则有很多,我们可以通过如下代码,得到所有需要avoid的地址。
e = open('./yolomolo', 'rb').read()

avoids = []

index = 0
while True:
index = e.find(b'\xB9\x00\x00\x00\x00',index+1)
if index == -1:
break
addr = 0x400000 + index
avoids.append()

print (len(avoids))
print (avoids)
  其中\xB9\x00\x00\x00\x00是mov ecx 0的机器码,因此完整代码可以如下组织:
import angr
import claripy

def main():
flag    = claripy.BVS('flag', 20*8, explicit_name=True)
buf     = 0x606000
crazy   = 0x400646
find    = 0x405a6e
e = open('./yolomolo', 'rb').read()

avoids = []

index = 0
while True:
index = e.find(b'\xB9\x00\x00\x00\x00',index+1)
if index == -1:
break
addr = 0x400000 + index
avoids.append(addr)

proj = angr.Project('./yolomolo')
state = proj.factory.blank_state(addr=crazy, add_options={angr.options.LAZY_SOLVES})

state.memory.store(buf, flag, endness='Iend_BE')
state.regs.rdi = buf


for i in range(19):
state.solver.add(flag.get_byte(i) >= 0x30)
state.solver.add(flag.get_byte(i) <= 0x7f)

simgr = proj.factory.simulation_manager(state)

simgr.explore(find=find, avoid=avoids)
found = simgr.found[0]
return found.solver.eval(flag, cast_to=bytes)

if __name__ in '__main__':
import logging
logging.getLogger('angr.sim_manager').setLevel(logging.DEBUG)
print(main())

例题  其实angr最适合拿来解决线性的程序。
就比如说这题ekopartyctf2016_rev250

深入浅出angr(六)

深入浅出angr(六)
  如果去混淆,不一定能去除成功,如果动态调试,必定会耗费相当多的时间。如果你会使用angr,那么使用angr是在容易不过的事情了。
  由于需要调用当前的动态库,我们可以这样运行LD_LIBRARY_PATH=./ ./FUck_binary

深入浅出angr(六)

深入浅出angr(六)
  OK,并不是命令行参数输入。
  通过IDA,获取更多的信息。

深入浅出angr(六)

深入浅出angr(六)
  最终的find应该在这里。

深入浅出angr(六)

深入浅出angr(六)
  需要避免的分支0x403ABA,403A7E等
  我们可以通过之前提到过的方法提取出所有的avoid分支。
avoids = []
def get_avoids():
file_bytes = open('./FUck_binary','rb').read()
index = 0
while True:
index = file_bytes.find(b'\x66\x90',index+1)
if index == -1:
break
if index < 0x3a7e:
continue
addr = 0x400000+index
avoids.append(addr)
  在对输入进行条件约束时我们可以这么组织,这是常用的限制可打印字符的方式。
  state.solver.And(c <= '~', c >= ' ')
  跑了一下结果还以为代码写错了,这答案也太让人摸不着头脑了。

深入浅出angr(六)

深入浅出angr(六)
  代码如下:
import angr
import claripy

BUF_LEN = 100

avoids = []
def get_avoids():
file_bytes = open('./FUck_binary','rb').read()
index = 0
while True:
index = file_bytes.find(b'\x66\x90',index+1)
if index == -1:
break
if index < 0x3a7e:
continue
addr = 0x400000+index
avoids.append(addr)
def main():

p = angr.Project('FUck_binary')
flag = claripy.BVS('flag', BUF_LEN*8)
state = p.factory.entry_state(stdin=flag)

for c in flag.chop(8):
state.solver.add(state.solver.And(c <= '~', c >= ' '))

ex = p.factory.simulation_manager(state)
ex.explore(find=0x403a40,avoid=avoids)

found = ex.found[0]
print(found.posix.dumps(0))

if __name__ == '__main__':
#main()
get_avoids()
main()
总结
  既然选择了angr,便只顾风雨兼程



温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-3-29 17:20 , Processed in 0.095888 second(s), 41 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表