mirror of
				https://github.com/maride/pancap.git
				synced 2025-10-10 19:36:51 +00:00 
			
		
		
		
	Add support for DHCPv4 packets
This commit is contained in:
		
							parent
							
								
									aa59576c9c
								
							
						
					
					
						commit
						37afbb58a9
					
				
							
								
								
									
										30
									
								
								ethernet/dhcpv4/common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								ethernet/dhcpv4/common.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| package dhcpv4 | ||||
| 
 | ||||
| import "fmt" | ||||
| 
 | ||||
| // Appends the appendee to the array if it does not contain appendee yet | ||||
| func appendIfUnique(appendee string, array []string) []string { | ||||
| 	// Iterate over all elements and check values | ||||
| 	for _, elem := range array { | ||||
| 		if elem == appendee { | ||||
| 			// ... found. Stop here | ||||
| 			return array | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// None found, append | ||||
| 	return append(array, appendee) | ||||
| } | ||||
| 
 | ||||
| // Prints each element, along with a small ASCII tree | ||||
| func printTree(strarr []string) { | ||||
| 	// iterate over each element | ||||
| 	for iter, elem := range strarr { | ||||
| 		// check if we got the last element | ||||
| 		if iter < len(strarr) - 1 { | ||||
| 			fmt.Printf("|- %s\n", elem) | ||||
| 		} else { | ||||
| 			fmt.Printf("'- %s\n\n", elem) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										109
									
								
								ethernet/dhcpv4/dhcp.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								ethernet/dhcpv4/dhcp.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| package dhcpv4 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/fatih/color" | ||||
| 	"github.com/google/gopacket" | ||||
| 	"github.com/google/gopacket/layers" | ||||
| 	"log" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	requestMAC []string | ||||
| 	responses []dhcpResponse | ||||
| ) | ||||
| 
 | ||||
| // Called on every DHCP (v4) packet | ||||
| func HandleDHCPv4Packet(packet gopacket.Packet) error { | ||||
| 	var dhcppacket layers.DHCPv4 | ||||
| 	var ethernetpacket layers.Ethernet | ||||
| 
 | ||||
| 	// Decode raw packet into DHCPv4 | ||||
| 	decodeDHCPErr := dhcppacket.DecodeFromBytes(packet.Layer(layers.LayerTypeDHCPv4).LayerContents(), gopacket.NilDecodeFeedback) | ||||
| 	if decodeDHCPErr != nil { | ||||
| 		// Encountered an error during decoding, most likely a broken packet | ||||
| 		return decodeDHCPErr | ||||
| 	} | ||||
| 
 | ||||
| 	// And decode raw packet into Ethernet | ||||
| 	decodeEthernetErr := ethernetpacket.DecodeFromBytes(packet.Layer(layers.LayerTypeEthernet).LayerContents(), gopacket.NilDecodeFeedback) | ||||
| 	if decodeEthernetErr != nil { | ||||
| 		// Encountered an error during decoding, most likely a broken packet | ||||
| 		return decodeEthernetErr | ||||
| 	} | ||||
| 
 | ||||
| 	// Examine packet further | ||||
| 	if dhcppacket.Operation == layers.DHCPOpRequest { | ||||
| 		// Request packet | ||||
| 		appendIfUnique(dhcppacket.ClientHWAddr.String(), requestMAC) | ||||
| 	} else { | ||||
| 		// Response/Offer packet | ||||
| 		addResponseEntry(dhcppacket.ClientIP.String(), dhcppacket.ClientHWAddr.String(), ethernetpacket.SrcMAC.String()) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Print summary after all packets are processed | ||||
| func PrintDHCPv4Summary() { | ||||
| 	headline := color.New(color.FgRed, color.Bold) | ||||
| 	headline.Println("DHCP Requests") | ||||
| 	printRequestSummary() | ||||
| 	headline.Println("DHCP Responses/Offers") | ||||
| 	printResponseSummary() | ||||
| } | ||||
| 
 | ||||
| // Prints the summary of all DHCP request packets | ||||
| func printRequestSummary() { | ||||
| 	fmt.Printf("%d unique DHCP requests\n", len(requestMAC)) | ||||
| 	printTree(requestMAC) | ||||
| } | ||||
| 
 | ||||
| // Prints the summary of all DHCP offer packets | ||||
| func printResponseSummary() { | ||||
| 	var tmpaddr []string | ||||
| 
 | ||||
| 	// Iterate over all responses | ||||
| 	for _, r := range responses { | ||||
| 		tmpaddr = append(tmpaddr, fmt.Sprintf("%s offered %s IP address %s", r.serverMACAddr, r.destMACAddr, r.newIPAddr)) | ||||
| 	} | ||||
| 
 | ||||
| 	// Draw as tree | ||||
| 	printTree(tmpaddr) | ||||
| } | ||||
| 
 | ||||
| // Adds a new response entry. If an IP address was already issued or a MAC asks multiple times for DNS, the case is examined further | ||||
| func addResponseEntry(newIP string, destMAC string, serverMAC string) { | ||||
| 	for _, r := range responses { | ||||
| 		// Check for interesting cases | ||||
| 		if r.destMACAddr == destMAC { | ||||
| 			// The same client device received multiple IP addresses, let's examine further | ||||
| 			if r.newIPAddr == newIP { | ||||
| 				// the handed IP is the same - this is ok, just badly configured | ||||
| 				if r.serverMACAddr == serverMAC { | ||||
| 					// Same DHCP server answered. | ||||
| 					log.Printf("MAC address %s received the same IP address multiple times via DHCP by the same server.", destMAC) | ||||
| 				} else { | ||||
| 					// Different DHCP servers answered, but with the same address - strange network, but ok... | ||||
| 					log.Printf("MAC address %s received the same IP address multiple times via DHCP by different servers.", destMAC) | ||||
| 				} | ||||
| 			} else { | ||||
| 				// far more interesting - one client received multiple addresses | ||||
| 				if r.serverMACAddr == serverMAC { | ||||
| 					// Same DHCP server answered. | ||||
| 					log.Printf("MAC address %s received different IP addresses (%s, %s) multiple times via DHCP by the same server.", destMAC, r.newIPAddr, newIP) | ||||
| 				} else { | ||||
| 					// Different DHCP servers answered, with different addresses - possibly an attempt to build up MitM | ||||
| 					log.Printf("MAC address %s received different IP addresses (%s, %s) multiple times via DHCP by different servers (%s, %s).", destMAC, r.newIPAddr, newIP, r.serverMACAddr, serverMAC) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Add a response entry - even if we found some "strange" behavior before. | ||||
| 	responses = append(responses, dhcpResponse{ | ||||
| 		destMACAddr:   destMAC, | ||||
| 		newIPAddr:     newIP, | ||||
| 		serverMACAddr: serverMAC, | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										8
									
								
								ethernet/dhcpv4/dhcpResponse.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ethernet/dhcpv4/dhcpResponse.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| package dhcpv4 | ||||
| 
 | ||||
| type dhcpResponse struct { | ||||
| 	destMACAddr string | ||||
| 	newIPAddr string | ||||
| 	serverMACAddr string | ||||
| } | ||||
| 
 | ||||
| @ -3,6 +3,7 @@ package ethernet | ||||
| import ( | ||||
| 	"git.darknebu.la/maride/pancap/ethernet/arp" | ||||
| 	"git.darknebu.la/maride/pancap/ethernet/dns" | ||||
| 	"git.darknebu.la/maride/pancap/ethernet/dhcpv4" | ||||
| 	"github.com/google/gopacket" | ||||
| 	"github.com/google/gopacket/layers" | ||||
| 	"log" | ||||
| @ -30,6 +31,11 @@ func Analyze(source *gopacket.PacketSource) error { | ||||
| 			// Handle ARP packet | ||||
| 			arp.ProcessARPPacket(packet) | ||||
| 		} | ||||
| 
 | ||||
| 		if packet.Layer(layers.LayerTypeDHCPv4) != nil { | ||||
| 			// Handle DHCP (v4) packet | ||||
| 			dhcpv4.HandleDHCPv4Packet(packet) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// After processing all packets, print summary | ||||
| @ -42,4 +48,5 @@ func Analyze(source *gopacket.PacketSource) error { | ||||
| func printSummary() { | ||||
| 	arp.PrintARPSummary() | ||||
| 	dns.PrintDNSSummary() | ||||
| 	dhcpv4.PrintDHCPv4Summary() | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user