Research & Technique Apache Tomcat RCE 취약점 (CVE-2019-0232) 취약점개요 지난 4월 15일전세계적으로가장많이사용되는웹애플리케이션서버인 Apache Tomcat에서 RCE 취약점이공개되었다. CVE-2019-0232 취약점은 Windows 시스템의 Apache Tomcat 서버에서 enablecmdlinearguments 옵션이 True로설정된 CGI 서블릿을사용할시전달받는인자들을적절하게처리하지못해발생하며, 공격자가임의의명령을원격으로실행할수있다. Tomcat 7.x 및 8.x 서버에서 CGI 서블릿을사용할때에는 enablecmdlinearguments 옵션이 True로기본설정되어취약점에노출될수있으므로주의가필요하다. 영항받는소프트웨어버전 S/W 구분 Apache Tomcat 취약버전 9.0.18 이전버전 8.5.40 이전버전 7.0.94 이전버전 EQST insight 14
테스트환경구성정보 역할구분 공격자 정보 Windows 10 64bit 희생자 Windows 7 32bit / Apache Tomcat 8.5.39 취약점테스트 Step 1. 취약점테스트환경구축 취약한버전의 Apache Tomcat(8.5.39) 을다운로드하여희생자 PC 에설치한다. 이전버전의 Tomcat 을다운로드할수있는사이트는다음과같다. https://archive.apache.org/dist/tomcat/tomcat-8/ 설치한 Apache Tomcat 에서 CGI 서블릿을사용하기위해 conf/web.xml 파일에서 CGI 서블릿설정을다음과같이 수정한다.... <servlet> <servlet-name>cgi</servlet-name> <servlet-class>org.apache.catalina.servlets.cgiservlet</servlet-class> <init-param> <param-name>cgipathprefix</param-name> <param-value>web-inf/cgi-bin</param-value> </init-param> <init-param> <param-name>enablecmdlinearguments</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>executable</param-name> <param-value></param-value> </init-param> <load-on-startup>5</load-on-startup> </servlet>... <servlet-mapping> <servlet-name>cgi</servlet-name> <url-pattern>/cgi-bin/*</url-pattern> </servlet-mapping>... EQST insight 15
그후 conf/context.xml 파일을수정하여관리자서블릿과같은컨테이너서블릿을사용할수있도록 privileged 속 성을추가한다. <?xml version= 1.0 encoding= UTF-8?> <Context privileged= true > <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource> </Context> webapps/root/web-inf 폴더에 cgi-bin 폴더를생성하고, 그안에 poc.bat 를작성한다. @echo off echo Content-Type: text/plain echo. set foo=%~1 %foo% Bin 폴더내의 startup.bat 파일을실행시켜 Apache Tomcat 서버를시작한다. Step 2. POC 테스트 공격자는희생자의 Apache Tomcat 서버에접근하여 poc.bat 요청시삽입한 dir 명령이실행된것을확인할수있 다. [POC 테스트성공화면 ] EQST insight 16
취약점상세분석 Step 1. 취약점동작원리 CVE-2019-0232 취약점은 Windows 에서 Java App이외부프로그램을실행할경우 Command Line 인자들을 Windows에전달할때발생하는버그로인해발생한다. 먼저, Linux에서 Java App에서외부프로그램을실행할때인자들을문자열배열로전달한다. [ 외부프로그램실행코드 ] Java App 이외부프로그램을실행할때전달된문자열배열대로출력되는것을확인할수있다. [Linux 에서외부프로그램실행 ] 반면, Windows에서는 Command Line 인자들을단일 Command Line 문자열로전달한후, Command Line 문자열을구문분석하여실행한다. 동일한예제로 Java App에서외부프로그램을실행하면 ProcessImpl() 함수에서실행되어야할파일은.bat이나.cmd 확장자가존재할경우에는 cmd.exe가실행된다. 따라서, CreateProcess() 함수에서 cmd.exe의첫번째매개변수로실행할파일의이름이전달되어실행되기때문에 C:\Windows\system32\ cmd.exe / c arg.bat arg & dir Command Line이실행된다. EQST insight 17
[Windows 에서외부프로그램실행 ] [Command Line 확인 ] Step 2. 취약한소스코드분석 CGI 서블릿에서 enablecmdlinearguments 가 true 로설정되어있을경우사용자가입력한값을그대로 Command Line 의인자로저장한다. 이부분에서사용자의입력에대한적절한처리를하지않아취약점이발생한다. EQST insight 18
[ 입력값에대한검증이존재하지않음 ] CGI 요청시 doget() 함수에서데이터를전달받아 command, 환경변수, 작업폴더, 파라미터를포함한 CGIRunner 객체를생성하여실행한다. [CGI 실행코드 ] 이후 run() 함수내에서 command 를실행하기위해 exec() 함수를호출하여 process 를생성한다. 실행할파일명과 인자들은 exec() 함수내부의 ProcessImpl() 함수에전달되어단일 Command Line 으로만들어진다. 생성된 Command Line 은 Windows 프로세스생성함수인 CreateProcess() 함수를통해실행된다. EQST insight 19
[Command Line 생성 ] Step 3. 패치된소스코드분석 Apache Tomcat 버전 7.x 및 8.x 에서기본으로 true 로되어있던 enablecmdlinearguments 를패치된 Tomcat 에서 는 false 로변경하여 CGI 서블릿으로 Command Line 인자를전달하지않도록하였다. [Apache Tomcat 7.x 및 8.x 버전의기본설정변경 ] 또한, Windows 시스템에서실행할경우새롭게추가된정규표현식매칭으로입력값을검사하는코드가추가되었 다. EQST insight 20
[ 정규표현식패턴검사추가 ] CGI 서블릿에서인자를전달해야할때, enablecmdlinearguments 값이 true 로설정되어야한다. 이때입력값에 대한유효성을검사하는코드가추가되었다. 정규표현식매칭에서?, & 등의특수문자는허용되지않기때문에 false 를반환한다. EQST insight 21
[ 사용자입력값을정규표현식매치를이용하여검사 ] 허용되지않은문자가입력값에포함되었을시, valid 변수에반환된 false 값이들어가면서 CGI 를실행하지않고 404 에러를반환하게된다. EQST insight 22
[CGI 명령유효성검사 ] [ 유효하지않은경우 404 에러반환 ] EQST insight 23
공격시나리오 Apache Tomcat CVE-2019-0232 취약점을이용하여취약한대상의정보를탈취하는시나리오는다음과같다. 웹페이지 Tomcat 웹서버 WWW 데이터베이스 1 대상탐색 2 CVE CVE-2019-0232 서버주요정보탈취 획득한정보활용 CVE 3 중요정보탈취 5 4 TOP SECRET 공격자 [ 공격시나리오 ] 1 공격자는운영중인페이지가 Windows 환경에서취약한버전의 Tomcat으로 CGI 서블릿을사용하는것을확인함 2 공격자는 CGI 요청시악의적인명령을전달하여 RCE을시도함 3 공격을통해웹서버내의주요정보 ( 시스템설정파일, 소스코드 ) 들을획득함 4 공격자는획득한정보를통해서버에대한공격을재수행함 5 재공격에성공하여공격자가중요정보를탈취함 EQST insight 24
대응방안 취약점이패치된 Apache Tomcat 버전으로업데이트한다. - Apache Tomcat 9.0.18 이상 - Apache Tomcat 8.5.40 이상 - Apache Tomcat 7.0.93 이상 [Apache Tomcat 취약점패치 ] EQST insight 25