angr学习[1]简单加载程序分析,设置寄存器

0x01简介
之前学了一些但是后来没有跟进,慢慢忘了,最近找到一个比较好的学习github项目,系统地重新学一下

angr是一种模糊执行工具,不是太清楚怎么做的但是比直接爆破要好很多就对了。
并且angr提供了一个强大的功能,可以加载分析人以平台下的二进制文件。

原github项目地址
https://github.com/jakespringer/angr_ctf

下面的代码会给出两部分
1.官网给出的代码,但是需要填写一些内容。 我这里会填上之后放进来
2.我自己跟着写的。 这上面会加上我的理解

0x02环境搭建
需要pypy来运行generate.py 编译出来二进制文件。
需要给pypy安装pip 用来安装库 这东西好像跟python没多大区别

python2
需要安装angr python2 -m pip install angr

编译命令 pypy generate.py 1 1


0x00简单加载分析
github上并没有给地址,这里是我自己填上的,程序不同地址可能会不同

填上官网给的脚本的地址空缺

#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# Before you begin, here are a few notes about these capture-the-flag
# challenges.
#
# Each binary, when run, will ask for a password, which can be entered via stdin
# (typing it into the console.) Many of the levels will accept many different
# passwords. Your goal is to find a single password that works for each binary.
#
# If you enter an incorrect password, the program will print "Try again." If you
# enter a correct password, the program will print "Good Job."
#
# Each challenge will be accompanied by a file like this one, named
# "scaffoldXX.py". It will offer guidance as well as the skeleton of a possible
# solution. You will have to edit each file. In some cases, you will have to
# edit it significantly. While use of these files is recommended, you can write
# a solution without them, if you find that they are too restrictive.
#
# Places in the scaffoldXX.py that require a simple substitution will be marked
# with three question marks (???). Places that require more code will be marked
# with an ellipsis (...). Comments will document any new concepts, but will be
# omitted for concepts that have already been covered (you will need to use
# previous scaffoldXX.py files as a reference to solve the challenges.) If a
# comment documents a part of the code that needs to be changed, it will be
# marked with an exclamation point at the end, on a separate line (!).

import angr
import sys

def main(argv):
  # Create an Angr project.
  # If you want to be able to point to the binary from the command line, you can
  # use argv[1] as the parameter. Then, you can run the script from the command
  # line as follows:
  # python ./scaffold00.py [binary]
  # (!)
  path_to_binary = "1"  # :string
  project = angr.Project(path_to_binary)

  # Tell Angr where to start executing (should it start from the main()
  # function or somewhere else?) For now, use the entry_state function
  # to instruct Angr to start from the main() function.
  initial_state = project.factory.entry_state()

  # Create a simulation manager initialized with the starting state. It provides
  # a number of useful tools to search and execute the binary.
  simulation = project.factory.simgr(initial_state)

  # Explore the binary to attempt to find the address that prints "Good Job."
  # You will have to find the address you want to find and insert it here. 
  # This function will keep executing until it either finds a solution or it 
  # has explored every possible path through the executable.
  # (!)
  print_good_address = 0x08048675  # :integer (probably in hexadecimal)
  simulation.explore(find=print_good_address)

  # Check that we have found a solution. The simulation.explore() method will
  # set simulation.found to a list of the states that it could find that reach
  # the instruction we asked it to search for. Remember, in Python, if a list
  # is empty, it will be evaluated as false, otherwise true.
  if simulation.found:
    # The explore method stops after it finds a single state that arrives at the
    # target address.
    solution_state = simulation.found[0]

    # Print the string that Angr wrote to stdin to follow solution_state. This 
    # is our solution.
    print solution_state.posix.dumps(sys.stdin.fileno())
  else:
    # If Angr could not find a path that reaches print_good_address, throw an
    # error. Perhaps you mistyped the print_good_address?
    raise Exception('Could not find the solution')

if __name__ == '__main__':
  main(sys.argv)

加上我的理解

# -*- coding:utf-8 -*-
#https://github.com/jakespringer/angr_ctf
"""
运行步骤:
    1.创建project载入要分析的文件
    2.告诉angr从哪里加载
    3.告诉angr到哪里结束,angr会探索这些结果
    4.判断是否有想要的结果然后输出

"""
import angr
import sys
reload(sys)
sys.setdefaultencoding('utf8')


def main(argv):
    path_to_binary = "1"  # :string
    project = angr.Project(path_to_binary)#要分析的二进制文件

    # 告诉ange从哪里开始执行entry_state() 表示从main函数开始
    initial_state=project.factory.entry_state()

    #创建一个使用起始状态初始化的模拟管理器。它提供
    #一些有用的工具来搜索和执行二进制文件。
    simulation=project.factory.simgr(initial_state)

    #函数会一直运行直到运行到0x08048675这个地质处,或者探索了每条可能路径
    print_good_address = 0x08048675  # :integer (probably in hexadecimal)
    simulation.explore(find=print_good_address)
    #找到的方案会存放到simulation.found列表里面(列表里面存放的是地址)
    if simulation.found:
        solution_state=simulation.found[0]
        #用这种方式输出内容
        print solution_state.posix.dumps(sys.stdin.fileno())
    else:
        raise Exception("Could not find the solution")
if __name__=="__main__":
    main(sys.argv)

0x01这里添加了avoid用来排除错误的位置

git给出

import angr
import sys
reload(sys)
sys.setdefaultencoding('utf8')

def main(argv):
  path_to_binary = "1"
  project = angr.Project(path_to_binary)
  initial_state = project.factory.entry_state()
  simulation = project.factory.simgr(initial_state)

  # Explore the binary, but this time, instead of only looking for a state that
  # reaches the print_good_address, also find a state that does not reach 
  # will_not_succeed_address. The binary is pretty large, to save you some time,
  # everything you will need to look at is near the beginning of the address 
  # space.
  # (!)
  print_good_address = 0x080485E0
  will_not_succeed_address = 0x080485F2
  simulation.explore(find=print_good_address, avoid=will_not_succeed_address)

  if simulation.found:
    solution_state = simulation.found[0]
    print solution_state.posix.dumps(sys.stdin.fileno())
  else:
    raise Exception('Could not find the solution')

if __name__ == '__main__':
  main(sys.argv)

我的理解

# -*- coding:utf-8 -*-
import angr
import sys
reload(sys)
sys.setdefaultencoding("utf8")

def main(argv):

    project=angr.Project("1")
    initial_state=project.factory.entry_state()
    simulation=project.factory.simgr(initial_state)

    print_good_address=0x080485E0
    will_not_succeed_address=0x080485F2
    #这里除了找得到一个正确的地方还要找到一个不正确的地方,这样可以减少探索时间
    simulation.explore(find=print_good_address,avoid=will_not_succeed_address)

    if simulation.found:
        solution_astate=simulation.found[0]
        print solution_astate.posix.dumps(sys.stdin.fileno())
    else:
        raise Exception('Could not find the solution')

if __name__ == '__main__':
    main(sys.argv)

0x02如何避免在代码里面写入地址
git给出

# It is very useful to be able to search for a state that reaches a certain
# instruction. However, in some cases, you may not know the address of the
# specific instruction you want to reach (or perhaps there is no single
# instruction goal.) In this challenge, you don't know which instruction
# grants you success. Instead, you just know that you want to find a state where
# the binary prints "Good Job."
#
# Angr is powerful in that it allows you to search for a states that meets an
# arbitrary condition that you specify in Python, using a predicate you define
# as a function that takes a state and returns True if you have found what you
# are looking for, and False otherwise.

import angr
import sys
reload(sys)
sys.setdefaultencoding('utf8')

def main(argv):
  path_to_binary = argv[1]
  project = angr.Project(path_to_binary)
  initial_state = project.factory.entry_state()
  simulation = project.factory.simgr(initial_state)

  # Define a function that checks if you have found the state you are looking
  # for.
  def is_successful(state):
    # Dump whatever has been printed out by the binary so far into a string.
    stdout_output = state.posix.dumps(sys.stdout.fileno())
    #print(stdout_output)
    # Return whether 'Good Job.' has been printed yet.
    # (!)
    return 'Good Job.' in stdout_output# :boolean


  # Same as above, but this time check if the state should abort. If you return
  # False, Angr will continue to step the state. In this specific challenge, the
  # only time at which you will know you should abort is when the program prints
  # "Try again."
  def should_abort(state):
    stdout_output = state.posix.dumps(sys.stdout.fileno())

    return 'Try again.' in stdout_output


  # Tell Angr to explore the binary and find any state that is_successful identfies
  # as a successful state by returning True.
  simulation.explore(find=is_successful, avoid=should_abort)

  if simulation.found:
    solution_state = simulation.found[0]
    print solution_state.posix.dumps(sys.stdin.fileno())
  else:
    raise Exception('Could not find the solution')

if __name__ == '__main__':
  main(sys.argv)

我的理解

# -*- coding:utf-8 -*-

import angr
import sys
reload(sys)
sys.setdefaultencoding("utf8")

#和上一个不同这里用is_successful和should_abort两个bool型函数代替了原本的地址。
#也就是说simulation.explore()函数会接收find 和avoid的值,在find为True的时候结束探索。 在avoid为True的时候会重新开始新一轮探索

#使用条件是:有明确输出正确或错误。
#优势:省去了找两个地址的时间,也会兼容更多编译出来的代码

def main(argv):
    project=angr.Project("1")
    initial_state=project.factory.entry_state()
    simulation=project.factory.simgr(initial_state)

    def is_successful(state):
        stdout_output=state.posix.dumps(sys.stdout.fileno())

        return "Good Job." in stdout_output

    def should_abort(state):
        stdout_output=state.posix.dumps(sys.stdout.fileno())
        return "Try agarn." in stdout_output

    simulation.explore(find=is_successful,avoid=should_abort)

    if simulation.found:
        solution_state=simulation.found[0]
        print solution_state.posix.dumps(sys.stdin.fileno())
    else:
        raise Exception("Could not find the  solution")

if __name__=='__main__':
    main(sys.argv)

接下来会持续更新这个再接再厉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值