This shows you the differences between two versions of the page.
|
isc:labs:05 [2024/11/03 22:10] florin.stancu |
isc:labs:05 [2025/11/04 11:49] (current) david.gherghita [Exercises] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Lab 05 - Application Security ====== | ====== Lab 05 - Application Security ====== | ||
| + | |||
| + | ===== Objectives ===== | ||
| + | |||
| + | * Call conventions & stack structure | ||
| + | * Buffer overflow vulnerabilities | ||
| + | * Using pwndbg & pwntools to facilitate exploit development | ||
| ===== Resources ===== | ===== Resources ===== | ||
| - | *[[https://dhavalkapil.com/blogs/Buffer-Overflow-Exploit/|Buffer overflow explained]] | + | * [[https://dhavalkapil.com/blogs/Buffer-Overflow-Exploit/|Buffer overflow explained]] |
| - | *[[https://dhavalkapil.com/blogs/Shellcode-Injection/|Shellcode explained]] | + | * [[https://dhavalkapil.com/blogs/Shellcode-Injection/|Shellcode explained]] |
| + | * [[https://chatgpt.com/share/67279837-b05c-800e-a60a-6629ef3dd7f7|ChatGPT's record for stack structure & buffer overflow]] //(same length, but why bother read the opinion of some anonymous industry expert when you got the popular AI kid parroting the same stuff, right?)// | ||
| ===== Setup ===== | ===== Setup ===== | ||
| - | * [[:isc:info:virtualmachine|Open a lab VM instance]] on [[https://cloud.grid.pub.ro|OpenStack]], use the **m1.medium** flavor for 2GB of RAM (required by ''pwndbg'' :(( ). | + | * [[:isc:info:virtualmachine|Open a lab VM instance]] on [[https://cloud.grid.pub.ro|OpenStack]]. |
| - | **If you're not using the OpenStack VM**: | + | **If you're using the local VM for ARM 64 (AArch64)**: |
| - | * Install the 32-bit **libc** and **gcc-multilib** packages: <code> | + | * You have ''x86'' cross-compilers pre-installed! Use ''i686-linux-gnu-gcc'' to build 32-bit programs and ''x86_64-linux-gnu-gcc'' for AMD64 targets; |
| - | sudo apt install libc6-dev-i386 gcc-multilib | + | * You also have [[https://www.qemu.org/docs/master/user/main.html|qemu-user]] properly installed inside the local VM, so you can simply run any x86 binaries and they'll get emulated! |
| - | </code> | + | * If you intend to use ''objdump'' aarch64-hosted/emulated x86 binaries, you must use the cross compiler suite's, so make sure to prefix it, e.g.: ''x86_86-gnu-linux-objdump''! |
| - | * Install the PwnDbg plugin: <code> | + | |
| - | git clone https://github.com/pwndbg/pwndbg | + | |
| - | cd pwndbg | + | |
| - | ./setup.sh | + | |
| - | </code> | + | |
| - | To check if everything is OK, run the command ''gdb'' with no arguments. The prompt should be similar to this: | + | Note that we are using [[https://github.com/pwndbg/pwndbg|PwnDbg]] instead of the classic GDB because it is much more user friendly. Hope you'll like it ;) |
| - | + | ||
| - | <code> | + | |
| - | ➜ gdb | + | |
| - | GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 | + | |
| - | ... | + | |
| - | pwndbg> | + | |
| - | </code> | + | |
| - | + | ||
| - | Enter ''q'' to exit GDB. We are using [[https://github.com/pwndbg/pwndbg|PwnDbg]] instead of the classic GDB because it is much more user friendly. Hope you'll like it ;) | + | |
| ===== Overview ===== | ===== Overview ===== | ||
| Line 37: | Line 30: | ||
| {{:isc:labs:stack_layout.png?700}} | {{:isc:labs:stack_layout.png?700}} | ||
| + | |||
| + | Also check out one of the resources linked on top ^^ ! | ||
| <note tip> | <note tip> | ||
| Line 142: | Line 137: | ||
| * Hint: you're on 64-bit, check the links above for the calling convention... | * Hint: you're on 64-bit, check the links above for the calling convention... | ||
| * Hint 2: you also don't have debugging info compiled-in, so you must use disassembly to find the RBP offset of the ''buf'' variable; | * Hint 2: you also don't have debugging info compiled-in, so you must use disassembly to find the RBP offset of the ''buf'' variable; | ||
| + | <spoiler In case of emergency, expand> | ||
| + | If this seems too difficult or you wasted too much time, just add ''-g'' to the ''gcc'' rule inside the Makefile, recompile and try it this way :( | ||
| + | </spoiler> | ||
| <solution -hidden> | <solution -hidden> | ||
| Line 157: | Line 155: | ||
| === [50p] 02. Stack overflow (EZ) === | === [50p] 02. Stack overflow (EZ) === | ||
| - | * Run & study the ''buffovf'' binary. There is a stack overflow vulnerability in there, can you see it? | + | * Run & study the ''buffovf'' binary. There is a vulnerability in there, can you see it? |
| * Yep, you **must** use stack overflow to get this flag! | * Yep, you **must** use stack overflow to get this flag! | ||
| * First, try to crash the program. Use programmatically generated input (e.g., from Python3); | * First, try to crash the program. Use programmatically generated input (e.g., from Python3); | ||
| Line 170: | Line 168: | ||
| * Next, try to answer this question: how many bytes do I need to overflow until I get to the EIP saved by the ''call''er (also see the stack diagram above)? | * Next, try to answer this question: how many bytes do I need to overflow until I get to the EIP saved by the ''call''er (also see the stack diagram above)? | ||
| - | * Use either ''objdump -S'' or ''pwndbg> disass <name>'' on the //vulnerable function// to figure out the offset of the buffer variable from the EBP register using the assembly code; | + | * Use either ''objdump -S -M intel'' or ''pwndbg> disass <name>'' on the //vulnerable function// to figure out the offset of the buffer variable from the EBP register using the assembly code; |
| * In order to check if the answer is right, try to use an input of the following form: ''%%b"A" * N + b"\xEF\xCD\xAB\x98"%%''; this should make the program segfault with the end instruction pointer at ''0x98ABCDEF'' (readily visible in pwndbg's automatic registers printing); | * In order to check if the answer is right, try to use an input of the following form: ''%%b"A" * N + b"\xEF\xCD\xAB\x98"%%''; this should make the program segfault with the end instruction pointer at ''0x98ABCDEF'' (readily visible in pwndbg's automatic registers printing); | ||
| * Things start to become easy; call the ''for_the_win'' function (simply replace the address above with the function's virtual address)! | * Things start to become easy; call the ''for_the_win'' function (simply replace the address above with the function's virtual address)! | ||
| * Do not forget: x86 uses little endian encoding for multi-byte integers! | * Do not forget: x86 uses little endian encoding for multi-byte integers! | ||
| - | * Another warning: ASLR is enabled and the program is compiled as position independent code! Use ''gdb'' to "leak" the function's address, which shouldn't change while using ''gdb'' (it uses the same constant seed for ASLR's randomizer)! | + | * As bonus, can you further chain calls to make the exploited program gracefully exit? |
| <solution -hidden> | <solution -hidden> | ||
| <code> | <code> | ||
| - | pwndbg> run "briliantul" < <(python3 -c 'import sys; sys.stdout.buffer.write(b"A" * 24 + b"\xa6\x91\x04\x08")') | + | pwndbg> run "Salam" < <(python3 -c 'import sys; sys.stdout.buffer.write(b"A" * 0x19 +b"\xa6\x91\x04\x08" + b"\x0e\x93\x04\x08" + b"\xbe\xba\xfe\xca")') |
| - | ... | + | |
| - | hey, args | + | |
| - | what's ur last name? | + | |
| - | almost there, try to supply the correct arguments! | + | |
| - | bye | + | |
| - | + | ||
| - | Program received signal SIGSEGV, Segmentation fault. | + | |
| </code> | </code> | ||
| </solution> | </solution> | ||