Windows Shellcode và ứng dụng khai thác lỗi tràn bộ đệm – Phần cuối
Hôm nay tôi sẽ kết thúc loạt bài viết về chủ đề “Windows ShellCode và ứng dụng khai thác lỗi tràn bộ đệm”. Tôi hi vọng đã mang lại những kiến thức hữu ích khi nghiên cứu về shellcode và lỗi tràn bộ đệm. Bạn có thể theo dõi các bài viết trước tại đây: Windows Shellcode và ứng dụng ...
Hôm nay tôi sẽ kết thúc loạt bài viết về chủ đề “Windows ShellCode và ứng dụng khai thác lỗi tràn bộ đệm”. Tôi hi vọng đã mang lại những kiến thức hữu ích khi nghiên cứu về shellcode và lỗi tràn bộ đệm.
Bạn có thể theo dõi các bài viết trước tại đây:
Windows Shellcode và ứng dụng khai thác lỗi tràn bộ đệm – Phần 1
Windows Shellcode và ứng dụng khai thác lỗi tràn bộ đệm – Phần 2
Windows Shellcode và ứng dụng khai thác lỗi tràn bộ đệm – Phần 3
Lấy địa chỉ hàm bên trong Kernel32.dll
Ta đã có địa chỉ của Kernel32.dll, bước tiếp theo ta phải xác định địa chỉ của các hàm cần tìm bên trong Kernel32.dll. Cơ chế dưới đây cho phép tìm kiếm địa chỉ hàm theo tên hàm trong bàng Export Directory Table.
Hình 6 : Tìm kiếm hàm trong thư viện
Trong cấu trúc của DLL PE luôn phải có bảng chứa thông tin về các hàm (symbols) xuất. Kỹ thuật sử dụng là truy nhập vào bảng chứa tên các hàm, so sánh tên từng hàm với hàm tên hàm muốn tìm. Từ đó xác định địa chỉ tuyệt đối của hàm.
Đoạn asm dưới đây cho phép tìm kiếm địa chỉ hàm “GetProcAddress()”
Như vậy, ta đã xác định được địa chỉ của hàm GetProcAddress(), địa chỉ cơ sở của Kernel32.dll. Dựa vào 2 thông tin trên, ta dễ dàng xác định địa chỉ hàm LoadLibrary() thông qua hàm GetProcAddress(). Như vậy, ta đã có đủ điều kiện để viết được một Shellcode không phụ thuộc vào phiên bản của hệ điều hành. Trong phần cuối là mã nguồn asm cho phép thực hiện gọi một MessageBoxA trong User32.dll bằng các phương pháp đã nêu.
Tối ưu độ dài của Shellcode
Với phương pháp tìm kiếm địa chỉ đã nêu trên, Shellcode đã có thể thực thi mà không phụ thuộc vào phiên bản của hệ điều hành. Nhưng nếu Shellcode sử dụng nhiều hàm API để thực hiện nhiệm vụ phức tạp thì bộ nhớ lưu trữ tên của các hàm sử dụng sẽ rất lớn. Để giảm kích thước của Shellcode ta sẽ phải giảm kích thước lưu trữ tên các hàm cần tìm. Điều này còn cho phép ta không cần sử dụng GetProcAddress() để lấy địa chỉ hàm.
Kỹ thuật được sử dụng là ta sẽ băm (hash) chuỗi tên hàm trong 4-byte bằng thuật toán sau trong C :
Đoạn asm sau sẽ minh họa việc tìm kiếm hàm LoadLibraryA trong Kernel32.dll bằng cách thông qua cấu trúc Export Directory Table, lấy lần lượt từng tên hàm trong bảng chứa tên hàm, băm (hash) cái tên đó rồi so khớp với 0xec0ee48e (LoadLibrary). Việc so khớp sẽ dừng lại nếu khớp kết quả băm, từ đó tìm ra địa chỉ hàm LoadLibrary.
Bên dưới là mã asm của chương trình gọi MessageBox đã cải tiến của version1 bằng các hàm băm, nên shellcode kết quả có kích thước cho nhỏ hơn.
Các shellcode phổ biến
MessageBox1
MessageBox2