Hotline : 07 088 44444
Thích
Chia sẻ

Shellcode là gì? Hướng dẫn cách viết Shellcode

16/06/2021

Bạn biết tất cả về hashes trong an ninh mạng và cách decode Base64. Bạn có thể cũng quen thuộc với kỹ thuật in ẩn (steganography) và thậm chí có thể bạn có thể kể lại lịch sử của an ninh mạng và sự phát triển của EDR. Nhưng làm thế nào để giải thích việc sử dụng shellcode độc ​​hại? Bạn biết rằng nó không liên quan gì đến các shell script hoặc các ngôn ngữ shell scripting như Bash. Nhưng bạn có thể tự nói về shellcode thực sự là gì và tại sao nó lại là một công cụ tuyệt vời cho những hacker?

Shellcode là gì?

Chúng ta biết shellcode không liên quan gì đến shell script, vậy tại sao lại có tên như vậy? Thuật ngữ “shellcode” trước đây được sử dụng để mô tả code được thực thi bởi một target program do khai thác lỗ hổng bảo mật và được sử dụng để mở một shell từ xa. Tức là một phiên bản của command line interpreter. Mục đích để hacker có thể sử dụng shell đó để tiếp tục tương tác với hệ thống của nạn nhân. Thường chỉ mất một vài dòng code để tạo ra một shell process mới, vì vậy popping shell là một phương tiện tấn công rất nhẹ và hiệu quả, miễn là chúng ta có thể cung cấp đầu vào phù hợp cho một target program.

shellcode

Standard C code như trên sẽ bật ra một shell. Bạn có thể biên dịch và chạy nó trong một editor như Geany. Có thể biến các chương trình nhỏ như chương trình ở trên thành các chuỗi đầu vào có thể được cung cấp cho một chương trình dễ bị tấn công để đạt được hiệu quả tương tự. Phần thưởng cho những kẻ tấn công là nếu chương trình mục tiêu của bạn đang chạy với các đặc quyền nâng cao, thì shell mới được tạo ra của bạn cũng sẽ thừa hưởng các đặc quyền đó.

Tạo một chuỗi shellcode từ code như trên yêu cầu sử dụng disassembler để tiết lộ lắp ráp “bên dưới” C. Chúng ta có thể làm điều đó trong bất kỳ disassembler nào như IDA, Ghidra, OllyDbg, Radare2 hoặc otool trên macOS. Đây là chương trình trong disassembler:

shell-code-la-gi

Các mã opcode mà chúng ta cần để tạo shellcode của mình được tô màu đỏ. Ở bên phải của chúng là các hướng dẫn tương tự bằng ngôn ngữ hợp ngữ cho chúng ta dễ đọc hơn.

Sau khi có mã opcodes, chúng ta cần đặt mã này vào một format có thể được sử dụng làm string input cho một chương trình khác. Điều này liên quan đến việc nối các mã opcodes thành một chuỗi và viết trước mỗi hex byte với \ x để tạo ra một chuỗi có format sau:

\ x55 \ x48 \ x89 \ xe5 \ x48 \ x83 \ xec \ x30 \ x31 \ xc0 \ x89 \ xc2 \ x48 \ x8d \ x75 \ xe0 \ x48 \ x8b \ x3b \ x0d \ xe9 \ x…

Cách tạo Shellcode

Các lệnh shellcode không được phép chứa các số 0, vì bất kỳ ký tự 0 nào trong chuỗi đầu vào sẽ được chương trình target hiểu là ký tự null-terminator. Do đó, phần còn lại của shellcode sẽ bị loại bỏ. Chương trình ở trên có rất nhiều byte rỗng.

Để giải quyết vấn đề này và để tạo shellcode có định dạng tốt, chúng ta cần thay thế bất kỳ lệnh nào chứa null byte bằng các lệnh khác. Làm như vậy sẽ dễ dàng hơn nhiều nếu chúng ta viết code trực tiếp bằng một ngôn ngữ hợp ngữ như NASM thay vì bắt đầu bằng một ngôn ngữ như C và giải nén hợp ngữ. Hãy xem một ví dụ khác được thiết kế đặc biệt để tránh vấn đề null-byte. Dưới đây là cách tháo gỡ (disassembly) cho một vấn đề tương tự cũng bật ra một shell bằng cách sử dụng execute (), nhưng hợp ngữ nhỏ hơn và hiệu quả hơn nhiều so với trước đây.

cách tạo shellcode

Lưu ý ở dòng 8, số thập lục phân 48 31 f6, đại diện cho các lệnh cho tổ hợp sau:

xor %ris, %rsi

Việc sử dụng XOR ở đây là một ví dụ về việc bỏ qua hạn chế của việc không thể sử dụng các số 0 mà Vietnix đã đề cập ở trên. Chương trình này cần đẩy số nguyên 0 lên stack. Để làm như vậy, trước tiên nó tải 0 vào CPU’s %rsi register. Cách làm như sau:

move $0x0, %rsi

Nhưng nếu chúng ta nhập dữ liệu đó vào một disassembler trực tuyến, sẽ tạo ra raw hex với các số 0 trong instruction operand.

4889342500000000

Chúng ta có thể giải quyết vấn đề đó bằng cách làm xo giá trị của %rsi với chính nó. Khi cả hai giá trị đầu vào của XOR đều giống nhau, kết quả sẽ là 0. Nhưng lệnh không yêu cầu bất kỳ số 0 nào trong raw hex.

Bây giờ chúng ta có thể tạo một chuỗi shellcode được định dạng tốt chứa chương trình hoàn chỉnh:

\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05

Hãy tạo một chương trình thực thi shellcode để xem nó hoạt động:

cách hoạt động của shellcode

Tìm các chương trình có lỗ hổng

Và bây giờ chúng ta đã có một số shellcode và khái niệm. Nhưng việc tìm kiếm các chương trình dễ bị tấn công mà chúng ta có thể cung cấp shellcode không phải là một vấn đề đơn giản. Có một cách là thông qua thiết kế ngược một chương trình, làm mờ và thử nghiệm với hy vọng tìm ra một target program xử lý sai các edge case của input data. Trong các trường hợp code chương trình xử lý sai một số dạng input không mong muốn. Điều này đôi khi có thể được sử dụng để thay đổi luồng thực thi chương trình và làm cho nó gặp sự cố hoặc cho phép chúng ta chạy các lệnh của chính mình do shellcode cung cấp. Một lỗi lập trình phổ biến thường có thể được sử dụng để đạt được điều này là lỗi tràn bộ đệm (buffer overflow).

Tràn bộ đệm là gì?

Tràn bộ đệm xảy ra khi chương trình ghi data vào bộ nhớ lớn hơn diện tích của bộ nhớ, bộ đệm, chương trình dành riêng cho nó. Do đó ghi đè lên một số data chương trình không liên quan. Đây là lỗi lập trình, vì trước tiên code phải luôn kiểm tra xem độ dài của data đầu vào bất kì không được phép vượt quá kích thước của bộ đệm đã được cấp phát. Khi điều này xảy ra, chương trình có thể bị lỗi, nhưng đầu vào được tạo ra đặc biệt như shellcode thay vào đó có thể cho phép hacker thực thi code của riêng chúng. Dưới đây là một ví dụ đơn giản về lỗi tràn bộ đệm:

lỗi tràn bộ đệm

Chương trình dự trữ 16 bytes bộ nhớ cho đầu vào, nhưng kích thước của đầu vào không bao giờ được kiểm tra. Nếu user nhập một chuỗi dài hơn 16 bytes, dữ liệu sẽ ghi đè lên bộ nhớ liền kề (adjacent memory). Lỗi tràn bộ đệm xảy ra. Hình ảnh bên dưới cho thấy điều gì sẽ xảy ra nếu bạn cố gắng thực thi chương trình trên và cung cấp cho nó đầu vào lớn hơn 16 bytes:

lỗi buffer onverflow

Tuy nhiên, hacker không sử dụng nhiều cách này. Trừ khi tất cả những gì chúng muốn là đưa chương trình đến trạng thái ngừng hoạt động. Trong hầu hết các trường hợp không chỉ là gây ra buffer overflow mà còn sử dụng nó như một phương tiện để kiểm soát việc thực thi.

Dụng cụ Shellcode và Exploitation

Việc viết shellcode là một công việc đòi hỏi một số kỹ năng nhất định. Do đó, những hacker luôn có sẵn nhiều công cụ để giúp chúng. Có các post exploitation kits có sẵn như Metasploit và PowerSploit cung cấp những thứ như bộ mã hóa (encoder) để giúp tạo compliant shellcode, các công cụ để tạo tải trọng (payloads) và các chức năng có thể đưa trực tiếp shellcode vào các quy trình.

dụng cụ của Shellcode

Trên Linux và macOS, ngay cả một bash post-exploit kit đơn giản như Bashark cũng sẽ cung cấp một chức năng để thực thi shellcode.

Bashark

Bạn có thể dễ dàng tìm thấy các ví dụ về shellcode được tạo sẵn trên internet, bao gồm cả trong các tài nguyên dành cho các penetration tester và những red teamer như Exploit Database. Mặc dù các cuộc tấn công thực tế thường sẽ yêu cầu một số mức độ tùy chỉnh để đảm bảo shellcode phù hợp với target program, môi trường thực thi và mục tiêu của hacker.

Để tránh bị hacker tấn công và đánh cắp dữ liệu cá nhân, bạn không nên để tràn bộ đệm dữ liệu (buffer overflow) trong khi viết code, cân nhắc và xem xét kỹ lưỡng trước khi gán biến và khai báo giá trị cho code. Vietnix hy vọng bạn nắm rõ được khái niệm Shellcode cũng như cách bảo mật tốt hơn cho mọi dữ liệu cá nhân của bạn. Vietnix xin cảm ơn vì bạn đã dành thời gian để đọc bài viết này.

Nếu bạn có thắc mắc hay có vấn đề cần hỗ trợ, bạn có thể liên hệ trực tiếp với Vietnix thông qua các kênh sau:
  • Hotline: 1800 1093 - 07 088 44444
  • Email: support@vietnix.vn
  • Hoặc chat trực tiếp với Vietnix thông qua biểu tượng Livechat ở góc phải màn hình. Đội ngũ chuyên viên của chúng tôi luôn sẵn sàng tư vấn và hỗ trợ bạn 24/7.
Vietnix hiện đang có chương trình khuyến mãi lớn nhất trong năm, giảm giá TRỌN ĐỜI: Đăng ký dùng thử ngay và Vietnix sẽ hoàn tiền 100% nếu quý khách không hài lòng với chất lượng sản phẩm, dịch vụ!
Mình là Bo - admin của Quản Trị Linux. Mình đã có 10 năm làm việc trong mảng System, Network, Security và đã trải nghiệm qua các chứng chỉ như CCNP, CISSP, CISA, đặc biệt là chống tấn công DDoS. Gần đây mình trải nghiệm thêm Digital Marketing và đã hòan thành chứng chỉ CDMP của PersonVUE. Mình rất thích được chia sẻ và hỗ trợ cho mọi người, nhất là các bạn sinh viên. Hãy kết nối với mình nhé!
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments