정의
웹을 통해 시스템 명령어를 실행하는 공격
웹 내부에서 시스템 명령어를 실행하는 경우, 입력값을 제대로 검사하지 않으면 해커가 조작하여 시스템 명령어를 실행
실습
Low 단계에서 127.0.0.1을 입력하고 몇 초 지난 후 ping 명령이 실행됐음을 알 수 있다.
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
소스 코드를 보면 입력한 ip를 목적지로 ping 메시지를 4번 보내는 것을 알 수 있다. shell_exec가 시스템 명령어 실행함수다.
입력값에 ;cat /etc/passwd를 입력하면 cat /etc/passwd 명령의 실행결과가 출력된다.
Command Injection 공격에 사용되는 특수문자의 일부는 다음과 같다.
; - 앞의 명령어가 실패해도 다음 명령어가 실행
&& - 앞의 명령어가 성공했을 때 다음 명령어가 실행
& - 앞의 명령어를 백그라운드로 돌리고 동시에 뒤의 명령어를 실행
| - 앞의 명령어의 실행 결과 값을 뒤의 명령어의 입력값으로 사용
;id를 입력하면 웹 어플리케이션을 실행한 사용자가 누군지 알 수 있다. 관리자 권한을 얻어야 모든 명령을 사용할 수 있기 때문에 권한 상승 작업이 필요하다.
Medium 단계에서 소스 코드를 보면 &&와 ;가 필터링 되고 있다.
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
&&와 ;를 없는 문자로 치환하고 있다. 따라서 &나 |와 같은 특수문자를 이용하여 여전히 우회가능하다.
High 단계에서는 필터링되는 문자가 많다.
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
한 가지 문제가 있다. 파이프 부분에서 뒤에 공백이 있다. 따라서 파이프 뒤에 명령을 이어서 쓰면 우회가능하다.
Impossible 단계
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode( ".", $target );
// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
Command Injection의 가장 좋은 대응 방법은 사용자의 입력값이 원래 의도에 맞는지 검사하는 것이다.
허용할 값을 명시하는 것이다. 따라서 화이트리스트 방식이다.
IP 주소를 입력받는 것이라면 입력값이 IP인지 확인해야한다.
IPv4는 0~255 범위의 값을 4개 가지고 .으로 구분된다.
위의 코드에서 .을 기준으로 4가지 값이 각각 숫자인지 확인하고 다시 IP 형태로 합치는 작업을 수행한다.
대응 방안
가장 좋은 공격 대응 방안은 직접적으로 시스템 명령어를 호출하지 않는 것이다.
만약 시스템 명령어 exec()나 system() 함수를 사용해야하고 사용자 입력값이 명령어에 사용될 때는 입력값을 화이트리스트 방식으로 검증해야한다.
'dvwa' 카테고리의 다른 글
SQL Injection (0) | 2023.05.16 |
---|---|
File Upload (0) | 2023.05.06 |
File Inclusion (0) | 2023.05.06 |
CSRF (0) | 2023.05.05 |
Brute Force (0) | 2023.05.02 |