[웹 취약점] 운영체제 명령 실행 (Command Injection)
개요
운영체제 명령 실행 (Command Injection)은 사용자 입력 값에 의해 시스템 명령어가 실행되는 취약점으로, 사용자 입력 폼, 쿠키, 파라미터, HTTP 헤더 등을 시스템 셸에 전달할 때 공격이 발생한다.
운영체제 명령 실행은 주로 사용자 입력 값에 대한 검증이 미흡하여 발생하게 된다.
예시
위 사진의 페이지는 사용자가 IP 주소를 입력하면 해당 IP로 Ping을 보내고, 그 결과를 출력하는 페이지이다.
그런데 IP 주소 대신 '& cat /etc/passwd &'라는 문자열을 삽입하였더니 passwd 파일의 내용이 출력되는 것을 볼 수 있다. 이것이 바로 운영체제 명령 실행 취약점이다.
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
해당 페이지의 PHP 소스코드이다. 입력 값을 받아 별도의 검증 절차 없이 shell_exec()로 전달하는 모습을 볼 수 있다.
'192.168.0.1 & cat /etc/passwd'를 입력하면 'ping 192.168.0.1 -c 4 & cat /etc/passwd'라는 명령이 실행되는 셈이다.
진단 방법
사용자 입력 폼, 쿠키, 파라미터, HTTP 헤더 등에 임의의 명령어를 삽입하여 명령어가 실행되는지 여부를 확인하면 된다.
운영체제 명령 실행 취약점은 셸(Shell)에서 명령어를 연달아 사용할 수 있는 특징을 이용하므로 ';', '&', '&&', '|' 같은 특수문자들을 활용하게 된다. 해당 특수문자들에 대한 설명은 다음과 같다.
1. 세미콜론 (;)
순차적 연결이라고 하며, 하나의 라인에 주어진 명령어들을 전부 순서대로 실행한다.
2. 앰퍼샌드 (&)
후면 처리라고 하며, 명령어를 구분하여 앰퍼샌드(&) 앞에 있는 명령어는 백그라운드로 실행하고, 뒤에 있는 명령어는 즉시 실행한다.
3. 더블 앰퍼샌드 (&&)
참 조건형 연결이라고 하며, 앞에 있는 명령어가 성공했을 때 뒤에 있는 명령어를 실행한다.
4. 버티컬 바 (|)
파이프 연결이라고 부르며, 버티컬 바(|) 앞에 있는 명령어의 결과를 뒤에 있는 명령어의 입력으로 사용한다.
조치 방안
Server Side Script 언어로 프로그램을 작성하는 경우, 가능하면 시스템 명령어를 직접적으로 호출하지 않도록 구현 해야 한다.
만약 시스템 명령어를 사용해야 한다면 데이터가 운영체제의 셸(Shell)에 전달되기 이전에 데이터를 검증하여 앞서 설명한 특수문자에 대한 필터링 처리가 이루어지도록 해야한다.