Buffer Overflow Prep
Vietnamese version
Prepare
Trước khi đọc bài này, tôi nghĩ bạn nên có kiến thức nền về Buffer Overflow trên OS Linux, vì nó khá dễ, Đối với Windows nó phức tạp hơn 1 chút. Hmm, dù sao thì bạn nên học từ dễ đến khó để đạt được hiệu suất tối ưu nhất
Connect Machine bằng Remote Desktop Connection (credential: admin/password)
Some Binaries:
The SLMail installer.
The brainpan binary.
The dostackbufferoverflowgood binary.
The vulnserver binary.
A custom written "oscp" binary which contains 10 buffer overflows, each with a different EIP offset and set of badchars.
Guide for Exploiting Buffer Overflow: http://github.com/Tib3rius/Pentest-Cheatsheets/blob/master/exploits/buffer-overflows.rst
Machine này sẽ ôn luyện cho các bro ôn thi OSCP, nhưng tôi không có tiền thi nên tôi sẽ explorer nó hết mức có thể :>>
Quy trình cho exploit:
Fuzzing
Control EIP
Finding JMP ESP gadget
Finding Bad Chars
Generate Shellcode
Exploitation
Từng quy trình tôi sẽ làm rõ bên dưới:
Lí do Buffer Overflow ở Windows phức tạp hơn Linux là do:
Trên Windows, khi Buffer Overflow xảy ra, chương trình sẽ raise lỗi: Access Violation (0xC0000005) Windows sử dụng Structured Exception Handling (SEH) để quản lí lỗi nên thay vì hiển thị thông báo lỗi thì nó sẽ bắt lỗi và sử dụng try-except hoặc nó sẽ đóng chương trình hoặc nó sẽ raise 1 popup "The program has stopped working"
Trên Linux, khi Buffer Overflow xảy ra, nó sẽ không có SEH như Windows, mà sẽ gây lỗi Segmentation Fault (SIGSEGV) và In thông báo lỗi trực tiếp ra terminal vì nó sử dụng Signal Handling & Core Dump
Overflow 1
Đầu tiên, Tôi sẽ run oscp.exe với Immunity Debugger và đây là Output

Netcat đến IP của machine và port 1337.

Each rows correspond each challenge in this lab. If you want to pass payload to each challenge. Please enter following syntax: <Chall_name> <payload>, Example: OVERFLOW1 aaaaaaaaaaaa
Fuzzing
Tôi sử dụng script python sau để fuzzing buffer
Sau khi chạy script và sending payload thì màn hình Remote sẽ như sau:

Chú ý vào thanh status sẽ thấy rằng chương trình bị crash do địa chỉ EIP không được xác định
Controlling EIP
Tôi sử dụng script này để tìm ra chính xác padding đến EIP:
Output:

Sau khi chạy, ta có value của EIP là: 0x61757461. Sử dụng cyclic để tìm ra padding:
Sau khi đã biết chính xác padding để ghi đè đến EIP, tôi sẽ thay thế nó bằng 1 address JMP ESP.

Finding Bad Chars
Việc tìm bad chars để xem kí tự nào là kí tự sẽ bị thay đổi bởi chương trình. Khi các bad char được gửi lên server nó sẽ được thay thế bằng cặp từ \x0D\x0A (tức \r\n - cặp giá trị kết thúc dòng trong Windows). Từ đó ta có thể loại bỏ các kí tự đó trong shellcode của mình, không gây ra hỏng Shellcode.
Phạm vi của ASCII Table: từ 0 -> 256 nhưng tôi sẽ không gửi byte \x00 lên vì nó sẽ gây ra terminate chuỗi :>> nên sẽ loại luôn kí tự từ đầu.
Ta có thể thấy payload đã được thay đổi từ byte \x07 -> Bad char:
Remove nó khỏi mảng bad_char:
Làm tương tự với các byte tiếp theo:

Ta sẽ có list bad char: \x07, \x2e, \xa0.
Hoặc ta sẽ sử dụng command sau:
Mona sẽ gen cho tôi 1 file bin tại vị trí:
Sử dụng tệp này để so sánh với phần pattern bad chars:
Trong đó address là địa chỉ bắt đầu từ chuỗi \x01\x02\x03\....\xFF
Đây là output:

Finding JMP ESP gadget
Sau khi tôi tìm được các badchar thì tôi sẽ tìm các jump point trên memory của chương trình bằng command sau:
Nếu khi bạn enter thì của sổ Log Data sẽ hiện ra như sau:

Có thể thấy nó load lên các gadget từ Lib: essfunc.dll
Thì ta có tổng là 9 jump point. Bạn có thể pick bừa 1 cái để làm jump point
Chú ý dòng sau:
Quay trở lại CPU Windows: Windows > CPU - main thread, module oscp
Generate Shellcode
Bây giờ ta sẽ có viễn cảnh khai thác như sau:
Nếu Stack chứa shellcode thì sau khi JMP ESP, shellcode sẽ được thực thi
Tôi sẽ gen shellcode reverse shell bằng Metasploit như sau:
Sau khi gửi payload lên server ta có thể thấy shellcode đã bị ảnh hưởng:


Tính từ JMP ESP đến phần không bị ảnh hưởng là: 0x194FA40 - 0x194FA24 = 28 byte
Tôi sẽ padding với NOP operator: \x90

Đây chính là các NOP byte mà tôi đã chèn vào.
Final payload:
Done:


Overflow 2
Sau khi làm xong bài 1 thì tôi sẽ làm tiếp bài 2. Nhưng tôi sẽ không giải thích nhiều nữa nếu không có gì thay đổi với bài trước
Crash at 800 bytes:

Tôi sẽ tìm ra chính xác vị trí nó với cyclic:
Pattern tại thanh ghi EIP:

Có vẻ 634 là giá trị offset chính xác đến EIP. Ở dưới đây bạn thấy rằng \x0A và \x0D là vì payload tôi gửi lên là bad chars (Giữa 256 kí tự, tôi lại chọn đúng kí tự badchars 🤡)

Sau 1 hồi tôi tìm được 5 bad chars:
Done:

Do kĩ thuật khai thác ở bài lab này tương tự nhau nên tôi sẽ chỉ làm những bước quan trọng nhất để chuẩn bị cho việc khai thác.
Overflow 3

Overflow 4

Overflow 5

Overflow 6

Overflow 7

Overflow 8

Overflow 9

Overflow 10

Last updated
Was this helpful?

