[웹 해킹] Command Injection
1. 개요
Command Injection은 애플리케이션이 시스템 명령어를 실행하기 위해 사용자의 입력을 포함할 때, 공격자가 입력을 조작하여 추가 명령어를 삽입하거나 실행하도록 만드는 방식
📌 공격 조건 :
1. 애플리케이션이 운영체제 명령어를 호출해야 하는 경우
2. 입력값에 대한 검증이 충분하지 않은 경우
Command Injection 공격은 2021 OWASP Top 10에서 `Injection`에 해당된다.
2. 공격 예시
📕 예시1
<?php
if (isset($_GET['ip'])) {
$ip = $_GET['ip'];
$output = shell_exec("ping -c 4 " . $ip);
echo "<pre>$output</pre>";
}
?>
위와 같이 `ping` 명령어에 사용자 입력($ip)을 포함하여서 실행되는데, 공격자가 입력값을 조작하여 추가 명령어를 수행할 수 있음.
Unix/Linux일 때 예시 : `8.8.8.8; cat /etc/passwd`
윈도일 때 예시 : `8.8.8.8 && dir`
📕 예시2
웹 애플리케이션에서 파일 이름이 URL에 표시되는 경우가 많다. Perl은 프로세스에서 열린 문장으로 데이터를 파이프로 연결할 수 있다. 파일 이름 끝에 파이프 기호 `|`를 추가하면 된다.
[예시]
`https://sensitive/cgi-bin/userData.pl?doc=user1.txt`
👉 `https://sensitive/cgi-bin/userData.pl?doc=/bin/ls|`
이렇게 URL을 수정하면, `/bin/ls` 명령어가 실행된다.
📕 예시3
.php 페이지의 URL 끝에 세미콜론 (`;`)을 추가한 다음에 운영체제 명령어를 입력하면 명령이 실행된다. `%3B`는 URL 인코딩이 되어 있어 세미콜론(`;`)으로 디코딩된다.
[예시]
`https://sensitive/something.php?dir=%3Bcat%20/etc/passwd`
(URL 디코딩) `https://sensitive/something.php?dir=;cat /etc/passwd`
📕 예시4
인터넷에서 탐색할 수 있는 문서 집합을 포함하는 애플리케이션의 예로, `Burp Suite`와 같은 프록시툴로 실행하면 다음과 같은 POST HTTP를 얻을 수 있다.
POST /public/doc HTTP/1.1
Host: www.example.com
[...]
Referer: https://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
이제 POST HTTP에 주입할 운영 체제 명령을 추가할 수 있는지 테스트할 수 있습니다.
POST /public/doc HTTP/1.1
Host: www.example.com
[...]
Referer: https://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:\
👉 문서 경로에 `|`을 추가하여 `Dir c:\`라는 시스템 명령어 실행
애플리케이션이 요청을 검증하지 않으면 다음과 같은 결과를 얻을 수 있음.
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
3. 취약한 함수
Command Injection에 사용할 수 있는 특수문자 : `| ; & $ > < ' !`
- `cmd1|cmd2` : (파이프) `|`를 사용하면 cmd1의 출력을 cmd2의 입력으로 전달합니다. cmd1이 성공하거나 실패하더라도 cmd2는 실행됩니다.
- `cmd1;cmd2` : (순차실행) `;`를 사용하면 cmd1의 실행이 끝난 후, 성공여부와 상관없이 cmd2가 실행됩니다.
- `cmd1||cmd2` : (OR 논리연산) cmd1 실행이 실패할 경우에만 cmd2가 실행됩니다.
- `cmd1&&cmd2` : (AND 논리연산) cmd1 실행이 성공할 경우에만 cmd2가 실행됩니다.
- `$(cmd)` : (명령어 치환) cmd의 실행 결과를 캡처하여 다른 명령어의 일부로 사용합니다. 예를 들어 `echo $(whoami)` 에서 `whoami` 명령어의 출력 결과를 포함하여 `사용자이름`을 출력합니다.
- `cmd` : 특정 명령어를 실행하는 데 사용됩니다.
- `>(cmd)`: (프로세스 치환-출력) `>(ls)` 명령어의 출력을 임시 파일이나 스트림으로 만들어 다른 명령어로 보냅니다. 파일을 필요로 하는 명령어와 함께 사용됩니다.
- `<(cmd)`: (프로세스 치환-입력) `<(ls)` 명령어의 출력을 임시 파일이나 스트림으로 만들어 다른 명령어가 입력으로 사용합니다.
PHP
- `system`, `shell_exec`, `exec`, `proc_open`, `eval`
Shell Scripts
- 모두 실행 가능
Perl
- `open`, `sysopen`, `glob`, `system`, `eval`
Java
- `Runtime.exec()`
C, C++
- `system`, `exec`, `ShellExecute`
(strcpy strcat sprintf vsprintf gets strlen (특별히 null 바이트와 함께 사용될 경우) scanf() fscanf sscanf vscanf vsscanf vfscanf realpath getopt getpass streadd strecpy strtrns)
Python
- `exec`, `eval`, `os.system`, `os.popen`, `subprocess.popen`, `subprocess.call`
4. 예방방법
- 사용자 입력값 검증
- 명령어 실행 회피
* 시스템 명령어 대신 안전한 API 사용 등
- 입력값 이스케이프 처리
- 최소 권한 사용
https://owasp.org/Top10/A03_2021-Injection/