A binary analysis tool in Python to automatically find paths to code
Angr is really useful for quickly solving some Reverse Engineering challenges. The most useful function allows you to define an address in a Linux binary, and it will run the binary with different inputs to slowly make progress toward that goal.
For a CTF challenge, you could point the goal to be after some if statements that you would otherwise have to reverse engineer. Then Angr will find a valid input that gets to the code after the if statements, solving the challenge for you.
Template
This template lets Angr do the magic to solve it automatically without much effort, but for more advanced examples see their documentation.
import angr# Change this binaryproject = angr.Project("./binary", auto_load_libs=False)@project.hook(0x401337)# Change this address to your targetdefprint_flag(state):print("Valid input:", state.posix.dumps(0)) project.terminate_execution()project.execute()
Examples
When you can and can't use Angr is something you just need to get a feel for, by trying it sometimes and seeing if it works. In most cases, you're looking for some check on an input you're giving, and finding how to get past that if statement is a tedious process. Here are some examples of decompiled code where Angr could be used:
Example 1
undefined8 main(void) {uint uVar1;int local_10;int local_c;printf("Enter the flag: ");__isoc99_scanf(&DAT_00102015,buf);for (local_c =0; local_c <0x1d; local_c = local_c +1) { uVar1 = (uint)(local_c >>0x1f) >>0x1e; buf[local_c] = buf[local_c] ^*(byte *)((long)&magic + (long)(int)((local_c + uVar1 &3) - uVar1)); } local_10 =0;while( true ) {if (0x1c< local_10) { // Hard if statement (computation in the for() loop above)puts("Correct flag!");// <--- TARGET Angr right here// Ghidra shows 0x00101231, and starts by default at 0x00100000, meaning// we're only 0x1231 into the binary. When Angr runs a program with PIE enabled,// it starts at 0x00400000. So the final address we target is 0x00401231return0; }if (buf[local_10] != flag[local_10]) break; local_10 = local_10 +1; }puts("Wrong flag!");return0;}