Network Fu P1

Network-Fu

Networking is the engineering behind how our computers talks with each other, in this post show how network protocols work, and how you can do network scan.

There is multiple components in computer network, and each machine named after the role it play, firewalls do packet filtering, they range from advance firewalls that do a lot of things, and simple ones that only do packet filtering.

We will look at low-level stuff, so the setup will be simple. Host-base firewall is enough to understand network protocols. Firewalld is a front-end tool for iptables, which is the default firewall in Linux, iptables uses netfilter the network subsystem for Linux.

Firewalld separate the policies by zones. Firewalld Zone

A network or firewall zone defines the trust level of the interface used for a connection. There are several pre-defined zones provided by firewalld. Zone configuration options and generic information about zones are described in firewalld.zone(5)

We will start with ICMP protocol, that well-known for the ping command, i love learn things by doing, so it’s better to setup a lab and do some technical experiments.

Lab setup

server-client architecture need 2 machine, while most of these tasks can be done in 1 machine, it’s better to use 2 machine to separate the role of each one of them. i’m using virtual box to create 2 virtual machine, i love Linux so i have created 2 Ubuntu machines.

Server prerequisite:

  1. Linux with firewalld
  2. TCPdump

Client prerequisite:

  1. Nmap
  2. Python

My server IP is 10.15.10.101 & client IP is 10.15.10.100

Server

install firewalld & tcpdump in ubuntu:

apt install firewalld tcpdump

Centos

dnf install firewalld tcpdump

firewalld setup, assigning the public zone to one of the interfaces, if you are using virtualbox or one of the virtualization software, it’s best to setup internal network between the 2 hosts.

list your interfaces with ip a, and assign the public zone

ip a 
firewall-cmd --change-interface=enp0s8 --zone=public --permanent
firewall-cmd --reload

Then enable logging, there is multiple way to enable logging for firewalld, one by firewalld command, second by editing config file for firewalld

firewalld command to enable logging

firewall-cmd --set-log-denied=all
firewall-cmd --get-log-denied

config file, change LogDenied to be LogDenied=all & reload the service

vim /etc/firewalld/firewall.conf
LogDenied=off
LogDenied=all
systemctl reload firewalld.service

check the zone information & configuration

firewall-cmd --info-zone=public
public
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

ICMP Protocol

at the beginnging of any networking course, you will most likely encouter the OSI model, which descripe the layers of the networkings, starting from physical to application, in this Wikipedia ICMP Page this categorized ICMP as layer 3 along with IP protocol, which is not totally correct, checking the answers in server fault: why is ICMP categorized as a layer 3 protocol ?

there is multiple awesome answers, zoredache answer really explain it well

It is important for you to realize that the Internet does not fit cleaning into the OSI model. In fact RFCs (3439 2.4) mention that they consider layering to be harmful when people try to be too strict about it. ICMP is basically required for IP, so one could argue it belongs as part of IP. ICMP is basically the error notification feature of IP. TCP/UDP uses IP for error messages (port unreachable). PMTU is done by ICMP. So ICMP certainly lower the TCP/UDP. You need to simply accept that in TCP/IP there are no rigid borders between the layers. It only matters that something works.

There is multiple RFC document the ICMP protocol, looking at RFC 792 and learn about the header of ICMP is important to understand how it’s work.

ICMP header :

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |     Code      |          Checksum             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             unused                            |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      Internet Header + 64 bits of Original Data Datagram      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

in the ICMP header packet, there is multiple important parts, Type is used to specify the type of the request, unused here mostly store the content of the packet, this can be used maliciously, as we will look later at ping tunneling. for now lets use our lab to sniff the ping command packets.

Use TCPdump to listen on the interface between the server & client to inspect the packets coming from the clients. to specify certain interface use -i option in TCPdump. and ping the server from the client with ping command.

tcpdump -i enp0s8 

TCPdump identify the packets and label it as ICMP echo request, and capture the server response as echo-reply.

18:31:31.134336 IP 10.15.10.100 > main: ICMP echo request, id 2, seq 1, length 64
18:31:31.134407 IP main > 10.15.10.100: ICMP echo reply, id 2, seq 1, length 64
18:31:32.177554 IP 10.15.10.100 > main: ICMP echo request, id 2, seq 2, length 64
18:31:32.177611 IP main > 10.15.10.100: ICMP echo reply, id 2, seq 2, length 64

echo request & echo reply has different type code in the ICMP packets. from this page in iana.org website ICMP Parameters show each type and it’s name

echo request has type value 8 echo reply has type value 0

ICMP type can be utilized to perform host discovery scan, we will use nmap the most well known network scanning tools.

Nmap Host Discovery Techniques

ICMP Ping Types (-PE, -PP, and -PM)

In addition to the unusual TCP and UDP host discovery types discussed previously, Nmap can send the standard packets sent by the ubiquitous ping program. Nmap sends an ICMP type 8 (echo request) packet to the target IP addresses, expecting a type 0 (echo reply) in return from available hosts. As noted at the beginning of this chapter, many hosts and firewalls now block these packets, rather than responding as required by [RFC 1122](http://www.rfc-editor.org/rfc/rfc1122.txt). For this reason, ICMP-only scans are rarely reliable enough against unknown targets over the Internet. But for system administrators monitoring an internal network, this can be a practical and efficient approach. Use the `-PE` option to enable this echo request behavior.

While echo request is the standard ICMP ping query, Nmap does not stop there. The ICMP standards ([RFC 792](http://www.rfc-editor.org/rfc/rfc792.txt) and [RFC 950](http://www.rfc-editor.org/rfc/rfc950.txt)) also specify timestamp request, information request, and address mask request packets as codes 13, 15, and 17, respectively. While the ostensible purpose for these queries is to learn information such as address masks and current times, they can easily be used for host discovery. Nmap does not currently implement information request packets, as they are not widely supported (RFC 1122 insists that “a host SHOULD NOT implement these messages”). Timestamp and address mask queries can be sent with the `-PP` and -PM options, respectively. A timestamp reply (ICMP code 14) or address mask reply (code 18) discloses that the host is available. These two queries can be valuable when administrators specifically block echo request packets, but forget that other ICMP queries can be used for the same purpose.
IP Protocol Ping (-PO<protocol list>)

The newest host discovery option is the IP protocol ping, which sends IP packets with the specified protocol number set in their IP header. The protocol list takes the same format as do port lists in the previously discussed TCP and UDP host discovery options. If no protocols are specified, the default is to send multiple IP packets for ICMP (protocol 1), IGMP (protocol 2), and IP-in-IP (protocol 4). The default protocols can be configured at compile-time by changing `DEFAULT_PROTO_PROBE_PORT_SPEC` in `nmap.h`. Note that for the ICMP, IGMP, TCP (protocol 6), and UDP (protocol 17), the packets are sent with the proper protocol headers while other protocols are sent with no additional data beyond the IP header (unless the `--data-length` option is specified).

This host discovery method looks for either responses using the same protocol as a probe, or ICMP protocol unreachable messages which signify that the given protocol isn't supported by the destination host. Either type of response signifies that the target host is alive.

For expermintal purpose, we will block echo-request type from our server with firewalld. and check from nmap if we can detect if the server is up or not.

firewalld have 2 way of blocking ICMP, either with whitelisting or blocklisting, you can specify which type to allow, or the other way around, specify which type to block, usually it’s better to only allow the needed type, but since it’s learning expermintal we will only block echo-request, check icmp-block-inversion option in firewalld for whitelisting.

firewall-cmd --zone=public --add-icmp-block=echo-request --permanent
firewall-cmd --reload

Now ping does not work.

Cient

aziz@backbox ~ » ping 10.15.10.101 -c 1               

PING 10.15.10.101 (10.15.10.101) 56(84) bytes of data.
From 10.15.10.101 icmp_seq=1 Packet filtered

--- 10.15.10.101 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

Server

20:03:09.503470 IP 10.15.10.100 > main: ICMP echo request, id 5, seq 1, length 64
20:03:09.503579 IP main > 10.15.10.100: ICMP host main unreachable - admin prohibited filter, length 92

from the server output the ping command show that the packet is filtered

nmap scan ( use -n & -sn to not perform port scan and dns resolve ) check man nmap

since the 2 machine in the same vlan, ARP protocol can detect if the host is up or not. if you use nmap as root, it will send ARP packets. for our purpose, we will not use nmap as root to avoid that. since we intend to only check the host with ICMP.

-PE

nmap -n -sn  -PE 10.15.10.101 
Warning:  You are not root -- using TCP pingscan rather than ICMP
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 20:09 +03
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 0.00 seconds

server response

20:05:47.161385 IP 10.15.10.100.42376 > main.http: Flags [S], seq 1440670760, win 64240, options [mss 1460,sackOK,TS val 3157513925 ecr 0,nop,wscale 7], length 0
20:05:47.161513 IP main > 10.15.10.100: ICMP host main unreachable - admin prohibited filter, length 68

if you run the scan as root, it will perform ARP scan

-PM

nmap -n -sn  -PM 10.15.10.101
Warning:  You are not root -- using TCP pingscan rather than ICMP
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 20:11 +03
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 0.00 seconds

server response

20:11:30.975853 IP 10.15.10.100.46370 > main.http: Flags [S], seq 1134318034, win 64240, options [mss 1460,sackOK,TS val 3157857545 ecr 0,nop,wscale 7], length 0
20:11:30.975970 IP main > 10.15.10.100: ICMP host main unreachable - admin prohibited filter, length 68

-PP

nmap -n -sn  -PP 10.15.10.101    
Warning:  You are not root -- using TCP pingscan rather than ICMP
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-21 20:14 +03
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 0.00 seconds

server response

20:14:17.414434 IP 10.15.10.100.46374 > main.http: Flags [S], seq 2275498320, win 64240, options [mss 1460,sackOK,TS val 3158023934 ecr 0,nop,wscale 7], length 0
20:14:17.414528 IP main > 10.15.10.100: ICMP host main unreachable - admin prohibited filter, length 68

it seem like the 3 commands do the same.

nmap come with it’s own ping implementation nping, but nping have a lot more options.

nping command

# nping --icmp --icmp-type time --delay 500ms 10.15.10.101 -c1

Starting Nping 0.7.80 ( https://nmap.org/nping ) at 2021-05-21 20:35 +03
SENT (0.0720s) ICMP [10.15.10.100 > 10.15.10.101 Timestamp request (type=13/code=0) id=57524 seq=1 orig=0 recv=0 trans=0] IP [ttl=64 id=10514 iplen=40 ]
RCVD (0.0727s) ICMP [10.15.10.101 > 10.15.10.100 Timestamp reply (type=14/code=0) id=57524 seq=1 orig=0 recv=63347344 trans=63347344] IP [ttl=64 id=30982 iplen=40 ]
 
Max rtt: 0.662ms | Min rtt: 0.662ms | Avg rtt: 0.662ms
Raw packets sent: 1 (40B) | Rcvd: 1 (46B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 0.62 seconds

server response

20:35:47.343969 IP 10.15.10.100 > main: ICMP time stamp query id 57524 seq 1, length 20
20:35:47.344056 IP main > 10.15.10.100: ICMP time stamp reply id 57524 seq 1: org 00:00:00.000, recv 17:35:47.344, xmit 17:35:47.344, length 20

since firewalld configured to block only ICMP type echo request, other ICMP types are allowed, ICMP time is mentioned in the nmap ICMP host discovery description.

nping command show that it recived 1 packet, which indicator of host is up.

Ping Flood

this is simple and old technqiue to DOS a server. not so effective today, it’s basically just keep pinging the server, with enough clients it can uses all the server resources. or it can burn the server bandwith.

Monitor the server resources with htop. and run ping -f from the client.

aziz@backbox ~ » sudo ping -f 10.15.10.101                                         
PING 10.15.10.101 (10.15.10.101) 56(84) bytes of data.
EEEEEE........................................................E.........................................................E.........................................................E.........................................................E.............................................................E..............................................................E...........................................................E..........................................................E..........................................................E............................................................E............................................................E..........................................................E.........................................................E..........................................................E.......................................................E........................................................E...........................................................E...........................................................E.........................................................E........................................................E..........................................................E............................................................E...........................................................E..........................................................E...........................................................E...........................................................E...........................................................E...........................................................E...........................................................E...........................................................E..........................................................E...........................................................E...........................................................E..........................................................E............................................................E...........................................................E............................................................E.............................................................E...........................................................E..........................................................E..........................................................E...........................................................E...........................................................E...........................................................E............................................................E...........................................................E............................................^C
--- 10.15.10.101 ping statistics ---
2790 packets transmitted, 0 received, +52 errors, 100% packet loss, time 46736ms

ICMP tunnel

ICMP can be used to exchange messages between two machines. and it been used to leak data from one machine to another.

we will python scapy library to demontrate this. before doing that remove echo request block from the server.

firewall-cmd --remove-icmp-block=echo-request --permanent --zone=public

client code

# import scapy
from scapy.all import *

client = '10.15.10.100'
server = '10.15.10.101'

# user input for the message
message = input('Enter Message -> ') 
# construct the ICMP packet
pinger = IP(dst=server)/ICMP(id=0x0001, seq=0x1)/message
# send the packet
send(pinger)
# sniff for the reply back packet
t = sniff(filter="icmp",iface="enp0s8",count=1)
# convert the byte response to string
data = t[0][Raw].load
message = "".join( chr(x) for x in bytearray(data) )
print("server sent: {0}".format(message) )
print("raw hex dump ")
t.rawhexdump()

server code

# import scapy & time 
import time
from scapy.all import *

client = '10.15.10.100'
server = '10.15.10.101'

# sniff for the echo request packet with defined content
t = sniff(filter="icmp",iface="enp0s8",count=1)
# convert the byte response to string
data  = t[0][Raw].load
message = "".join( chr(x) for x in bytearray(data) )
print(" client sent : {0} ".format(message))
t.rawhexdump()

print("sending echo back")
# sleep for 1 second
time.sleep(1)
response = IP(dst=client)/ICMP(type="echo-reply", id=0x0001, seq=0x1)/data
send(response)

output client ( run with sudo or root for sniffing )

# python3 client.py                                                                   

Enter Message -> hello
.
Sent 1 packets.
server sent: hello
raw hex dump 
0000  08 00 27 65 75 5E 08 00 27 4B 38 53 08 00 45 00  ..'eu^..'K8S..E.
0010  00 21 00 01 00 00 40 01 51 F5 0A 0F 0A 65 0A 0F  .!....@.Q....e..
0020  0A 64 00 00 BC 2B 00 01 00 01 68 65 6C 6C 6F 00  .d...+....hello.
0030  00 00 00 00 00 00 00 00 00 00 00 00              ............

server ( run with sudo or root for sniffing )

# python3 server.py
0000  08 00 27 4B 38 53 08 00 27 65 75 5E 08 00 45 00  ..'K8S..'eu^..E.
0010  00 21 00 01 00 00 40 01 51 F5 0A 0F 0A 64 0A 0F  .!....@.Q....d..
0020  0A 65 08 00 B4 2B 00 01 00 01 68 65 6C 6C 6F 00  .e...+....hello.
0030  00 00 00 00 00 00 00 00 00 00 00 00              ............
 client sent : hello 
.
Sent 1 packets.
Reference
  1. https://nmap.org/book/nping-man-icmp-mode.html#nping-man-icmp-types
  2. https://man.archlinux.org/man/firewalld.1
  3. https://man.archlinux.org/man/nmap.1
  4. https://nmap.org/book/host-discovery-techniques.html
  5. https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
  6. https://datatracker.ietf.org/doc/html/rfc792
  7. https://www.cs.uit.no/~daniels/PingTunnel/
  8. https://www.hackepedia.org/?title=Ping
  9. https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml