Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách khai thác lỗi Command Injection thông qua phòng OsCommandInjection trên TryHackMe.
Cách khai thác lỗi Command Injection
Command Injection là hành vi lạm dụng của một ứng dụng để thực thi các lệnh trên hệ điều hành bằng cách sử dụng các đặc quyền giống như chương trình đang thực thi trên thiết bị.
- Command Injection vẫn là một trong mười lỗ hổng hàng đầu trong OWASP.
Nó còn được gọi là “Remote Code Execution” (RCE) vì kẻ tấn công có thể đánh lừa ứng dụng thực thi một chuỗi payload do kẻ tấn công cung cấp mà không cần quyền truy cập trực tiếp vào chính hệ thống (tức là một shell tương tác).
Máy chủ web sẽ tiếp tục xử lý và thực thi mã dưới “đặc quyền” và “kiểm soát truy cập” của người đang chạy ứng dụng.
- Hơn nữa, do khả năng thực thi mã từ xa trong ứng dụng, những lỗ hổng này thường được kẻ tấn công săn tìm nhiều nhất vì chúng cho phép kẻ tấn công chủ động giao tiếp với hệ thống dễ bị tấn công, cho phép kẻ tấn công đọc các tệp, dữ liệu của hệ thống hoặc những thứ tương tự khác.
lệnh: whoami – Nó sẽ liệt kê tài khoản của nạn nhân mà ứng dụng đang hoạt động như một ví dụ về command injection.
[Question 1.1] Read me!
Answer: Không cần trả lời.
Lỗ hổng này tồn tại do các ứng dụng thường xuyên sử dụng các hàm trong ngôn ngữ lập trình như PHP, Python và NodeJS để truyền dữ liệu và thực hiện các lệnh gọi hệ thống trên hệ điều hành của máy.
Ví dụ: Lấy đầu vào từ một trường và tìm kiếm mục nhập trong tệp.
Ví dụ về các hàm này:
- Loại dữ liệu này thường được lưu trong cơ sở dữ liệu và đó là nơi ứng dụng thu thập thông tin đầu vào của người dùng để tương tác với hệ điều hành của ứng dụng.
1) Ứng dụng lưu trữ các tệp MP3 trong một thư mục có trên hệ điều hành.
2) Người dùng nhập tên bài hát mà họ muốn tìm kiếm. Ứng dụng lưu dữ liệu đầu vào này vào biến $title.
3) Dữ liệu trong biến $title này được chuyển tới lệnh grep để tìm kiếm tệp văn bản có tên songtitle.txt để nhập bất kỳ thứ gì người dùng muốn tìm kiếm.
4) Kết quả tìm kiếm của songtitle.txt sẽ xác định liệu ứng dụng có thông báo cho người dùng rằng bài hát tồn tại hay không.
Kẻ tấn công có thể lợi dụng chương trình này bằng cách đưa ra các lệnh của riêng chúng để nó thực thi. Thay vì sử dụng grep để tìm kiếm mục nhập trong songtitle.txt, kẻ tấn công có thể yêu cầu ứng dụng đọc dữ liệu từ một tệp nhạy cảm hơn.
1) Gói “flask” được sử dụng để thiết lập máy chủ web
2) Một hàm sử dụng gói “subprocess” để thực hiện một lệnh trên thiết bị
3) Máy chủ web sẽ thực thi bất cứ lệnh gì được cung cấp. Ví dụ: để thực thi whoami, mình chỉ cần truy cập http: //flaskapp.thm/whoami
[Câu hỏi 2.1] Biến nào lưu dữ liệu đầu vào của người dùng trong đoạn mã PHP trên?
Trả lời: title
[Câu hỏi 2.2] Phương thức HTTP nào được sử dụng để truy xuất dữ liệu do người dùng gửi trong đoạn mã PHP?
Answer: GET
[Câu hỏi 2.3] Nếu tôi muốn thực thi lệnh id trong đoạn mã Python, tôi cần truy cập route nào?
Answer: /id
Các ứng dụng sử dụng đầu vào từ người dùng để cung cấp dữ liệu cho hệ thống thường có thể dẫn đến những hành vi không mong muốn.
Người vận hành Shell:
1) ; = chức năng tương tự như “&&”, ở chỗ nó không yêu cầu lệnh đầu tiên được thực hiện thành công, có nghĩa là nếu lệnh đầu tiên bị lỗi, lệnh thứ hai vẫn sẽ chạy.
2) & = Bởi vì nó là một toán tử nền, nên lệnh sẽ tiếp tục chạy và bạn sẽ có thể thực hiện các tác vụ khác (có nghĩa là có thể chạy đồng thời với lệnh đầu tiên)
3) && = Tượng trưng cho “and”, nó sẽ thực hiện lệnh thứ hai sau khi lệnh đầu tiên được hoàn thành thành công, lưu ý là lệnh đầu tiên PHẢI THÀNH CÔNG để chạy lệnh thứ hai.
Trong hầu hết các trường hợp, Command Injection có thể được phát hiện theo một trong hai cách:
- Blind Command Injection – Khi kiểm tra payload, không có đầu ra trực tiếp từ ứng dụng và phải phân tích hành vi của ứng dụng để khám phá xem payload của bạn có thành công hay không.
- Verbose Command Injection – Sau khi bạn đã kiểm tra payload, kẻ tấn công sẽ nhận được phản hồi ngay lập tức từ chương trình. Ví dụ: bạn có thể sử dụng lệnh “whoami” để xem ứng dụng đang chạy với tư cách người dùng nào và tên người dùng sẽ được hiển thị trực tiếp trên trang.
Phát hiện Blind Command Injection:
- Cách này phải sử dụng payload, nên hơi mất thời gian.
- Nếu có thể, hãy buộc một số đầu ra.
1) ping = Ứng dụng sẽ treo trong x giây, tùy thuộc vào số lượng ping bạn chỉ định.
2) > = Đó là “redirector”, có nghĩa là chúng ta có thể lấy đầu ra của một lệnh (chẳng hạn như “cat” để xuất ra một tệp) và chuyển hướng nó đến một nơi khác. Sau khi được chuyển hướng, chúng ta có thể sử dụng “cat” để đọc nội dung của tệp mới được tạo.
3) whoami = In tên người dùng tương ứng với id người dùng hiện tại.
4) curl = Đây là một cách tiếp cận tuyệt vời để kiểm tra vì nó gửi và nhận dữ liệu từ một ứng dụng trong payload của bạn.
Phát hiện Verbose Command Injection:
- Một trong những phương pháp đơn giản nhất là cho ứng dụng cung cấp phản hồi hoặc đầu ra về những gì đang xảy ra hoặc đang được chạy.
ping hoặc whoami được hiển thị trực tiếp trên ứng dụng web
Payload hữu ích:
- Linux
- Windows
[Câu hỏi 3.1] Tôi sẽ sử dụng payload nào nếu tôi muốn xác định người dùng mà ứng dụng đang chạy với tư cách gì?
Answer: whoami
[Câu hỏi 3.2] Tôi sẽ sử dụng công cụ mạng phổ biến nào để kiểm tra khả năng blind command injection trên máy Linux?
Answer: ping
[Câu hỏi 3.3] Tôi sẽ sử dụng payload nào để kiểm tra máy Windows để đưa blind command injection vào?
Answer: timeout
Chúng ta có thể tránh được lỗ hổng này bằng một số phương pháp, từ việc sử dụng các hàm hoặc thư viện có khả năng gây hại trong ngôn ngữ lập trình đến lọc đầu vào mà không dựa vào đầu vào của người dùng.
Các hàm dễ bị tấn công:
• Exec
• Passthru
• System
Trong ví dụ dưới đây, chương trình sẽ chỉ chấp nhận và xử lý các số được nhập vào biểu mẫu.
- Điều này có nghĩa là các lệnh như “whoami” sẽ không được thực hiện.
1. Ứng dụng sẽ chỉ chấp nhận một mẫu ký tự cụ thể (các chữ số 0-9)
2. Ứng dụng sau đó sẽ chỉ tiến hành thực thi dữ liệu này, tất cả đều là số.
Cần lưu ý rằng bất kỳ chương trình nào sử dụng các hàm này mà không thực hiện kiểm tra đầy đủ sẽ dễ bị command injection.
Lọc đầu vào:
- Đây là một trong những phương pháp hiệu quả nhất để phòng tránh command injection; nó là một quá trình điều chỉnh các định dạng hoặc kiểu dữ liệu mà người dùng nhập, bằng cách hạn chế ký tự đầu vào mà bất kỳ ai cũng được phép nhập.
Ví dụ:
1) Chỉ chấp nhận dữ liệu số
2) Loại bỏ bất kỳ ký tự đặc biệt nào như >, &, và /.
Ảnh sau đây minh họa cách sử dụng hàm PHP “filter_input” để xác định xem dữ liệu được cung cấp qua biểu mẫu đầu vào có phải là số hay không.
Không sử dụng bộ lọc:
Các bộ lọc này sẽ giới hạn bạn ở các payload được chỉ định; tuy nhiên, chúng ta có thể không dùng các bộ lọc này bằng cách khai thác logic của ứng dụng.
- Ví dụ, một chương trình có thể loại bỏ dấu ngoặc kép ; bằng cách sử dụng giá trị thập lục phân.
Ví dụ dưới đây chứng minh rằng, ngay cả khi dữ liệu được cung cấp ở định dạng khác với dự kiến, nó vẫn có thể được xử lý và tạo ra cùng một kết quả.
[Câu hỏi 4.1] Thuật ngữ chỉ quá trình “làm sạch” đầu vào của người dùng được cung cấp cho một ứng dụng là gì?
Answer: sanitisation
Sử dụng “127.0.0.1” để thử nghiệm localhost.
Với thử nghiệm “localhost”, chúng ta đã phát hiện ra một số thứ.
“& Dir” đã hoạt động, cho thấy rằng nạn nhân đang sử dụng “Windows” chứ không phải Linux.
Command Injection Cheatsheet:
– https://github.com/payloadbox/command-injection-payload-list
[Câu hỏi 5.1] Ứng dụng này đang chạy với tư cách người dùng nào?
Vì chúng ta biết nạn nhân đang sử dụng “Windows”, chúng ta có thể sử dụng toán tử shell “&” để tìm hiểu ứng dụng nào đang chạy.
Answer: www-data
[Câu hỏi 5.2] Nội dung của flag trong /home/tryhackme/flag.txt là gì?
Bởi vì toán tử “&” là hàm dễ bị tấn công và cho phép chúng ta điều hướng thư mục, và vì chúng tacó thể truy cập “dir”, nên chúng ta chỉ cần di chuyển đến flag.
Cuối cùng, để đọc tệp, chúng ta phải sử dụng “cat”, do đó thay vì “dir”, chúng ta sẽ sử dụng “cat”.
Answer: THM{COMMAND_INJECTION_COMPLETE}
Vậy là bạn đã biết được lỗi hổng này nguy hiểm như thế nào rồi đó.