Using hping3 to perform layer 3 discovery
An even more versatile discovery tool that can be used to perform host discovery in multiple different ways is hping3. It is more powerful than fping in the sense that it can perform multiple, different types of discovery techniques but is less useful as a scanning tool because it can only be used to target a single host. However, this shortcoming can be overcome using bash scripting. This recipe will demonstrate how to use hping3 to perform layer 3 discovery on remote hosts.
Getting ready
Using hping3 to perform layer 3 discovery does not require a lab environment, as many systems on the Internet will reply to ICMP echo requests. However, it is highly recommended that you perform any type of network scanning exclusively in your own lab unless you are thoroughly familiar with the legal regulations imposed by any governing authorities to whom you are subject. If you wish to perform this technique within your lab, you will need to have at least one system that will respond to ICMP requests. In the examples provided, a combination of Linux and Windows systems are used. For more information on setting up systems in a local lab environment, please refer to the the Installing Metasploitable2 and Installing Windows Server recipes in Chapter 1, Getting Started. Additionally, this section will require a script to be written to the filesystem, using a text editor such as VIM or Nano. For more information on writing scripts, please refer to the Using text editors (VIM and Nano) recipe in Chapter 1, Getting Started.
How to do it...
hping3 is a very powerful discovery utility that has a large range of options and modes that it can operate in. It is capable of performing discovery at both layer 3 and layer 4. To perform basic ICMP discovery of a single host address using hping3, you merely need to pass the IP address to be tested and the desired scanning mode of ICMP to it:
root@KaliLinux:~# hping3 172.16.36.1 --icmp HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes len=46 ip=172.16.36.1 ttl=64 id=41835 icmp_seq=0 rtt=0.3 ms len=46 ip=172.16.36.1 ttl=64 id=5039 icmp_seq=1 rtt=0.3 ms len=46 ip=172.16.36.1 ttl=64 id=54056 icmp_seq=2 rtt=0.6 ms len=46 ip=172.16.36.1 ttl=64 id=50519 icmp_seq=3 rtt=0.5 ms len=46 ip=172.16.36.1 ttl=64 id=47642 icmp_seq=4 rtt=0.4 ms ^C --- 172.16.36.1 hping statistic --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 0.3/0.4/0.6 ms
In the demonstration provided, the process was stopped using Ctrl + C. Similar to the standard ping utility, the hping3 ICMP mode will continue indefinitely unless a specific number of packets is specified in the initial command. To define the number of attempts to be sent, the -c
option should be included with an integer value that indicates the desired number of attempts:
root@KaliLinux:~# hping3 172.16.36.1 --icmp -c 2 HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes len=46 ip=172.16.36.1 ttl=64 id=40746 icmp_seq=0 rtt=0.3 ms len=46 ip=172.16.36.1 ttl=64 id=12231 icmp_seq=1 rtt=0.5 ms --- 172.16.36.1 hping statistic --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.3/0.4/0.5 ms
Although hping3 does not support the scanning of multiple systems by default, this can easily be scripted out with bash scripting. In order to do this, we must first identify the distinctions between the output associated with a live address and the output associated with a nonresponsive address. To do this, we should use the same command on an IP address to which no host is assigned:
root@KaliLinux:~# hping3 172.16.36.4 --icmp -c 2 HPING 172.16.36.4 (eth1 172.16.36.4): icmp mode set, 28 headers + 0 data bytes --- 172.16.36.4 hping statistic --- 2 packets transmitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms
By identifying the responses associated with each of these requests, we can determine a unique string that we can grep for; this string will isolate the successful ping attempts from the unsuccessful ones. With hping3, you may notice that the length value is only presented in the case that a response is returned. Based on this, we can extract the successful attempts by grepping for len
. To determine the effectiveness of this approach in script, we should attempt to concatenate the two previous commands and then pipe over the output to our grep
function. Assuming that the string we have selected is truly unique to successful attempts, we should only see the output associated with the live host:
root@KaliLinux:~# hping3 172.16.36.1 --icmp -c 1; hping3 172.16.36.4 --icmp -c 1 | grep "len" HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes len=46 ip=172.16.36.1 ttl=64 id=63974 icmp_seq=0 rtt=0.2 ms --- 172.16.36.1 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.2 ms --- 172.16.36.4 hping statistic --- 1 packets transmitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms
Despite the desired outcome, the grep
function, in this case, does not appear to be effectively applied to the output. As the output display handling in hping3 makes it difficult to pipe over to a grep
function and only extract the desired lines, we can attempt to work around this by other means. Specifically, we will attempt to determine whether the output can be redirected to a file, and then we can grep directly from the file. To do this, we will attempt to pass the output for both the commands used earlier to the handle.txt
file:
root@KaliLinux:~# hping3 172.16.36.1 --icmp -c 1 >> handle.txt --- 172.16.36.1 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.4/0.4/0.4 ms root@KaliLinux:~# hping3 172.16.36.4 --icmp -c 1 >> handle.txt --- 172.16.36.4 hping statistic --- 1 packets transmitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms root@KaliLinux:~# cat handle.txt HPING 172.16.36.1 (eth1 172.16.36.1): icmp mode set, 28 headers + 0 data bytes len=46 ip=172.16.36.1 ttl=64 id=56022 icmp_seq=0 rtt=0.4 ms HPING 172.16.36.4 (eth1 172.16.36.4): icmp mode set, 28 headers + 0 data bytes
While this attempt was not completely successful as the output was not totally redirected to the file, we can see by reading the file that enough is output to create an effective script. Specifically, we are able to redirect a unique line that is only associated with successful ping attempts and that contains the corresponding IP address in the line. To verify that this workaround might be possible, we will attempt to loop through each of the addresses in the /24
range and then pass the results to the handle.txt
file:
root@KaliLinux:~# for addr in $(seq 1 254); do hping3 172.16.36.$addr --icmp -c 1 >> handle.txt & done --- 172.16.36.2 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 6.6/6.6/6.6 ms --- 172.16.36.1 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 55.2/55.2/55.2 ms --- 172.16.36.8 hping statistic --- 1 packets transmitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms *** {TRUNCATED} ***
By doing this, there is still a large amount of output (the provided output is truncated for convenience) that consists of all the parts of output that were not redirected to the file. However, the success of the following script is not contingent upon the excessive output of this initial loop, but rather on the ability to extract the necessary information from the output file:
root@KaliLinux:~# ls Desktop handle.txt pinger.sh root@KaliLinux:~# grep len handle.txt len=46 ip=172.16.36.2 ttl=128 id=7537 icmp_seq=0 rtt=6.6 ms len=46 ip=172.16.36.1 ttl=64 id=56312 icmp_seq=0 rtt=55.2 ms len=46 ip=172.16.36.132 ttl=64 id=47801 icmp_seq=0 rtt=27.3 ms len=46 ip=172.16.36.135 ttl=64 id=62601 icmp_seq=0 rtt=77.9 ms
After completing the scan loop, the output file can be identified in the current directory using the ls
command, and then the unique string of len
can be grepped directly from this file. Here, in the output, we can see that each of our live hosts is listed. At this point, the only remaining task is to extract the IP addresses from this output and then recreate this entire process as a single functional script. Have a look at the following set of commands:
root@KaliLinux:~# grep len handle.txt len=46 ip=172.16.36.2 ttl=128 id=7537 icmp_seq=0 rtt=6.6 ms len=46 ip=172.16.36.1 ttl=64 id=56312 icmp_seq=0 rtt=55.2 ms len=46 ip=172.16.36.132 ttl=64 id=47801 icmp_seq=0 rtt=27.3 ms len=46 ip=172.16.36.135 ttl=64 id=62601 icmp_seq=0 rtt=77.9 ms root@KaliLinux:~# grep len handle.txt | cut -d " " -f 2 ip=172.16.36.2 ip=172.16.36.1 ip=172.16.36.132 ip=172.16.36.135 root@KaliLinux:~# grep len handle.txt | cut -d " " -f 2 | cut -d "=" -f 2 172.16.36.2 172.16.36.1 172.16.36.132 172.16.36.135
By piping over the output to a series of cut
functions, we can extract the IP addresses from the output. Now that we have successfully identified a way to scan multiple hosts and easily identify the results, we should integrate it into a script. An example of a functional script that would tie all of these operations together is as follows:
#!/bin/bash if [ "$#" -ne 1 ]; then echo "Usage - ./ping_sweep.sh [/24 network address]" echo "Example - ./ping_sweep.sh 172.16.36.0" echo "Example will perform an ICMP ping sweep of the 172.16.36.0/24 network and output to an output.txt file" exit fi prefix=$(echo $1 | cut -d '.' -f 1-3) for addr in $(seq 1 254); do hping3 $prefix.$addr --icmp -c 1 >> handle.txt; done grep len handle.txt | cut -d " " -f 2 | cut -d "=" -f 2 >> output.txt rm handle.txt
In the bash script that is provided, the first line defines the location of the bash interpreter. The block of code that follows performs a test to determine whether the one argument that was expected was supplied. This is determined by evaluating whether the number of supplied arguments is not equal to 1
. If the expected argument is not supplied, the usage of the script is output, and the script exits. The usage output indicates that the script is expecting the /24
network address as an argument. The next line of code extracts the network prefix from the supplied network address. For example, if the network address supplied was 192.168.11.0
, the prefix
variable would be assigned the value, 192.168.11
. The hping3 operation is then performed on each address within the /24
range, and the resulting output of each task is placed into the handle.txt
file.
Once completed, grep
is used to extract the lines that are associated with live host responses from the handle file and then extract the IP addresses from those lines. The resulting IP addresses are then passed into an output.txt
file, and the temporary handle.txt
file is removed from the directory. This script can be executed using a period and forward slash, followed by the name of the executable script:
root@KaliLinux:~# ./ping_sweep.sh Usage - ./ping_sweep.sh [/24 network address] Example - ./ping_sweep.sh 172.16.36.0 Example will perform an ICMP ping sweep of the 172.16.36.0/24 network and output to an output.txt file root@KaliLinux:~# ./ping_sweep.sh 172.16.36.0 --- 172.16.36.1 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.4/0.4/0.4 ms --- 172.16.36.2 hping statistic --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.5/0.5/0.5 ms --- 172.16.36.3 hping statistic --- 1 packets transmitted, 0 packets received, 100% packet loss round-trip min/avg/max = 0.0/0.0/0.0 ms *** {TRUNCATED} ***
Once completed, the script should return an output.txt
file to the execution directory. This can be verified using ls
, and the cat
command can be used to view the contents of this file:
root@KaliLinux:~# ls output.txt output.txt root@KaliLinux:~# cat output.txt 172.16.36.1 172.16.36.2 172.16.36.132 172.16.36.135 172.16.36.253
When the script is run, you will still see the same large amount of output that was seen when originally looping through the task. Fortunately, your list of discovered hosts will not be lost in this output, as it is conveniently written to your output file each time.
How it works…
Some modification is required to use hping3 to perform host discovery against multiple hosts or a range of addresses. In the recipe provided, a bash script was used to perform an ICMP echo request in sequence. This was possible due to the unique response that was generated by a successful and nonsuccessful request. By passing the function through a loop and the grepping for the unique response, we could effectively develop a script that performs ICMP discovery against multiple systems in sequence and then outputs a list of live hosts.