分享一次组合漏洞挖掘拿下目标

admin 2025年3月5日15:08:42评论31 views字数 2540阅读8分28秒阅读模式

前言

背景为多年前的某次红队在钓鱼、常规打点无果的情况下获取到了一份和目标单位某站点相匹配的代码,自此开始对这套代码进行审计。最终挖掘了众多小漏洞,在目标为springboot的情况下,利用jdk的懒加载特性巧妙串联诸多漏洞后拿下了该站点的shell。

漏洞挖掘和利用

JWT Token伪造漏洞

这个漏洞比较经典,很多系统在判断jwt token的时候会用一个固定的密钥去加解密,这时候如果攻击者在代码中拿到了这个密钥,那么他就可以反向的加密出一个加密的token来伪造任意用户,造成越权

分享一次组合漏洞挖掘拿下目标

这里就是这种情况,我们用代码中的token可以直接加密地得到一个管理员token。此种情况如果要修复的话,可以再加一个验证,在jwt token解密之后,调取数据库记录,验证这个user是否登录过,如果没登录过就说明这个token是被构造出来的,就应该拒绝登录。

jwt构造代码大致如下

分享一次组合漏洞挖掘拿下目标

Zip解压缩漏洞

发现某后台上传接口利用了一个第三方jar包做解压缩,这个jar包在解压缩过程中有zip解压缩漏洞,会造成文件在解压时可以落地到任意目录。

分享一次组合漏洞挖掘拿下目标

到这里为止,以及有了一个能在任意文件夹上传任意文件的漏洞,如果是Tomcat的话,直接传一个jsp就可以getshell了,不过这个系统是一个springboot,就没办法去传shell了。

springboot文件上传getshell之前网上也有人分享过覆盖charsets.jar,通过其懒加载特性去执行任意代码(https://landgrey.me/blog/22/)。核心思想是:如果charsets.jar中的类在系统运行过程中没有被使用过,则这个jar不会被jvm载入内存中。我们用文件上传漏洞把charsets.jar替换为我们的恶意jar,通过http请求包中添加Accept头或者fastjson等方法去主动加载charsets中的类,这时候jvm加载的就是我们的恶意charsets.jar了,在初始化的时候就会执行任意代码,具体的操作可以参考上面链接中的文章。我搭建这个系统后发现,这个系统在启动时有一些类调用到了charsets.jar中的类,所以charset.jar在系统启动的时候就被加载到内存中了,后面再去替换就没用了。

这时候问题陷入了僵局,但在思考后我想到,既然charsets.jar有懒加载的特性,其他的jar是否也有懒加载特性呢?最后找到了jre/lib/ext/nashorn.jar。那么接下来的问题就是我覆盖写了nashorn.jar后,怎么去加载我的恶意类了

sql执行

这个是同事发现的,看来像后门一样,直接执行任意sql语句。印象中是mysql数据库,总之无法通过此处getshell

触发类的实例化

jdbc触发

在对代码进行研究后发现有一个加载jdbc的地方,这里cnfgStr的值是从数据库读到的,因为我们可以执行任意sql语句,所以cnfgStr我们就完全可控了

分享一次组合漏洞挖掘拿下目标

下面再谈怎么通过jdbc连接触发类加载。一般我们在jdbc反序列化时,常见的jdbc连接字符串如下

jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc

其中statementInterceptors这个参数指定了一个类名,这个类在jdbc连接过程中是要被实例化然后调用的,因此我只要把这个参数中的类名改成我修改的nashorn.jar中的恶意类名就行了

fastjson触发

jdbc触发的问题在于,不能传参数给我们的恶意类(可能有办法,没去细看mysql文档,因为要花时间去挖掘,时间比较紧张),这就意味着我们的恶意内容比如执行java代码或执行系统命令,只能在实例化的时候触发一次。类似于

分享一次组合漏洞挖掘拿下目标

执行完之后nashorn.jar已经被加载到内存中了,这时候类的内容就不能改了。假如我们选择的是执行任意java代码,如果没注入进去,那后面就没机会再去试了。因此jdbc触发方案可行,但容错率太低,赌不起。

恰好看到了在进入jdbc连接前的代码是Fastjson的parseObject,于是想到能不能用Fastjson来触发类的实例化,Fastjson的好处是在用@type实例化类的时候是可以指定参数的,这样我们可以控制参数的不同,来每次都执行不一样的代码。大概代码如下

分享一次组合漏洞挖掘拿下目标

因此最后我选择了用fastjson的方式来触发,这样会给我们更多的尝试机会来getshell,容错率比较高

构造懒加载jar包

这个jar包的修改比较讲究,首先我们选择随便nashorn.jar中的一个类,这里打比方就修改jdk.nashorn.tools.Shell类,由于我们用的是fastjson触发,所以要考虑fastjson的版本。不巧的是,当前系统的fastjson是1.2.83的,fastjson1.2.83在实例化类的时候有一个@type白名单,我们的jdk.nashorn.tools.Shell必然不在fastjson白名单里面。这时候我想到了问chatgpt,怎么样可以绕过去这个白名单限制

分享一次组合漏洞挖掘拿下目标

不过我测试了下,这样在fastjson1.2.83下还是不行,要在类定义上方再加一个@JSONType才行。最后构造出来的恶意类如下:

分享一次组合漏洞挖掘拿下目标

然后把这个恶意类编译后替换原本的nashorn.jar即可,把这个jar通过之前的zip解压缩漏洞覆盖掉目标本地jdk的nashorn.jar

分享一次组合漏洞挖掘拿下目标

然后将数据库cnfgStr值改成如下。javaCode中填写自己要执行的java字节码的base64即可。执行完一次再执行第二次的话,通过任意sql执行漏洞更新数据库的javaCode内容,然后再触发一次fastjson调用即可即可

{"@type":"jdk.nashorn.tools.Shell","javaCode":"xxx"}

总结

实战中漏洞利用>漏洞挖掘,漏洞拿不下目标就都是空谈

原文始发于微信公众号(哈拉少安全小队):分享一次组合漏洞挖掘拿下目标

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年3月5日15:08:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   分享一次组合漏洞挖掘拿下目标https://cn-sec.com/archives/3799007.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息