What does angr do
In summary, angr is a python framework for binary analysis in reverse engineering
See its github homepage angr for details
Symbolic Execution is a program analysis technology. It can analyze the program to get the input for specific code areas to execute. When using Symbolic Execution to analyze a program, the program uses symbolic values as input rather than the specific values used in general program execution. When the target code is reached, the analyzer can obtain the corresponding path constraint, and then obtain the specific value that can trigger the target code through the constraint solver From Wikipedia
My understanding is a blasting tool that can find its own way
Then talk about learning:
The topic of study comes from Github's ctf_angr.
There is a problem with the use environment. First fill in the blanks only for the topic description, and then add and modify after the environment is configured.
If you need a topic, search CTF directly in Github_ angr
The download is as follows:
This is the program source code. The title is in dist and the answer is in aolutions.
Similar types will be placed in one article
Just look at the problem. The blasting is complete. No problem. Use angr here to solve it
Open the corresponding py file provided by the title (with translation):
# 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 as the parameter. Then, you can run the script from the command # line as follows: # python ./scaffold00.py [binary] # (!) path_to_binary = ???# : string enter the address of the title file. argv comes from the console parameter. You can also enter the address directly 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. # Tell Angr where to start execution (it should start with main()). Now, use entry_ The state function instructs Angr to start with 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. #Create an impersonation manager initialized with the startup state. It provides many useful tools to search and execute binaries. 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. # (!) #Explore the binaries to try to find the address where you printed "well done". You must find the address you are looking for and insert it here. This function executes until a solution is found or all possible paths through the executable are explored. (!) print_good_address = ??? # :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. # Check if we found a solution. The explore () method sets simulation.found to be able to find the list of arrived States and the instructions we ask it to search. Remember, in Python, if the list is empty, it evaluates to false, otherwise it is true. if simulation.found: # The explore method stops after it finds a single state that arrives at the # target address. #The explore method stops after finding a single state that has reached the destination address. solution_state = simulation.found # Print the string that Angr wrote to stdin to follow solution_state. This # is our solution. # Print the string written by Angr to stdin to follow the 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? # If Angr cannot find the path to the print\u good\u address, an error is thrown. Maybe you typed the wrong address? raise Exception('Could not find the solution')#This is an error handling mechanism, and I don't understand it very well. You can take a look at Baidu if __name__ == '__main__': main(sys.argv)
The first time I saw it, I didn't think it would matter. I summarized the main processes:
First tell angr where the file address is:
project = angr.Project(path_to_binary)
Then tell the angr file where the main function is:
initial_state = project.factory.entry_state()
Create simulation manager:
simulation = angr.factory.simgr(initial_state)
Tell angr to enter the correct address:
angr.explore(find = print_good_address)
The answer is simple:
Open the title file, disassembly of main function failed:
This is the advantage of angr.
Open the corresponding py file:
import angr import sys def main(argv): path_to_binary = argv 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 = ??? will_not_succeed_address = ??? simulation.explore(find=print_good_address, avoid=will_not_succeed_address) if simulation.found: solution_state = simulation.found print solution_state.posix.dumps(sys.stdin.fileno()) else: raise Exception('Could not find the solution') if __name__ == '__main__': main(sys.argv)
Similar to the first question, there is an avoid.
As the name suggests, avoiding this path can make the blasting more accurate.
This avoid_me doesn't have to output the wrong address, but it's not a big problem to fill in that address.
You can see that there is a function after jump after each comparison.
Click this function:
There is a should_ Successful zero setting:
Therefore, this function is not executed correctly. If you tell angr whether it will jump with so many branch jump, is it more efficient.
So fill in:
should_ Success is define d as 1. Setting zero is an error.
The article part is my own understanding. If there are mistakes, I hope to point out, thinku.