Autor: Justin Hutchens
Broj strana: 452
ISBN broj: 9781783982141
Izdavač: PACKT PUBLISHING
Godina izdanja: 2015.
"Kali Linux Network Scanning Cookbook" is intended for information security professionals and casual security enthusiasts alike. It will provide the foundational principles for the novice reader but will also introduce scripting techniques and in-depth analysis for the more advanced audience. Whether you are brand new to Kali Linux or a seasoned veteran, this book will aid in both understanding and ultimately mastering many of the most powerful and useful scanning techniques in the industry. It is assumed that the reader has some basic security testing experience.
Kali Linux Network Scanning Cookbook will introduce you to critical scanning concepts. You will be shown techniques associated with a wide range of network scanning tasks that include discovery scanning, port scanning, service enumeration, operating system identification, vulnerability mapping, and validation of identified findings. You will learn how to utilize the arsenal of tools available in Kali Linux to conquer any network environment. You will also be shown how to identify remote services, how to assess security risks, and how various attacks are performed. This immersive guide will also encourage the creation of personally scripted tools and the development of skills required to create them.
Scapyis a tool that can be used to craft and inject custom packets into a network. In this specific recipe, Scapy will be used to scan for active UDP services. This can be done by sending an empty UDP packet to destination ports and then identifying the ports that do not respond with an ICMP port-unreachable response.
To use Scapy to perform UDP scanning, you will need to have a remote system that is running network services over UDP. In the examples provided, an instance of Metasploitable2 is used to perform this task. Additionally, this section will require a script to be written to the filesystem using a text editor, such as VIM or Nano.
Using Scapy, we can quickly develop an understanding of the underlying principles behind how UDP scanning works. To positively confirm the existence of a UDP service on any given port, we will need to solicit a reply from that service. This can prove to be very difficult, as many UDP services will only reply to service-specific requests. Knowledge of any particular service can make it easier to positively identify that service; however, there are general techniques that can be used to determine, with a reasonable amount of accuracy, whether a service is running on a given UDP port. The technique that we will use with Scapy is to identify closed UDP ports with ICMP port-unreachable replies. To send a UDP request to any given port, we first need to build layers of that request. The first layer that we will need to construct is the IP layer:
root@KaliLinux:~# scapy Welcome to Scapy (2.2.0) >>> i = IP() >>> i.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= ip chksum= None src= 127.0.0.1 dst= 127.0.0.1 \options\ >>> i.dst = "172.16.36.135" >>> i.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= ip chksum= None src= 172.16.36.180 dst= 172.16.36.135 \options\
To build the IP layer of our request, we need to assign the IP object to the variable i. By calling the display function, we can identify the attribute configurations for the object. By default, both the sending and receiving addresses are set to the loopback address, 127.0.0.1. These values can be modified by changing the destination address, by setting i.dst to be equal to the string value of the address that we wish to scan. On calling the display function again, we see that not only has the destination address been updated, but Scapy also automatically updates the source IP address to the address associated with the default interface. Now that we have constructed the IP layer of the request, we can proceed to the UDP layer:
>>> u = UDP() >>> u.display() ###[ UDP ]### sport= domain dport= domain len= None chksum= None >>> u.dport 53
To build the UDP layer of our request, we use the same technique that we used for the IP layer. In the example provided, the UDP object was assigned to the u variable. As mentioned previously, the default configurations can be identified by calling the display function. Here, we can see that the default value for both the source and destination ports are listed as domain. As you might likely suspect, this is to indicate the Domain Name System (DNS) service associated with port 53. DNS is a common service that can often be discovered on networked systems. To confirm this, one can call the value directly by referencing the variable name and attribute. This can then be modified by setting the attribute equal to the new port destination value as follows:
>>> u.dport = 123 >>> u.display() ###[ UDP ]### sport= domain dport= ntp len= None chksum= None
In the preceding example, the destination port is set to 123, which is the Network Time Protocol (NTP) port. Now that we have created both the IP and UDP layers, we need to construct the request by stacking these layers:
>>> request = (i/u) >>> request.display() ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= udp chksum= None src= 172.16.36.180 dst= 172.16.36.135 \options\ ###[ UDP ]### sport= domain dport= ntp len= None chksum= None
We can stack the IP and UDP layers by separating the variables with a forward slash. These layers can then be set equal to a new variable that will represent the entire request. We can then call the display function to view the configurations for the request. Once the request has been built, it can be passed to the sr1 function so that we can analyze the response:
>>> response = sr1(request) Begin emission: ......Finished to send 1 packets. ....* Received 11 packets, got 1 answers, remaining 0 packets >>> response.display() ###[ IP ]### version= 4L ihl= 5L tos= 0xc0 len= 56 id= 63687 flags= frag= 0L ttl= 64 proto= icmp chksum= 0xdfe1 src= 172.16.36.135 dst= 172.16.36.180 \options\ ###[ ICMP ]### type= dest-unreach code= port-unreachable chksum= 0x9e72 unused= 0 ###[ IP in ICMP ]### version= 4L ihl= 5L tos= 0x0 len= 28 id= 1 flags= frag= 0L ttl= 64 proto= udp chksum= 0xd974 src= 172.16.36.180 dst= 172.16.36.135 \options\ ###[ UDP in ICMP ]### sport= domain dport= ntp len= 8 chksum= 0x5dd2
This same request can be performed without independently building and stacking each layer. Instead, we can use a single, one-line command by calling the functions directly and passing them the appropriate arguments as follows:
>>> sr1(IP(dst="172.16.36.135")/UDP(dport=123)) ..Begin emission: ...*Finished to send 1 packets. Received 6 packets, got 1 answers, remaining 0 packets >>>
Note that the response for these requests includes an ICMP packet that has type indicating that the host is unreachable and code indicating that the port is unreachable. This response is commonly returned if the UDP port is closed. Now, we should attempt to modify the request so that it is sent to a destination port that corresponds to an actual service on the remote system. To do this, we change the destination port back to port 53 and then send the request again, as follows:
>>> response = sr1(IP(dst="172.16.36.135")/UDP(dport=53),timeout=1,verbose=1) Begin emission: Finished to send 1 packets. Received 8 packets, got 0 answers, remaining 1 packets
When the same request is sent to an actual service, no reply is received. This is because the DNS service running on the system's UDP port 53 will only respond to service-specific requests. Knowledge of this discrepancy can be used to scan for ICMP host-unreachable replies, and we can then identify potential services by flagging the nonresponsive ports:
#!/usr/bin/python import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) from scapy.all import * import time import sys if len(sys.argv) != 4: print "Usage - ./udp_scan.py [Target-IP] [First Port] [Last Port]" print "Example - ./udp_scan.py 10.0.0.5 1 100" print "Example will UDP port scan ports 1 through 100 on 10.0.0.5" sys.exit() ip = sys.argv start = int(sys.argv) end = int(sys.argv) for port in range(start,end): ans = sr1(IP(dst=ip)/UDP(dport=port),timeout=5,verbose=0) time.sleep(1) if ans == None: print port else: pass
The provided Python script sends a UDP request to each of the first hundred ports in sequence. In the case that no response is received, the port is identified as being open. By running this script, we can identify all of the ports that don't return an ICMP host-unreachable reply:
root@KaliLinux:~# chmod 777 udp_scan.py root@KaliLinux:~# ./udp_scan.py Usage - ./udp_scan.py [Target-IP] [First Port] [Last Port] Example - ./udp_scan.py 10.0.0.5 1 100 Example will UDP port scan ports 1 through 100 on 10.0.0.5 root@KaliLinux:~ # ./udp_scan.py 172.16.36.135 1 100 53 68 69
A timeout of 5 seconds is used to adjust for latent responses that result from ICMP hostunreachable rate limiting. Even with this rather large response acceptance window, scanning in this fashion can still be unreliable at times. It is for this reason that UDP probing scans are often a more effective alternative.
In this recipe, UDP scanning is performed by identifying the ports that do not respond with ICMP port-unreachable responses. This process can be highly time consuming as ICMP port-unreachable responses are often throttled. It can also, at times, be an unreliable approach as some systems do not generate these responses, and ICMP is often filtered by firewalls. An alternative approach is to use service-specific probes that attempt to solicit a positive response.
Justin Hutchens currently works as a security consultant and regularly performs penetration tests and security assessments for a wide range of clients. He previously served in the United States Air Force where he worked as an intrusion detection specialist, network vulnerability analyst and malware forensic investigator for a large enterprise network with over 55,000 networked systems. He currently holds a Bachelor’s degree in Information Technology and multiple professional information security certifications, to include CISSP (Certified Information Systems Security Professional), OSCP (Offensive Security Certified Professional), eWPT (eLearnSecurity Web-Application Penetration Tester), GCIH (GIAC Certified Incident Handler), CNDA (Certified Network Defense Architect), CEH (Certified Ethical Hacker), ECSA (EC-Council Certified Security Analyst) and CHFI (Computer Hacking Forensic Investigator). He was also the writer and producer of the Packt eLearning video course “Kali Linux - Backtrack Evolved”.
© Sva prava pridržana, Kompjuter biblioteka, Beograd, Obalskih radnika 4a, Telefon: +381 11 252 0 272