Bin Workflow - Pez1181/CTF GitHub Wiki
file [file]
- ELF 32-bit LSB executable = x86 architecture.
- Dynamically linked = it relies on shared libraries like libc, which we may be able to abuse.
- Not stripped = symbol names are intact, which will make our life much easier when reverse engineering.
- Dynamically loaded interpreter = classic /lib/ld-linux.so.2
checksec --file=[file]
- RELRO: Partial = GOT entries written AFTER program startuo
- Canary: No = No overflow protection
- NX: Disabled = The Stack is EXECUTABLE, so shellcode can be injected and run
- PIE: No = Binary loaded at fixed adress. Makes ROP and ret2libc easier
- Symbols: 75 = named addresses for functions (main) (puts) etc
nm -C [file] | grep ' T '
- Lists all functions in the binary
gdb ./[file]
gdb> disass main
Look for other function calls. Example for CTFs would be a call to vuln.
gdb> disass vuln
Is there a gets? If there is, it reads user input without checking it's length. It will happily write past the bounds of the buffer and onto the stack. Note eax (for example eax, [ebp-0xb8])
gdb> cyclic 200
This will generate a string to write to the stack. Copy and paste it for use in the user input. When the program crashes, we check eip to find the value with:
gdb> cyclic -l [value]
This will tell you the offset. Then we need the buffer address:
gdb> b *[vuln_func_name]+[offset_for_gets]
Eg, if the disass of vuln listed gets at <+31>, then the command would be:
gdb> b *vuln+31
gdb> run
gdb> info frame
If this shows ebp, and we know from vuln disass that eax = ebp - 0xb8, then we can calculate the buffer address.
If you need for example flag(arg1, arg2), then the stack needs to be:
- addresss of flag()
- ret address
- arg 1
- arg 2