2012년 1월 PHP 5.4.2 이전 버전에서 원격 코드 실행(RCE, Remote Code Execution)이 가능한 취약점이 발견됐다.
1월에 최초로 발견되어 CVE 취약점 (CVE-2012-1823)로 명명됐다. 취약점이 발견된 후 즉시 보안 조치가 적용되지 않다가 5월 6일 보안 패치가 적용됐다.
이 취약점은 sapi/cgi/cgi_main.c 파일 내의 CGI 스크립트(php-cgi)가 –s, -d, -c 등과 같은 매개 변수를 적절히 검증하지 않아 발생한다.
대상
영향을 받는 버전의 5.3.12 또는 5.4.2 이전 버전을 사용하는 모든 시스템에 취약점이 노출되어 있다.
구분 | 제품명 | 버전 |
취약한 대상 | PHP | 5.3.12 이전 버전 5.4.2 이전 버전 |
권고 대상 | PHP | 5.3.12 이후 버전 5.4.2 이후 버전 |
환경 설정
연구와 학습 목적으로 취약하게 설정되어 있는 우분투 환경의 메타스플로잇테이블 버전2(Metasplitable V2)를 대상으로 CVE-2012-1823 취약점을 실습한다.
취약점 공격
취약점 공격 시 주로 사용되는 php-cgi 옵션과 php.ini 파일의 설정이다. 해당 옵션 및 설정을 가지고 원격 코드 실행이 가능한 공격이 가능하다.
옵션 | 내용 |
-s | 소스코드에 색을 입혀 출력 |
-n | php.ini 파일 사용하지 않음 |
-d | php.ini 파일에 정의된 설정 내용 조작 |
설정 | 내용 |
allow_url_fopen=1 | 외부 URL 파일을 로드 |
allow_url_include=1 | 외부 파일을 include, include_once, require, require_one 함수와 같이 포함할 때 사용 |
auto_prepend_file=php://input | HTTP 요청 바디에 있는 데이터를 실행 |
엔맵 스크립팅 엔진(NSE, Nmap Scripting Engine)을 이용해 메타스플로잇테이블 대상 내의 PHP 버전을 확인한다.
스캔 결과가 종료되면 PHP 버전이 출력되며, 출력된 버전을 보면 CVE-2012-1823 취약점에 해당하는 버전을 사용한 것으로 확인된다.
PHP로 구성된 웹 사이트에 매개변수 "-s"를 지정하면 "php-cgi –s"가 실행되어 웹 사이트의 소스코드가 노출된다.
매개변수 "-d", php.ini 파일의 설정 내용 "auto_prepend_file"을 지정하면 "php-cgi –d auto_prepend_file=/etc/passwd가 실행되어 패스워드 파일이 노출된다.
매개변수 "-d", php.ini 파일의 "allow_url_include, auto_prepend_file"을 이용하면 시스템 명령어를 사용할 수 있다.
다음과 같이 HTTP 헤더, HTTP 바디에 데이터를 입력 후 서버로 요청하면 shell_exec() 함수가 실행되어 현재 접속된 사용자의 정보가 출력된다.
외부에서 shell_exec() 함수를 사용할 수 있다는 것은 아파치 권한으로 실행될 수 있는 모든 명령어를 사용할 수 있다. 다음과 같이 wget 명령어로 웹쉘 파일을 업로드 시도하면 정상적으로 업로드 된다.
업로드한 디렉토리로 이동하여 웹쉘 파일을 실행한다.
메타스플로잇 프레임워크(MSF, Metasploit Framework)를 이용해 해당 취약점 모듈을 선택 후 공격을 수행한다. 취약점 공격에 성공하면 웹 서버와 리버스 커넥션이 맺어지게 되어 시스템 쉘이 획득된다.
공격 수행 중 패킷을 보면 php.ini 파일 설정을 무시하고 HTTP 바디에 있는 데이터를 먼저 처리하게 된다. 즉, 원격 코드 실행 시 사용한 HTTP 헤더, HTTP 바디와 동일한 페이로드이다.
취약점 발생 원리
CVE-2012-1823 취약점은 sapi/cgi/cgi_main.c 파일에서 매개변수를 검증하지 않아 발생되는 취약점이다.
취약점이 발생한 소스코드를 보면 while()문 내의 매개변수를 검증하는 코드가 존재하지 않아 취약점이 발생한다. if문은 cgi 사용 여부, while문은 php-cgi 옵션이 존재하면 php-cgi에 전달되는 구문이다.
대응 방안
○ 취약점이 존재하지 않는 버전으로 업데이트