Rate this post

Xin chào các bạn! Hôm nay, chúng ta sẽ cùng nhau khám phá một khái niệm quan trọng nhưng có thể nhiều bạn chưa biết đến trong an ninh mạng: Command Injection. Đây là một chủ đề không chỉ thú vị mà còn rất cần thiết cho bất kỳ ai quan tâm đến việc bảo vệ thông tin cá nhân và doanh nghiệp. Hãy cùng nhau tìm hiểu, bạn nhé!

Đầu tiên, bạn cần biết rằng Command Injection không phải là một trò ma thuật; nó là một loại tấn công mà ở đó, hacker có thể ‘chèn’ và thực thi các lệnh tùy ý trên máy chủ của bạn. Nghe có vẻ đáng sợ, phải không nào? Điều này xảy ra khi một ứng dụng không đủ an toàn trong việc xử lý dữ liệu đầu vào, cho phép các mã độc hại được thực thi. Tưởng tượng một tình huống: bạn nhập dữ liệu vào một biểu mẫu trên web, và thay vì xử lý thông tin đó, hệ thống lại chạy một lệnh trên máy chủ. Đó chính là Command Injection!

Bây giờ, bạn có thể tự hỏi, tại sao lại quan trọng khi hiểu về Command Injection? Câu trả lời nằm ở tầm ảnh hưởng của nó. Command Injection không chỉ gây hại cho hệ thống mà còn đe dọa đến thông tin cá nhân và doanh nghiệp. Nó có thể dẫn đến việc đánh cắp dữ liệu, phá hủy cơ sở dữ liệu, hoặc thậm chí làm cho hệ thống dễ bị tấn công từ bên ngoài. Và không chỉ giới hạn trong các ứng dụng web, Command Injection còn có thể xuất hiện trong nhiều loại ứng dụng khác, từ doanh nghiệp lớn đến các hệ thống IoT.

Đó là lý do tại sao việc hiểu biết về cách thức hoạt động và cách phòng chống Command Injection là cực kỳ quan trọng. Chúng ta cần phải biết cách kiểm soát đầu vào dữ liệu, tuân theo các nguyên tắc lập trình an toàn, và sử dụng các công cụ phát hiện và ngăn chặn tấn công hiệu quả. Đồng thời, việc nâng cao nhận thức và đào tạo cho cả lập trình viên và quản trị viên hệ thống cũng rất cần thiết.

Vậy là bạn đã có một cái nhìn tổng quan về Command Injection và tại sao nó lại quan trọng trong an ninh mạng. Hãy cùng nhau chia sẻ thông tin này để mọi người có thể bảo vệ mình trước những mối đe dọa tiềm ẩn trong thế giới số! Hãy tiếp tục theo dõi blog để cập nhật thêm nhiều thông tin hữu ích khác nhé!

Command injection attack là gì?

Command injection là một cuộc tấn công trong đó mục tiêu là thực hiện các lệnh tùy ý trên hệ điều hành chủ thông qua một ứng dụng dễ bị tấn công. Các cuộc tấn công chèn lệnh có thể xảy ra khi một ứng dụng chuyển dữ liệu không an toàn do người dùng cung cấp (biểu mẫu, cookie, tiêu đề HTTP, v.v.) đến trình bao hệ thống. Trong cuộc tấn công này, các lệnh hệ điều hành do kẻ tấn công cung cấp thường được thực thi với các đặc quyền của ứng dụng dễ bị tấn công. Các cuộc tấn công chèn lệnh có thể xảy ra phần lớn do không đủ xác thực đầu vào.

Cuộc tấn công này khác với Code Injection, trong đó việc tiêm mã cho phép kẻ tấn công thêm mã của riêng chúng, sau đó được ứng dụng thực thi. Trong Command Injection, kẻ tấn công mở rộng chức năng mặc định của ứng dụng, thực thi các lệnh hệ thống mà không cần phải chèn mã.

Ví dụ 1

Đoạn mã sau là một trình bao bọc xung quanh lệnh cat UNIX để in nội dung của tệp ra đầu ra tiêu chuẩn. Nó cũng có thể tiêm:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {
 char cat[] = "cat ";
 char *command;
 size_t commandLength;

 commandLength = strlen(cat) + strlen(argv[1]) + 1;
 command = (char *) malloc(commandLength);
 strncpy(command, cat, commandLength);
 strncat(command, argv[1], (commandLength - strlen(cat)) );

 system(command);
 return (0);
}

Được sử dụng bình thường, đầu ra chỉ đơn giản là nội dung của tệp được yêu cầu:

$ ./catWrapper Story.txt

Tuy nhiên, nếu chúng ta thêm dấu chấm phẩy và một lệnh khác vào cuối dòng này, lệnh sẽ được thực thi bởi catWrapper mà không có gì phải phàn nàn:

$ ./catWrapper "Story.txt; ls"
$ ./catWrapper "Story.txt; ls"
When last we left our heroes...
Story.txt               doubFree.c              nullpointer.c
unstosig.c              www*                    a.out*
format.c                strlen.c                useFree*
catWrapper*             misnull.c               strlength.c             useFree.c
commandinjection.c      nodefault.c             trunc.c                 writeWhatWhere.c

Nếu catWrapper đã được đặt để có mức đặc quyền cao hơn người dùng tiêu chuẩn, các lệnh tùy ý có thể được thực hiện với đặc quyền cao hơn đó.

Ví dụ 2

Chương trình đơn giản sau đây chấp nhận tên tệp làm đối số dòng lệnh và hiển thị nội dung của tệp trở lại người dùng. Chương trình được cài đặt setuid root vì nó được thiết kế để sử dụng như một công cụ học tập cho phép quản trị viên hệ thống đang được đào tạo kiểm tra các tệp hệ thống đặc quyền mà không cho họ khả năng sửa đổi hoặc làm hỏng hệ thống.

int main(char* argc, char** argv) {
 char cmd[CMD_MAX] = "/usr/bin/cat ";
 strcat(cmd, argv[1]);
 system(cmd);
}

Bởi vì chương trình chạy với đặc quyền root, cuộc gọi đến system () cũng thực thi với đặc quyền root. Nếu người dùng chỉ định một tên tệp tiêu chuẩn, thì lệnh gọi sẽ hoạt động như mong đợi. Tuy nhiên, nếu kẻ tấn công chuyển một chuỗi có dạng “; rm -rf /”, thì lệnh gọi đến system () không thể thực thi cat do thiếu đối số và sau đó tiếp tục xóa đệ quy nội dung của phân vùng gốc.

Ví dụ 3

Đoạn mã sau từ một chương trình đặc quyền sử dụng biến môi trường $ APPHOME để xác định thư mục cài đặt của ứng dụng, sau đó thực thi một tập lệnh khởi tạo trong thư mục đó.

...
char* home=getenv("APPHOME");
char* cmd=(char*)malloc(strlen(home)+strlen(INITCMD));
if (cmd) {
 strcpy(cmd,home);
 strcat(cmd,INITCMD);
 execl(cmd, NULL);
}
...

Như trong Ví dụ 2, mã trong ví dụ này cho phép kẻ tấn công thực hiện các lệnh tùy ý với đặc quyền nâng cao của ứng dụng. Trong ví dụ này, kẻ tấn công có thể sửa đổi biến môi trường $ APPHOME để chỉ định một đường dẫn khác chứa phiên bản độc hại của INITCMD. Bởi vì chương trình không xác nhận giá trị đọc từ môi trường, bằng cách kiểm soát biến môi trường, kẻ tấn công có thể đánh lừa ứng dụng chạy mã độc.

Kẻ tấn công đang sử dụng biến môi trường để điều khiển lệnh mà chương trình gọi ra, vì vậy ảnh hưởng của môi trường là rõ ràng trong ví dụ này. Bây giờ chúng ta sẽ chuyển sự chú ý của mình đến những gì có thể xảy ra khi kẻ tấn công thay đổi cách diễn giải lệnh.

Ví dụ 4

Đoạn mã dưới đây là từ một tiện ích CGI dựa trên web cho phép người dùng thay đổi mật khẩu của họ. Quá trình cập nhật mật khẩu theo NIS bao gồm chạy lệnh thực hiện trong thư mục / var / yp. Lưu ý rằng kể từ khi chương trình cập nhật các bản ghi mật khẩu, nó đã được cài đặt gốc setuid.

Chương trình gọi make như sau:

system("cd /var/yp && make &> /dev/null");

Không giống như các ví dụ trước, lệnh trong ví dụ này được mã hóa cứng, vì vậy kẻ tấn công không thể kiểm soát đối số được truyền đến system (). Tuy nhiên, vì chương trình không chỉ định một đường dẫn tuyệt đối cho make và không xóa bất kỳ biến môi trường nào trước khi gọi lệnh, kẻ tấn công có thể sửa đổi biến $ PATH của chúng để trỏ đến một tệp nhị phân độc hại có tên là make và thực thi tập lệnh CGI từ một dấu nhắc shell. Và vì chương trình đã được cài đặt gốc setuid, phiên bản make của kẻ tấn công hiện chạy với đặc quyền root.

Môi trường đóng một vai trò quan trọng trong việc thực hiện các lệnh hệ thống trong các chương trình. Các hàm như system () và execute () sử dụng môi trường của chương trình gọi chúng, và do đó những kẻ tấn công có cơ hội tiềm ẩn để ảnh hưởng đến hành vi của các lệnh gọi này.

Có nhiều trang web sẽ cho bạn biết rằng Java’s Runtime.exec hoàn toàn giống với chức năng hệ thống của C. Đây không phải là sự thật. Cả hai đều cho phép bạn gọi một chương trình / quy trình mới. Tuy nhiên, hàm hệ thống của C chuyển các đối số của nó tới shell (/ bin / sh) để được phân tích cú pháp, trong khi Runtime.exec cố gắng chia chuỗi thành một mảng các từ, sau đó thực thi từ đầu tiên trong mảng với các từ còn lại. dưới dạng các tham số. Runtime.exec KHÔNG cố gắng gọi trình bao tại bất kỳ thời điểm nào. Sự khác biệt chính là

phần lớn chức năng được cung cấp bởi shell có thể được sử dụng cho những trò nghịch ngợm (chuỗi các lệnh sử dụng “&”, “&&”, “|”, “||”, v.v., chuyển hướng đầu vào và đầu ra) sẽ chỉ đơn giản là một tham số được chuyển đến lệnh đầu tiên và có thể gây ra lỗi cú pháp hoặc bị loại bỏ dưới dạng tham số không hợp lệ.

Ví dụ 5

Các đoạn mã nhỏ sau đây dễ bị chèn lệnh OS trên nền tảng Unix / Linux:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
     char command[256];

     if(argc != 2) {
          printf("Error: Please enter a program to time!\n");
          return -1;
     }

     memset(&command, 0, sizeof(command));

     strcat(command, "time ./");
     strcat(command, argv[1]);

     system(command);
     return 0;
}

Nếu đây là một nhị phân suid, hãy xem xét trường hợp khi kẻ tấn công nhập vào như sau: ls; con mèo / etc / shadow. Trong môi trường Unix, các lệnh shell được phân tách bằng dấu chấm phẩy. Bây giờ chúng ta có thể thực hiện các lệnh hệ thống theo ý muốn!

Java:

Có nhiều trang web sẽ cho bạn biết rằng Java’s Runtime.exec hoàn toàn giống với chức năng hệ thống của C. Đây không phải là sự thật. Cả hai đều cho phép bạn gọi một chương trình / quy trình mới. Tuy nhiên, hàm hệ thống của C chuyển các đối số của nó tới shell (/ bin / sh) để được phân tích cú pháp, trong khi Runtime.exec cố gắng chia chuỗi thành một mảng các từ, sau đó thực thi từ đầu tiên trong mảng với các từ còn lại. dưới dạng các tham số. Runtime.exec KHÔNG cố gắng gọi trình bao tại bất kỳ thời điểm nào. Sự khác biệt chính là phần lớn các chức năng được cung cấp bởi shell có thể được sử dụng cho mục đích nghịch ngợm (chuỗi các lệnh sử dụng &, &&, |, ||, v.v., chuyển hướng đầu vào và đầu ra) sẽ chỉ đơn giản là một tham số được chuyển đến lệnh đầu tiên và có thể gây ra lỗi cú pháp hoặc bị loại bỏ dưới dạng tham số không hợp lệ.

Ví dụ 6

Đoạn mã PHP sau dễ bị tấn công chèn lệnh:

<?php print("Please specify the name of the file to delete"); print("<p>"); $file=$_GET['filename']; system("rm $file"); ?>

Yêu cầu và phản hồi sau đây là một ví dụ về một cuộc tấn công thành công:

Yêu cầu http://127.0.0.1/delete.php?filename=bob.txt;id

Please specify the name of the file to delete

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Cách kiểm tra lỗ hổng Command Injection

Bài viết này mô tả cách kiểm tra ứng dụng để đưa lệnh vào hệ điều hành. Người kiểm tra sẽ cố gắng đưa một lệnh hệ điều hành thông qua một yêu cầu HTTP vào ứng dụng.

Các bài viết liên quan:

Chèn lệnh hệ điều hành là một kỹ thuật được sử dụng thông qua giao diện web để thực hiện các lệnh hệ điều hành trên máy chủ web. Người dùng cung cấp các lệnh của hệ điều hành thông qua giao diện web để thực hiện các lệnh của hệ điều hành. Bất kỳ giao diện web nào không được làm sạch đúng cách đều có thể bị khai thác này. Với khả năng thực thi các lệnh hệ điều hành, người dùng có thể tải lên các chương trình độc hại hoặc thậm chí lấy mật khẩu. Việc đưa lệnh vào hệ điều hành có thể ngăn ngừa được khi tính bảo mật được nhấn mạnh trong quá trình thiết kế và phát triển các ứng dụng.

Mục tiêu kiểm tra

Xác định và đánh giá các điểm tiêm lệnh.

Làm thế nào để kiểm tra

Khi xem một tệp trong ứng dụng web, tên tệp thường được hiển thị trong URL. Perl cho phép chuyển dữ liệu từ một quy trình vào một câu lệnh mở. Người dùng có thể chỉ cần thêm ký hiệu Pipe | vào cuối tên tệp.

URL mẫu trước khi thay đổi:

http: //sensitive/cgi-bin/userData.pl? doc = user1.txt

URL mẫu đã được sửa đổi:

http: //sensitive/cgi-bin/userData.pl? doc = / bin / ls |

Thao tác này sẽ thực hiện lệnh / bin / ls.

Thêm dấu chấm phẩy vào cuối URL cho trang .PHP, theo sau là lệnh của hệ điều hành, sẽ thực thi lệnh. % 3B là URL được mã hóa và giải mã thành dấu chấm phẩy

Ví dụ:

http: //sensitive/something.php? dir =% 3Bcat% 20 / etc / passwd

Ví dụ

Hãy xem xét trường hợp của một ứng dụng có chứa một bộ tài liệu mà bạn có thể duyệt từ Internet. Nếu bạn kích hoạt proxy cá nhân (chẳng hạn như ZAP hoặc Burp Suite), bạn có thể nhận được POST HTTP như sau (http://www.example.com/public/doc):

POST /public/doc HTTP/1.1
Host: www.example.com
[...]
Referer: http://127.0.0.1/WebGoat/attack?Screen=20
Cookie: JSESSIONID=295500AD2AAEEBEDC9DB86E34F24A0A5
Authorization: Basic T2Vbc1Q9Z3V2Tc3e=
Content-Type: application/x-www-form-urlencoded
Content-length: 33

Doc=Doc1.pdf

Trong yêu cầu đăng bài này, chúng tôi nhận thấy cách ứng dụng truy xuất tài liệu công khai. Bây giờ chúng ta có thể kiểm tra xem có thể thêm lệnh hệ điều hành để đưa vào HTTP POST hay không. Hãy thử những cách sau (http://www.example.com/public/doc):

POST /public/doc HTTP/1.1
Host: www.example.com
[...]
Referer: http://127.0.0.1/WebGoat/attack?Screen=20
Cookie: JSESSIONID=295500AD2AAEEBEDC9DB86E34F24A0A5
Authorization: Basic T2Vbc1Q9Z3V2Tc3e=
Content-Type: application/x-www-form-urlencoded
Content-length: 33

Doc=Doc1.pdf+|+Dir c:\

Nếu ứng dụng không xác thực yêu cầu, chúng tôi có thể nhận được kết quả sau:

Exec Results for 'cmd.exe /c type "C:\httpd\public\doc\"Doc=Doc1.pdf+|+Dir c:\'
    Output...
    Il volume nell'unità C non ha etichetta.
    Numero di serie Del volume: 8E3F-4B61
    Directory of c:\
     18/10/2006 00:27 2,675 Dir_Prog.txt
     18/10/2006 00:28 3,887 Dir_ProgFile.txt
     16/11/2006 10:43
        Doc
        11/11/2006 17:25
           Documents and Settings
           25/10/2006 03:11
              I386
              14/11/2006 18:51
             h4ck3r
             30/09/2005 21:40 25,934
            OWASP1.JPG
            03/11/2006 18:29
                Prog
                18/11/2006 11:20
                    Program Files
                    16/11/2006 21:12
                        Software
                        24/10/2006 18:25
                            Setup
                            24/10/2006 23:37
                                Technologies
                                18/11/2006 11:14
                                3 File 32,496 byte
                                13 Directory 6,921,269,248 byte disponibili
                                Return code: 0

Trong trường hợp này, chúng tôi đã thực hiện thành công một cuộc tấn công đưa vào hệ điều hành.

Các ký tự đặc biệt cho Command Injection

  • Ký tự đặc biệt sau có thể được sử dụng để chèn lệnh, chẳng hạn như | ; & $> <‘!
  • cmd1 | cmd2: Công dụng của | sẽ làm cho lệnh 2 được thực hiện mặc dù lệnh 1 thực hiện có thành công hay không.
  • cmd1; cmd2: Công dụng của; sẽ làm cho lệnh 2 được thực hiện mặc dù lệnh 1 thực hiện có thành công hay không.
  • cmd1 || cmd2: Lệnh 2 sẽ chỉ được thực hiện nếu lệnh 1 không thực hiện được.
  • cmd1 && cmd2: Lệnh 2 sẽ chỉ được thực thi nếu lệnh 1 thực hiện thành công.
    • Ví dụ: $(cmd) : For example, echo $(whoami) or $(touch test.sh; echo 'ls' > test.sh)
  • cmd: Nó được sử dụng để thực thi một lệnh cụ thể. Ví dụ, whoami
    • >(cmd):> (ls)
    • <(cmd): <(ls)

Đánh giá mã API nguy hiểm

Hãy lưu ý việc sử dụng API sau vì nó có thể dẫn đến rủi ro tiêm lệnh.

Java

  • Runtime.exec()

C/C++

  • system
  • exec
  • ShellExecute

Python

  • exec
  • eval
  • os.system
  • os.popen
  • subprocess.popen
  • subprocess.call

PHP

  • system
  • shell_exec
  • exec
  • proc_open
  • eval

Biện pháp khắc phục hậu quả

Vệ sinh

URL và dữ liệu biểu mẫu cần được làm sạch để tìm các ký tự không hợp lệ. Một danh sách từ chối các ký tự là một tùy chọn nhưng có thể khó nghĩ ra tất cả các ký tự để xác nhận chống lại. Ngoài ra, có thể có một số vẫn chưa được phát hiện. Danh sách cho phép chỉ chứa các ký tự hoặc danh sách lệnh phải được tạo để xác thực đầu vào của người dùng. Các nhân vật bị bỏ sót, cũng như các mối đe dọa chưa được phát hiện, nên bị loại bỏ bởi danh sách này.

Danh sách từ chối chung được đưa vào để tiêm lệnh có thể là | ; & $> <‘\! >> #

Thoát hoặc lọc các ký tự đặc biệt cho cửa sổ, () <> & * ‘| =? ; [] ^ ~! . “% @ / \: +,` Thoát hoặc lọc các ký tự đặc biệt cho Linux, {} ()> <& * ‘| =?; [] $ – # ~!.”% / \: +, `

Quyền

Ứng dụng web và các thành phần của nó phải chạy dưới các quyền nghiêm ngặt không cho phép thực thi lệnh của hệ điều hành. Cố gắng xác minh tất cả thông tin này để kiểm tra theo quan điểm kiểm tra hộp xám.

Công cụ

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Contact Me on Zalo
Call now