This article is a part of “Programming with gopacket library”, which mainly focuses on manually constructing data link layer, network layer and transport layer packets to scan the IPv4 IP addresses of the whole network (in the example, mainland China) to see if the corresponding network is reachable. First, we need to know the IP addresses of the entire network. In fact, we can use fping to detect whether these IPs are connected, then we can quickly scan these IPs ourselves based on ICMP to find out which IP addresses are active on the entire network, and finally we can use tcp scan to scan the IPs of the entire network, and you can even scan the exposed Redis instances on the public network.
Please do not use the techniques presented in this article to do anything illegal. This article only shares the underlying (advanced) programming techniques of the network, not the business logic of the company, and does not involve any hacking.
Get the IP address of the whole public network
The global IP address block is assigned by IANA (Internet Assigned Numbers Authority) to the five major regional IP address allocation authorities around the world, which are listed below.
- ARIN (American Registry for Internet Numbers) This organization is currently responsible for the assignment of IP addresses in North America. It is also responsible for assigning addresses to NSPs (Network Service Providers) worldwide.
- RIPE (Reseaux IP Europeens) At present, this organization is mainly responsible for IP address allocation in Europe, the Middle East, Central Asia and other regions.
- APNIC (Asia Pacific Network Information Center) This organization is currently responsible for IP address allocation in Asia and the Pacific region.
- LACNIC (Latin America and the Caribbean Information Center) This organization is currently responsible for IP address assignment in the Latin America and the Caribbean region.
- AFRINIC (African Network Information Centre) This organization is currently responsible for IP address assignment in the Africa region.
Some articles say there are also three regional centers, which should be an older term, and now there are five regional centers.
Although this article is about the public IP of the whole network, we still focus on our own public IP, which is the IP address assigned by APNIC. China Mobile, China Unicom, China Telecom and the former China Tietong, China Weitong, China Netcom and Education Network have all applied for a large number of network addresses, including a large number of IP addresses accumulated in the hands of cloud service providers such as Ali, Tencent, Baidu and Huawei.
These five regional centers provide a list of their assigned IP address ends and autonomous systems, and are publicly available, which you can obtain using the connection below.
|
|
The most relevant to us are the addresses assigned by APNIC in Asia Pacific region.
By filtering, we can get the IP addresses assigned to mainland China.
This ipv4.txt file contains the IP network segment 1 assigned to mainland China.
Now that we have all the IP addresses on the public network ready, the next step is to detect whether these IP addresses are alive or not. Because it is impossible to use all the IP addresses applied for, and even the IPs used may be offline or blocked, so not all IPs may be connected, and our example in this article is to find out these alive IPs quickly.
Bulk scan with fping
The most common tool we use to check whether a host is alive or not is ping.
A ping is a network tool used to test whether packets can reach a particular host over the IP protocol. ping works by sending an ICMP request echo packet to the target host and waiting to receive an echo response packet. The program estimates the rate of lost packets (packet loss rate) and the packet round-trip time (network latency) in terms of time and number of successful responses.
In December 1983, Mike Muuss wrote the first such program to facilitate the investigation of the root cause of IP network problems when they occurred. Because the program operated similarly to the active sonar of a submarine, he named it after the sound of sonar.
When we want to know whether a host is alive or not, we often say “ping its IP address and see if we can ping it”.
Linux’s ping tool supports the use of UDP or TCP for probing live, in addition to the ICMP protocol, because most network programs use the UDP and TCP protocols, so the use of these two protocols is more in line with the business network protocols, after all, network devices are likely not to handle ICMP and TCP/UDP the same way, for example, TCP program switches can Hash to select the next-hop port based on a five-tuple.
Although the ping tool is suitable for detecting hosts alive, it can only detect one target IP at a time, in our scenario in this paper, we want to detect very many Ip addresses, and detecting them one by one would take a huge amount of time, so we will use another tool: fping.
fping is similar to a ping operation, but with much better performance when pinging multiple hosts. fping has a very long history: Roland Schemers released its first version in 1992, and since then it has become the standard network diagnostic and statistical tool.
Here is a scan of the 8.8.8.8/24
network segment.
Based on the fping function, we can probe each line of the ipv4.txt file segment by segment and output the probe results.
|
|
First we get all the assigned IP address segments of the continent through a script and store them in the ipv4.txt file. Each line in this file contains one IP address segment, and we use bufio.Scanner
to scan it line by line. Every time we get an address segment, we call the fping function to process it.
|
|
Here we use exec.Command
to call the fping command and scan one segment at a time, if the IP address is timeout or not working, we ignore it and print out only the surviving IP addresses.
Implementing ICMP scanning by ourselves
Although using fping has better performance than ping for multi-host probing, it still does not meet our needs. We want to continuously scan the entire network for IP address survivability, so this time we have to write our own program.
We can use the same probing protocol as ping and fping, send ICMP probe packets, if there is an ICMP Reply back, we think the network is through.
We use manual construction of data link layer frames to construct this sent data from the bottom.
Data link layer needs to set the mac address, the local host address we can get out (although there may be more than one NIC, but we have to pick out the actual route to use the Mac address of that NIC), according to the way the network is processed, we do not need to know the Mac address of the target address, just fill in the Mac address of our gateway, the gateway will propagate the probe packet through the routing protocol The gateway will propagate the probe packet out through the routing protocol and finally reach the target address, or it will be dropped in the middle. (If pinging a host on the same LAN, you need to fill in the Mac address of the target host, not the Mac address of the gateway)
Data link layer needs to set the mac address, the local host address we can get (although there may be more than one NIC, but we have to pick the actual route to use the Mac address of that NIC), according to the way the network is processed, we do not need to know the Mac address of the target address, just fill in the Mac address of our gateway, the gateway will propagate the probe packet through the routing protocol The gateway will propagate the probe packet out through the routing protocol and finally reach the target address, or it will be dropped in the middle. (If pinging a host on the same LAN, you need to fill in the Mac address of the target host, not the Mac address of the gateway)
So the first step is that we need to find out the local and gateway Mac address. The protocol to find this address is arp protocol and we need to construct arp packet and process the return result of arp.
|
|
To construct these underlying network packets (frames), we commonly use the gopacket library, and use it to send and receive packets.
The function above starts by constructing the contents of layers.Ethernet
and layers.ARP
, then calls sendPackets
to send them out, and then calls s.handle.ReadPacketData()
to read the arp return, which contains the gateway’s Mac address.
In fact, we define a Scanner
that facilitates us to handle the whole logic. When this Scanner
is initialized, the local IP address, local Mac address, and gateway Mac address used for probing are prepared.
|
|
Here is a trick, generally servers may have multiple NICs and more Ip addresses, so which NIC and local IP address to use when probing? You can use router.Route
to get the local NIC, gateway, local IP, etc. used to access the public network. In this example, we visit the well-known 114.114.114.114
public network address as the target address, save this information for backup, then call getHwAddr
to get the Mac address of the gateway.
gopacket
opens a device for reading and writing network data via pcap.OpenLive
, and we have all this ready when we create Scanner
.
Now everything is ready, we just need to pass the destination IP to be probed to it and let it do the probing. Here we implement a Scan
method.
|
|
input
is a channel, into which the user can pass the target IP to be probed. It will return an output
channel, which contains the active target IPs.
Then the whole logic is clear: start a goroutine to send ICMP packets, start a goroutine to receive ICMP, there is no blocking between the two, and the performance is naturally very good.
|
|
Sending data constructs layers.Ethernet
, layers.IPv4
, layers.ICMPv4
packets, each ICMPv4 packet probes a destination IP, which is only responsible for sending.
|
|
The receiving logic has a trick, it filters the packet in the kernel state by BPFFilter, and the value concerns our ICMP return packet. The format is the same as in the tcpdump tool.
After it reads the ICMP packet, it writes the target address to output
.
Basically, using less than one CPU resource, in about one and a half hours all the public IPs on the mainland were probed.
Implement your own TCP scan and find the exposed Redis port IP address
Well, the above technique is good and can quickly scan the whole network for public addresses, but we want to go a step further and use TCP to scan the whole network for public IPs, and we scan specific -ports in order to see if a service is exposed on the public IP. This kind of scanning is often done by security companies, but this time we implemented it manually.
This time we scan port 6379, which is the default port for redis. Although having this port open on the server does not mean that Redis services are deployed, it is very likely that they are. For security reasons, these exposed Redis services should be set to AUTH, and should even be set to allow specific IP access through the firewall.
With the TCP approach to probing, we use the first two steps of the three handshakes: first send a syn packet, and the other side may return a sync+ack packet (if the port is open) or an rst packet (if the port is not open, or if the connection is denied), or nothing is returned. We will only focus on the first two.
In fact, the code logic and the above ICMP program is almost too much, get the gateway Mac address and other ways and the above and the example is not much different. We still define a Scanner
type, but with more information about the local port and remote port.
|
|
We want to collect the IP addresses that can be connected but the port is not open, and the IP addresses where the port is open, so the Scan
method has been fine-tuned to support the output of both lists.
|
|
When sending data we have to construct TCP syn packets.
|
|
When receiving data, we distinguish between TCP+ACK packets and RST packets.
|
|
The code structure is not very different from ICMP probing.
With the help of gopacket (libpcap) library, we can easily and efficiently implement a network-wide public IP scan, which is very meaningful for network probing and security checking. According to the above example, you can also easily implement the UDP method of detection, you may also want to practice.
Ref
https://colobu.com/2023/03/19/scan-all-IP-addresses-of-mainland-fastly-like-lightning/