Hướng dẫn viết shellcode

tmnt53

VIP Members
25/04/2015
98
132 bài viết
Hướng dẫn viết shellcode
Trong video khai thác BoF, chúng ta có dùng đến một con shellcode là binsh. Hôm nay mình sẽ hướng dẫn các bạn cách hoạt động của một con shellcode và cách viết nó.

Môi trường: Linux, viết shellcode 32bit.

Linh các file đính kèm (con shellcode binsh, file testShellcode.c) ở cuối bài viết.

Khi viết shellcode trên môi trường Linux, ta dùng đến các system call. Trên Windows thường không làm vậy, mà phải gọi tới các hàm trong thư viện dll, vì hệ thống system call qua các đời Windows bị thay đổi, mà không phải việc gì cũng làm được. Còn trên Linux thì ngược lại, ổn định, rõ ràng, hỗ trợ mọi việc từ ghi file tới mở kết nối socket.

System call là các lời gọi tới các xử lý ngắt, mà các xử lý này được thực hiện trong kernel. Khi ta gọi một hàm trên hệ thống 32bit, thì ta phải truyền tham số vào stack và thực hiện lệnh call. Nhưng khi thực hiện gọi một system call, ta sẽ truyền các tham số vào các thanh ghi, và thực hiện lệnh int 0x80.

Ví dụ một con shellcode đơn giản nhất, chỉ thực hiện công việc tương tự hàm exit, qua lời gọi system call sys_exit:

mov ebx, 0x3
mov eax, 1
int 0x80

Shellcode trên tương đương với lời gọi hàm exit(0x3). Trong Linux, hàm exit có system call tương ứng của nó, nhận 1 tham số. Tham số này được truyền qua thanh ghi ebx (mov ebx, 0x3). Còn system call exit có số hiệu 1, nên ta truyền eax bằng 1 (mov eax, 0x1). Cuối cùng gọi lệnh int 0x80 là xong.

Để biên dịch con shellcode trên, ta tạo một file exit.asm với nội dung:

1.PNG

Và ta dùng nasm để biên dịch: nasm exit.asm -o exit

Dòng BITS 32 nhằm chỉ cho nasm biết là ta cần biên dịch mã 32bit.

Để dump shellcode ra, ta dùng objdump:

objdump -D -b binary -mi386 -M intel fileName

2.PNG

Như hình trên ta thấy vùng bôi màu vàng chính là mã hex của shellcode sau khi được biên dịch.

Để chạy shellcode này, ta dùng một chương trình gọi chạy shellcode như sau:

3.PNG

Chương trình trên nhận tham số thứ nhất là file shellcode; đọc shellcode vào một string, và thực thi vùng shellcode ấy. Vì shellcode 32bit nên ta biên dịch cần tham số -m32. Còn -execstack là để cho phép thực thi dữ liệu, như vậy shellcode mới có quyền chạy (theo như kiến thức phần NX - https://whitehat.vn/threads/gioi-thieu-nx-va-aslr.8446/)

gcc testShellcode.c -o testShellcode32 -m32 -zexecstack

Ta gọi chạy fileshellcode exit, và in ra giá trị trả về:

4.PNG

Nhận thấy giá trị trả về là 3 => shellcode đã thực thi thành công!

Để tra số hiệu của các system call, có thể xem tại http://syscalls.kernelgrok.com/.

5.png

Ví dụ, sys_read có số hiệu 3. Hay để gọi sys_write, ta phải truyền eax = 0x4.

Trong bảng trên, các tham số cần truyền vào cho ebx, ecx,… không được chuẩn, ví dụ đối với sys_execve, các tham số thể hiện như trên là sai. Để biết phải truyền các tham số cho sys_execve như thế nào, ta sử dụng định nghĩa hàm:

  • Tra số hiệu được eax = 0xb
  • Thứ tự truyền các tham số lần lượt là ebx, ecx, edx, esi, edi
  • Xem định nghĩa hàm bằng man execve:

6.png

Vậy cần truyền ebx = filename, ecx = argv, edx = envp.

Con shellcode binsh chỉ đơn giản gọi đến hàm execve với các tham số như sau:
  • filename = “/bin//shx00x00x00x00”
  • argv = NULL
  • envp không xác định (không truyền gì vào cho edx)

7.PNG

Người ta truyền các tham số không tuân quy tắc như trên là để làm sao cho shellcode ngắn nhất có thể, và không có byte 0x00. Con shellcode binsh tạo ra chỉ dài 21 byte. Test chạy thử shellcode:

8.PNG

Tổng kết lại, ta có:
  • Shellcode thường được gọi lên các system call. Sử dụng system call table để tra danh sách system call.
  • Sử dụng nasm để viết shellcode.
  • Dùng testShellcode để kiểm tra shellcode có chạy hay không (debug bằng gdb nếu cần).
 
Chỉnh sửa lần cuối bởi người điều hành:
Nghe nguy hiểm quá ;)
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  • Thích
Reactions: tmnt53
Comment
Dang dinh viet 1 bai huong dan viet ve shellcode thi ban lam rui...... hehehe{6}{6}
 
Comment
Trong video khai thác BoF (https://whitehat.vn/threads/video-huong-dan-khai-thac-bof-co-ban.8391/), chúng ta có dùng đến một con shellcode là binsh. Hôm nay mình sẽ hướng dẫn các bạn cách hoạt động của một con shellcode và cách viết nó.

Môi trường: Linux, viết shellcode 32bit.

Linh các file đính kèm (con shellcode binsh, file testShellcode.c) ở cuối bài viết.

Khi viết shellcode trên môi trường Linux, ta dùng đến các system call. Trên Windows thường không làm vậy, mà phải gọi tới các hàm trong thư viện dll, vì hệ thống system call qua các đời Windows bị thay đổi, mà không phải việc gì cũng làm được. Còn trên Linux thì ngược lại, ổn định, rõ ràng, hỗ trợ mọi việc từ ghi file tới mở kết nối socket.

System call là các lời gọi tới các xử lý ngắt, mà các xử lý này được thực hiện trong kernel. Khi ta gọi một hàm trên hệ thống 32bit, thì ta phải truyền tham số vào stack và thực hiện lệnh call. Nhưng khi thực hiện gọi một system call, ta sẽ truyền các tham số vào các thanh ghi, và thực hiện lệnh int 0x80.

Ví dụ một con shellcode đơn giản nhất, chỉ thực hiện công việc tương tự hàm exit, qua lời gọi system call sys_exit:

mov ebx, 0x3
mov eax, 1
int 0x80

Shellcode trên tương đương với lời gọi hàm exit(0x3). Trong Linux, hàm exit có system call tương ứng của nó, nhận 1 tham số. Tham số này được truyền qua thanh ghi ebx (mov ebx, 0x3). Còn system call exit có số hiệu 1, nên ta truyền eax bằng 1 (mov eax, 0x1). Cuối cùng gọi lệnh int 0x80 là xong.

Để biên dịch con shellcode trên, ta tạo một file exit.asm với nội dung:

View attachment 1133

Và ta dùng nasm để biên dịch: nasm exit.asm -o exit

Dòng BITS 32 nhằm chỉ cho nasm biết là ta cần biên dịch mã 32bit.

Để dump shellcode ra, ta dùng objdump:

objdump -D -b binary -mi386 -M intel fileName

View attachment 1134

Như hình trên ta thấy vùng bôi màu vàng chính là mã hex của shellcode sau khi được biên dịch.

Để chạy shellcode này, ta dùng một chương trình gọi chạy shellcode như sau:

View attachment 1135

Chương trình trên nhận tham số thứ nhất là file shellcode; đọc shellcode vào một string, và thực thi vùng shellcode ấy. Vì shellcode 32bit nên ta biên dịch cần tham số -m32. Còn -execstack là để cho phép thực thi dữ liệu, như vậy shellcode mới có quyền chạy (theo như kiến thức phần NX - https://whitehat.vn/threads/gioi-thieu-nx-va-aslr.8446/)

gcc testShellcode.c -o testShellcode32 -m32 -zexecstack

Ta gọi chạy fileshellcode exit, và in ra giá trị trả về:

View attachment 1136

Nhận thấy giá trị trả về là 3 => shellcode đã thực thi thành công!

Để tra số hiệu của các system call, có thể xem tại http://syscalls.kernelgrok.com/.

View attachment 1137

Ví dụ, sys_read có số hiệu 3. Hay để gọi sys_write, ta phải truyền eax = 0x4.

Trong bảng trên, các tham số cần truyền vào cho ebx, ecx,… không được chuẩn, ví dụ đối với sys_execve, các tham số thể hiện như trên là sai. Để biết phải truyền các tham số cho sys_execve như thế nào, ta sử dụng định nghĩa hàm:

  • Tra số hiệu được eax = 0xb
  • Thứ tự truyền các tham số lần lượt là ebx, ecx, edx, esi, edi
  • Xem định nghĩa hàm bằng man execve:
View attachment 1138


Vậy cần truyền ebx = filename, ecx = argv, edx = envp.

Con shellcode binsh chỉ đơn giản gọi đến hàm execve với các tham số như sau:

  • filename = “/bin//shx00x00x00x00”
  • argv = NULL
  • envp không xác định (không truyền gì vào cho edx)

View attachment 1139

Người ta truyền các tham số không tuân quy tắc như trên là để làm sao cho shellcode ngắn nhất có thể, và không có byte 0x00. Con shellcode binsh tạo ra chỉ dài 21 byte. Test chạy thử shellcode:

View attachment 1140

Tổng kết lại, ta có:
  • Shellcode thường được gọi lên các system call. Sử dụng system call table để tra danh sách system call.
  • Sử dụng nasm để viết shellcode.
  • Dùng testShellcode để kiểm tra shellcode có chạy hay không (debug bằng gdb nếu cần).
objdump-png.1134

Anh ơi bức hình này dùng chương trình GNU Nano ạ??
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
objdump-png.1134

Anh ơi bức hình này dùng chương trình GNU Nano ạ??
Anh dùng objdump mà. Em để ý câu lệnh trong hình anh dùng là: "objdump -D -b binary -mi386 -M intel exit", dùng để dump ra code trong file shellcode exit.
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Anh dùng objdump mà. Em để ý câu lệnh trong hình anh dùng là: "objdump -D -b binary -mi386 -M intel exit", dùng để dump ra code trong file shellcode exit.
Ý em là phần mềm nào ý ạ .
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
ồ dạ , nó có thể cài trên window đc k anh , tại em cài máy ảo , mà mở thì nhiều lúc lag
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
  • Thích
Reactions: tmnt53
Comment
ồ dạ , nó có thể cài trên window đc k anh , tại em cài máy ảo , mà mở thì nhiều lúc lag
Trên Windows không có objdump, trên Windows đương nhiên có tool, nhưng em nên dùng Ubuntu/Kali, vì anh hướng dẫn các demo toàn trên Ubuntu mà.
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Chỗ con shell binsh thừa lệnh " mov edx,0x8 "
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Thẻ
shellcode
Bên trên