Tcpdump – analyze your packets

packet sniffing and analysis with tcpdump

tcpdump is a powerful tool that can help detect and analyze network traffic. The command line usage is very simple and allow to use grep and other terminal utilities for match and discover ethernet packets and flows.
In this tutorial we’ll show some basic examples that allow you to discover the various options the tool offers

installation

install is very simple. Just use yum (or your distro packet manager)

# yum install tcpdump

first….we have to discover the various interfaces we can sniff just type the command tcpdump with -D options

root@raspberrypi:~# tcpdump -D

1.eth0 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.nflog (Linux netfilter log (NFLOG) interface)
5.nfqueue (Linux netfilter queue (NFQUEUE) interface)
6.usbmon1 (USB bus number 1) 

let’s sniff the first 10 packets from our eth0 interface:

# tcpdump -i eth0 -c 10

write our sniff to a pcap file (readable from wireshark too)

# tcpdump -i eth0 -w /home/pi/sniffing.pcap

we can read data from the captured file and look for arp traffic only with

# tcpdump -nn -r sniffing.pcap arp

extract from the capture traffic from and directed to one specific host (-nn means “don’t resolve hostname and port numbers”)

# tcpdump -n -r sniffing.pcap host 192.168.1.200 

extract traffic from a specific network, a specific source ip and a unique destination

# tcpdump -n net 10.0.0.0/8 
# tcpdump src 192.168.1.15
# tcpdump dst 8.8.8.8

is possible to filter src and destination port (port range too)

# tcpdump src port 4444
# tcpdump dst port 80
# tcpdump port 53
# tcpdump portrange 1000-1100

boolean operators

with the use of boolean operators is possible to obtain interesting combination of search options

# tcpdump host 192.168.1.100 and port not 22
# tcpdump src 8.8.8.8 and dst 192.168.1.50
# tcpdump not tcp

is possible to make even more complex searches by combining various options

# tcpdump 'src 192.168.1.100 and (dst port 21 or 25)'

TCP Flags filtering

is possible to make some decision on which flags consider in our sniff. In order to apply correctly this it’s important to have a basic knowledge of the ethernet packet header. Here’s the header format taken from RFC 793

TCP Header Format


    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
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |       |C|E|U|A|P|R|S|F|                               |
   | Offset| Res.  |W|C|R|C|S|S|Y|I|            Window             |
   |       |       |R|E|G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

tcp flags starts from byte 13 (as the image shows), from the CWR (Congestion Window Reduced) and ECE [ECN (Explicit Congestion Notification) flags.

if we want to filter only SYN-ACK packet we have to do this simple operation. Put an ‘1’ in correspondence of every flag we want to consider and convert the value to decimal:

CEUAPRSF
00010010 = 18 (decimal)

so to accomplish this filter request we have to use this option:

# tcpdump 'tcp[13]=18'

if we want to check RST packet? both requests are equivalent

# tcpdump 'tcp[13] & 4!=0'
# tcpdump 'tcp[tcpflags] == tcp-rst'

4 is the value of the ‘r’ flag inside CEUAPRSF so in the previous research we asked for packets at least with r flag active

is possible to use linux terminal tools like grep, cut, awk etc to make more specific researches.

# tcpdump -vvtt | grep 'raspberry' 

the last option is related to packet size. here’s an example:

# tcpdump -i eth0 <= 64 and dst 192.168.1.100
# tcpdump dst 10.0.0.1 or less 32
# tcpdump greater 128 and port not 22 

conclusion

tcpdump can provide information for IT troubleshooting. The syntax is quite human and after some tests you will easily remember the right option that will support you in your daily activities

Port Protection with fail2ban

A public server is scanned and brute forced a lot of times every hour of the day. These are the statistic related to my public and unknown developer test server in the last 24 hours:

Elk stack report of the last 24 hours ssh bruteforce attacks

This could be both a security problem and a system performance issue due to the resources spent in order to manage every connection. Fail2ban is easy to be installed and configured. After different trials of guessing user password the attacker client is automatically inserted in the iptables drop chain for a certain amount of time.

Let’s install epel ( Extra Packages for Enterprise Linux ) and fail2ban service :

yum install epel-release
yum install -y fail2ban fail2ban-systemd

‘Enable’ to make it persistent and start the service

systemctl enable fail2ban
systemctl start fail2ban

if selinux is installed you need to update the policies with:

yum update -y selinux-policy*

The default configuration file is located in /etc/fail2ban directory and it’s called jail.conf.
This file can be modified or restored by package distribution updates so it’s better to create a new file called jail.local and make there our configurations

vim /etc/fail2ban/jail.local

here we can specify some settings like global bantime and other customization. These reported here are the default ones that can fits your installation:

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space (and/or comma) separator.
ignoreip = 127.0.0.1

# "bantime" is the number of seconds that a host is banned.
bantime  = 600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 600

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport
banaction_allports = iptables-allports

can be more complex parameters to be enabled that, for example, can alert you by mail with whois query included. Just explore the configuration file!

# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
            %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

protect sshd

What I prefer is to create a personal and specific fail2ban configuration for every service we expose. Let’s protect our ssh deamon
Copy the jail.conf to /etc/fail2ban/jail.d/sshd.local and edit it:

cp jail.conf /etc/fail2ban/jail.d/sshd.local
vim /etc/fail2ban/jail.d/sshd.local

This configuration and the changes we’ll make here will override the default configuration of jail.local.
This could be a simple configuration

[sshd] 

enabled = true
port = ssh

# this will force the system to use IPTABLES for ban the attacker ip
action = iptables-multiport

maxretry = 5
bantime = 600

# specify a path for the log related to fail2ban events
logpath = %(sshd_log)s

that’s it! restart the service every time you make configuration changes

systemctl restart fail2ban

this is the running configuration for iptables just before activating fail2ban

iptables -L -n                                                                                                                                         
Chain INPUT (policy ACCEPT)                                                                                                                                                     
target     prot opt source               destination                                                                                                                            

Chain FORWARD (policy ACCEPT)                                                                                                                                                    target     prot opt source               destination                                                                                                                             

Chain OUTPUT (policy ACCEPT)                                                                                                                                                     target     prot opt source               destination  

after some minutes this is the situation! we already banned an IP!

# iptables -L -n

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
f2b-default  tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain f2b-default (1 references)
target     prot opt source               destination         
REJECT     all  --  58.242.83.38         0.0.0.0/0            reject-with icmp-port-unreachable
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

how to check how many client were banned

# fail2ban-client status sshd                                                                                                                  

Status for the jail: sshd                                                                                                                                                       |- Filter                                                                                                                                                                       |  |- Currently failed: 1                                                                                                                                                       |  |- Total failed:     54
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions                                                                                                                                                                           
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   58.242.83.38                                                                                                    

great! so now what if we need to unban a client that was wrongly inserted into iptables drop list? it’s simple:

fail2ban-client -h

give us a good help in which we can find a lot of information and configuration regarding fail2ban use. To unban an ip just type

set <JAIL> unbanip <IP>                  manually Unban <IP> in <JAIL>

so in our case it became:

fail2ban-client set sshd unbanip xxx.xxx.xxx.xxx

conclusion

fail2ban is very easy to configure and deploy. Despite this simple installation it can provide a big help to keep your server authentications secure.