Exploit writing tutorial part 3 : SEH Based Exploits
Ở
2 phần trước, chúng ta đã nói về stack overflow. Phần này, chúng ta sẽ
nói về một phương pháp khai thác khác sử dụng ngoại lệ, để từ đó thực
hiện lệnh nhảy tới đoạn code mong muốn.
Trước hết, cần phải nói về ngoại lệ - exception handlers ?
Việc
bắt ngoại lệ được đặt trong ứng dụng, mục đích để bắt các ngoại lệ mà
ứng dụng có thể gặp phải ( ví dụ như file không tồn tại, hay chia cho
0...)
try
{
//run stuff. If an exception occurs, go to
}
catch
{
// run stuff when exception occurs
}
Nếu trong một chương trình bình thường không sử dụng ngoại lệ, đầu tiên sẽ đẩy vào các tham số, rồi đến EIP, EBP, tiếp đến cấp phát cho các biến cục bộ. Nếu chương trình có sử dụng ngoại lệ, sẽ cấp phát thêm một vùng để chứa ngoại lệ
"Address
of exception handler" là một phần của SEH record. Windows có một SEH
mặc định (Structured Exception Handler) để bắt ngoại lệ. Khi mà ngoại lệ
này được bắt, bạn sẽ thấy một popup “xxx has encountered a problem and
needs to close”.
Để
ứng dụng có thể trỏ đến catch code, con trỏ sẽ trỏ tới exception
handler code được lưu trên stack. Mỗi code block có một frame của riêng
mình. Nói cách khác, mỗi chương trình có một stack frame, nếu ngoại lệ
được triển khai trong chương trình, ngoại lệ sẽ được xử lý trong stack
frame này. Thông tin về ngoại lệ được lưu trữ trong
exception_registration của stack
Cấu trúc của SEH record là 8bytes gồm 2 block 4 bytes.
Một con trỏ trỏ đến exception_registration tiếp theo, thường là SEH record tiếp theo
Con trỏ trỏ tới địa chỉ của exception handler code
Ở
phía trên của các khối dữ liệu chính (các khối dữ liệu của chức năng
của main, hoặc TEB TEB (Thread Environment Block) / TIB (Thread
Information Block), một con trỏ trỏ đến đầu của chuỗi SEH được đặt.
Chuỗi SEH này thường được gọi là FS: [0]
Vì
vậy, khi nhìn vào mã lệnh Intel bạn sẽ thấy lệnh DWORD ptr từ FS: [0].
Điều này đảm bảo rằng xử lý ngoại lệ được thiết lập và sẽ có thể bắt lỗi
khi chúng xảy ra. Opcode của lệnh này là 64A100000000. Nếu bạn không
thể tìm thấy opcode này, các ứng dụng / thread không có thể có ngoại lệ
xử lý.
Dưới
cùng của chuỗi SEH được chỉ định bởi FFFFFFFF. Điều này sẽ kích hoạt
kết thúc không của chương trình (và hệ điều hành xử lý sẽ kick vào)
How can we then use the SEH to jump to shellcode ?
Lý
thuyết là, nếu bạn có thể ghi đè SE handler để sử dụng khi ngoại lệ
được kích hoạt, chúng ta có thể buộc ứng dụng nhảy tới code mà chúng ta
mong muốn ( giống như stack overflow). Tuy nhiên, bằng cơ chế XOR, trước
khi mà ngoại lệ được kích hoạt, các thanh ghi sẽ được XOR trỏ
0×00000000 cho nên chúng ta không thể sử dụng được kỹ thuật jump reg như
bình thường.
Thay
vào đó, chúng sẽ sử dụng pop pop ret. Bình thường, các next SEH sẽ chứa
địa chỉ của SEH tiếp theo, SE handler chứa địa chỉ của code sẽ được
ngoại lệ thực thi. Chúng ta sẽ:
Gây ra một ngoại lệ, mục đích là kích hoạt SEH. Đương nhiên, phần giá trị của SEH record đã bị chúng ta điều khiển.
Ghi đè địa chỉ của next SEH bằng địa chỉ của jump code
Ghi đè địa chỉ của SEH handler bằng địa chỉ của pop pop retn
Khi
ngoại lệ được kích hoạt, con trỏ EIP trỏ tới SEH handler, lúc này trỏ
tới địa chỉ pop pop retn. Lúc này, lần lượt sẽ lấy trong stack ra 2 lần,
mỗi lần 4 bytes, có nghĩa là ESP + 8. Điều đó có nghĩa là con trỏ stack
trỏ tới next SEH.
Tiến
hành retn lấy địa chỉ lưu trong next SEH, nhưng nó không còn chứa địa
chỉ trỏ tới SEH record nữa mà trỏ tới jumpcode. Ở đây, thường là nhảy
8bytes. Để đảm bảo, thường nhảy 30bytes với NOP được sử dụng để cách.
Sơ đồ như sau:
1st exception occurs :|
--------------------------- (1)
|
-------+-------------- (3) opcode in next SEH : jump over SE Handler to the shellcode
| | |
| V V
[ Junk buffer ][ next SEH ][ SE Handler ][ Shellcode ]
opcode to do (3) Shellcode gets executed
jump over pop pop ret
SE Handler |
^ |
| |
-------------- (2) will ‘pretend’ there’s a second exception, puts address of next SEH location in EIP, so opcode gets exe
------------------------------------------------------------
Thanks for reading
--------------------------------------------------------------------------
Security Research
All my Lab:
Linux Lab -- window and Cisco Lab
to be continued - I will update more.
Comments