13. Security topics. Part 2: network security.¶
Network ssh brute force attacks
TCP wrappers
Stack overflow vulnerabilities
Package upgrade and verification
Network ports
Iptables
Open port scanning
Vulnerability scanning
13.1. SSH brute force attacks (Exercise)¶
On the desktop, download ncrack
:
wget https://github.com/nmap/ncrack/archive/master.zip
Install g++
, and libssl-dev
package, then compile and install ncrack by following the commands below:
unzip master.zip
cd ncrack-master/
./configure
make
sudo make install
Install crunch
package on the desktop, which is needed for generating a password dictionary.
apt install crunch
Deploy a new VM, testub
, by cloning kvm1.
Deploy a new VM, testcent
, by cloning CentOS7
.
Make the both host names resolvable by creating their entries in /etc/hosts
file on the desktop.
On the both VMs, create user account jerry. Assign password jerry1 to user jerry. If the password PAM module doesn’t allow you setting a such simple password, use command mkpasswd
and enter the hash manually into /etc/shadow
. Check if user jerry can login to the VM.
On the desktop, generate a password table, passwords.txt
, by running crunch
:
crunch 5 6 jerry123 -o passwords.txt
Run SSH bruteforce attacks onto account jerry on the both VMs:
ncrack -vv --user jerry -P passwords.txt testub:22
ncrack -vv --user jerry -P passwords.txt testcent:22
Within a few minutes, ncrack should be able to identify the correct password for user jerry from passwords.txt
list.
13.2. Identifying SSH login attacks in the system logs (Exercise)¶
On testub VM, check the lines in log file auth.log
and see ssh login attempts to user account jerry
:
grep jerry /var/log/auth.log | grep auth
See the successfull attempt to login:
grep jerry /var/log/auth.log | grep -E -v '(error|[Ff]ail)'
On testcent VM, check the lines in log file secure and see ssh login attempts to user account jerry
:
grep jerry /var/log/secure | grep auth
See the successfull attempt to login:
grep jerry /var/log/secure | grep -E -v '(error|[Ff]ail)'
13.3. TCP Wrappers¶
Access to inetd startable services can be controlled through daemon tcpd; it reads the access rules from files /etc/hosts.allow
and /etc/hosts.deny
. Similarly, the access can be controlled for the other services, such as portmap, if they have been compiled with libwrap libraries.
Format of /etc/hosts.allow and /etc/hosts.deny
:
service_list: host_list
/etc/hosts.allow
– is checked first by tcpd: if the entries match, the host is allowed to access the service, otherwise, /etc/hosts.deny
is checked – if the entries match, the access is denied. If non of the entries match, or both the files are empty, the access is allowed.
Keywords: ALL
(matches all requests), EXCEPT
, LOCAL
(hosts matching the local network - no domain), KNOWN
(resolvable hosts), PARANOID
(hostname doesn’t match IP), UNKNOWN
(unresolvable hosts).
Example:
etc/hosts.allow:
sshd: 165.230.172.13 128.6.
in.tftpd: LOCAL, .my.domain
in.rlogind: 128.6.14.216
in.rshd: 128.6.14.216 128.6.14.211
portmap: 128.6.14.0/255.255.255.128
ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
/etc/hosts.deny:
ALL: ALL
13.4. ssh protection with TCP Wrappers (Exercise).¶
Login to the console of testub
VM:
virsh console testub
Become root
sudo -s
Edit file /etc/hosts.deny
and add the following entry:
/etc/hosts.deny
ALL: ALL
Try SSH to testub from your desktop.
ssh 192.168.122.42
The SSH attempt should fail.
Edit file /etc/hosts.allow
and add the following entry:
/etc/hosts.allow
sshd: 192.168.122.
Try to SSH to smbhost from the desktop again.
13.5. Denyhosts (Exercise)¶
DenyHosts is a log-based intrusion prevention security tool for SSH servers written in Python. It is designed to prevent brute-force attacks on SSH servers by monitoring invalid login attempts in the authentication log and blocking the originating IP addresses using /etc/hosts.deny
and iptables
on Linux server.
On testub
VM, clear the logs, /etc/hosts.allow
, and /etc/hosts.deny
:
cp /dev/null /var/log/auth.log
cp /dev/null /etc/hosts.allow
cp /dev/null /etc/hosts.deny
On testub VM, install denyhosts
service:
apt-get install denyhosts
Edit file /etc/denyhosts.conf
and comment the line with iptables
/etc/denyhosts.conf
#IPTABLES = /sbin/iptables
Restart denyhosts:
systemctl restart denyhosts
On the desktop, run ncrack
on testub
VM, then check the content of /etc/hosts.deny
. You should see the IP address of the desktop, 192.168.122.1 denied accessing sshd. Try ssh-ing from the desktop to testub
.
13.6. Stack overflow example 1.¶
A buffer overflow is the result of stuffing more data into a buffer than it can handle.
In the example, the program has a function with a typical buffer overflow coding error.
Dangerous functions for stack overflow (don’t check the string boundaries): strcat(), strcpy(), sprintf(), vsprintf(), gets(), scanf()
.
#include <string.h>
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
int main() {
char large_string[256];
int i;
for( i = 0; i < 255; i++)
large_string[i] = 'A';
function(large_string);
}
To exploit such flaw, an attacker would need to give a specially crafted encoded input. It can be done locally by using a rootkit or over a network by sending a packet with improperly advertised lengths.
13.7. Stack overflow example 2.¶
A code prompts for password, reads it from keyboard, and gives the root shell.
#include <stdio.h>
#include <string.h>
int main()
{
int setuid(); //Declare the type of the functions used below
int system();
int gets();
char buff[10]; //Defines the input array buff of 10 Bytes size
int pass = 0;
printf("\n Enter the password : \n");
gets(buff);
if(strcmp(buff, "Password1") != 0)
{
printf ("\n Wrong Password \n");
}
else
{
printf ("\n Correct Password \n");
pass = 1;
}
if(pass != 0)
{
printf ("pass=, %3d", pass); //See how variable 'pass' is corrupted
/* Now Give root or admin rights to user*/
printf ("\n Root privileges given to the user \n");
setuid(0);
system("/bin/bash");
}
return 0;
}
Any given password string, exceeding 11 letters, would corrupt the memory region, containing variable pass, therefore cause the code to give the root shell.
13.8. Stack overflow exercise.¶
On testub
, download the source code and the Makefile:
wget http://linuxcourse.rutgers.edu/lessons/security_remote/Downloads/root_shell.c
wget http://linuxcourse.rutgers.edu/lessons/security_remote/Downloads/Makefile
Compile the source code, and assigne setuid root to the compiled executable:
make
sudo chown root:root root_shell
sudo chmod u+s root_shell
Run the executable:
./root_shell
When prompted for password, type in a long string: RRRRRRRRRRRRRRRRRRRR Notice, you got the root shell.
The way to fix it: use function fgets instead of gets, for example:
//gets(buff);
fgets(buff,sizeof(buff),stdin);
13.9. Package upgrades and md5 checksum verification. (Exercise)¶
On testub
VM, run upgrades on regular bases and every time a new vulnerability discovered in installed packages:
apt-get update
apt-get upgrade
On CentOS, use YUM for updates:
yum update
Verify md5 checksum of downloaded software:
md5sum root_shell.c
On testub
VM, install dlocate
and verify md5
checksum of the files installed with a package:
apt-get install dlocate
dlocate -md5sum tcpd
dlocate -md5check tcpd
On CentOS, testcent
, use rpm -V
command to verify package integrity:
rpm -V tcp_wrappers
13.10. Open Ports List. (Exercise)¶
Install package net-tools
on testcent
VM:
apt install net-tools
To see what ports are open, run command
netstat -nal
and check on TCP and UDP ports in the listing. To see what processes are bound to what ports, run as root
netstat -nalp | less
output:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:515 0.0.0.0:* LISTEN 1742/lpd Waiting
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1726/exim4
tcp 0 0 192.168.1.101:1040 128.6.238.10:22 ESTABLISHED 2229/ssh
tcp 0 0 192.168.1.101:1024 128.6.238.12:993 ESTABLISHED 2195/pine
tcp6 0 0 :::22 :::* LISTEN 1813/sshd
udp 0 0 0.0.0.0:68 0.0.0.0:* 2085/dhclient
Similarly,
netstat -n --inet --listening --programs
Also, the processes responsible for the open ports can be identified with
lsof -i
See example (Links to an external site.).
Syntax of lsof
:
lsof -i [TCP|UDP][@host][:port]
To list all open files for specific processes:
lsof -p PID
lsof -c COMMAND
lsof -u username
To list all open files
lsof
Exercise
SSH to smbhost
VM, become root, and run lsof to see the open internet ports:
ssh 192.168.122.42
sudo -s
lsof -i -P
Note, option “-P” shows you the port number.
You should see the ports opened for the following services: dhclient3, udp/68, sshd, tcp/22
.
If you have installed Samba in the previous class, you should also see the Samba related services with their ports, such as smbd, tcp/137,138,139, tcp/445
, and nmbd, udp/136,138
.
13.11. Closing ports by disabling network services.¶
The open ports are related to the aplications/processes, which start either at the system startup or through inetd/xinetd. For the Systemd aware applications,
systemctl stop service_name
systemctl disable service_name
Vulnerable services:
telnet, rsh, rcp, rexec, ftp, portmap, nfs, mountd, ypbind, ypserv
. Disable them if your computer is on the open Internet. But if you need them, install a firewall and implement the tcp_wrappers.Relatively secure services: Services protected with SSL libraries for encrypted connection such as
SSH, LDAP, Apache; Kerberos
.
13.12. IP filtering firewalls (iptables)¶
Packet filtering is implemented through Linux Kernel.
Chains for network packets:
INPUT
OUTPUT
FORWARD
Chains are combined into tables:
filter (default)
NAT
mangle
Each of the chains filters data packets based on Source and Destination IP Source and Destination Port number Network interface State of the packet Target for the rule:
ACCEPT
DROP
REJECT
QUEUE
RETURN
LOG
13.13. Building iptables rules¶
Set a default policy to drop packets:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
Flush the previous rules:
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
Append rules:
iptables --append (CHAIN) (selection-criteria) --jump (TARGET)
or
iptables -A (CHAIN) (selection-criteria) -j (TARGET)
ACCEPT packets for specified ports, for example, tcp/25:
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 25 -j ACCEPT
ACCEPT packets from specified subnets:
iptables -A INPUT -s 192.168.122.0/24 -j ACCEPT
iptables -A OUTPUT -d 192.168.122.0/24 -j ACCEPT
Stateful inspection for TCP connections:
-m state
--state: INVALID
NEW
ESTABLISHED
RELATED
For example, to allow access to port tcp/80 on Apache web server from subnet 192.168.122.0/24 only:
iptables -A INPUT -m state -p tcp --dport 80 -s 192.168.122.0/24 --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state -p tcp --sport 80 -d 192.168.122.0/24 --state ESTABLISHED,RELATED -j ACCEPT
13.14. Simple iptables script¶
executable script:
#!/bin/bash
IPT=/sbin/iptables
# Flush the tables
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
# Define default policy to DROP packets
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# Permit DNS traffic
$IPT -A INPUT -p udp --sport 53 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -j ACCEPT
# Accept local-network return traffic from private network 192.168.122.0/24:
$IPT -A INPUT -m state -p tcp --dport 1024:65535 --state ESTABLISHED,RELATED -s 192.168.122.0/24 -j ACCEPT
$IPT -A OUTPUT -m state -p tcp --sport 1024:65535 ! --state INVALID -d 192.168.122.0/24 -j ACCEPT
# Accept all HTTP connections
$IPT -A INPUT -m state -p tcp --dport 80 ! --state INVALID -j ACCEPT
$IPT -A OUTPUT -m state -p tcp --sport 80 --state ESTABLISHED,RELATED -j ACCEPT
# Accept local (192.168.122.0/24) SSH traffic
$IPT -A INPUT -m state -p tcp --dport 22 ! --state INVALID -s 192.168.122.0/24 -j ACCEPT
$IPT -A OUTPUT -m state -p tcp --sport 22 --state ESTABLISHED,RELATED -d 192.168.122.0/24 -j ACCEPT
# Accept all local (loopback) traffic on the lo interface
$IPT -A INPUT -s 127.0.0.1 -i lo -j ACCEPT
$IPT -A OUTPUT -d 127.0.0.1 -o lo -j ACCEPT
# Log all other traffic
$IPT -A INPUT -j LOG
$IPT -A OUTPUT -j LOG
To check the current iptables rules, run
/sbin/iptables -n -L
13.15. Configuring iptables firewall (Exercise)¶
Make sure iptables have been installed on testub VM:
dpkg -l | grep iptables
Check the iptables
rules on testub
:
/sbin/iptables -n -L
On testub
, download the iptables script from fw-script.sh
(Links to an external site.), make it executable, then run:
wget http://linuxcourse.rutgers.edu/lessons/security_remote/fw-script.sh
chmod 755 fw-script.sh
./fw-script.sh
Check the iptables rules again,
/sbin/iptables -n -L
You should see the new active rules.
Try pinging your desktop private virtual IP address from testub
:
ping 192.168.122.1
Try pinging testub
VM from the desktop:
ping 192.168.122.42
To enable ping, you need to add the following rules to your fw-script.sh
(you can include them somwhere after the default policy)
# Echo - uncomment to allow your system to be pinged.
$IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 0 -j ACCEPT
$IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 8 -j ACCEPT
$IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 11 -j ACCEPT
$IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 0 -j ACCEPT
$IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 8 -j ACCEPT
$IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 11 -j ACCEPT
After the script is modified, you need to run the script,
Run it:
./fw-script.sh
Try to ssh to some host located outside of the lab, for example, engsoft.rutgers.edu.
Try running apt update
command.
Both SSH and apt would hang up because the iptable rules don’t allow initiating outbound TCP connections with remote hosts and their returm from outside of the local virtual private network, 192.168.122.0/24.
To enable return TCP-connections from the outside of the subnet, change “-s 192.168.122.0/24” and “-d 192.168.122.0/24” for “-s 0/0” and “-d 0/0” in the rules for “Accept local-network return traffic…” in the script. The new rules should look as follows:
After the script is modified, you need to run the script,
./fw-script.sh
Try ssh to the host and apt command again. They should run fine.
13.16. fail2ban (Exercise)¶
Fail2ban is a software that scans log files for brute force login attempts in real-time and bans the attackers with iptables. This program works in the background and continuously scans the log files for unusual login patterns and security breach attempts.
Fail2ban
is similar to DenyHosts, however unlike DenyHosts which focuses on SSH, fail2ban can be configured to monitor any service that writes login attempts to a log file, and instead of using /etc/hosts
. deny only to block IP addresses/hosts, fail2ban
can use iptables
.
Fail2ban
installation on Ubuntu VM, testub
.
First, flush the active iptables rules:
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
Install fail2ban package:
apt install fail2ban
Backup the default configuration file
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Create a new configuration file, /etc/fail2ban/jail.d/sshd.local
, with the following content:
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
bantime = 86400
Restart fail2ban:
systemctl restart fail2ban
Check the active fail2ban status:
fail2ban-client status
Tru ssh to testub from the other VM and use incorrect password 5 times. Check the iptables settings on testub:
iptables -nL
Remove the banned IP address from the iptables, for example:
fail2ban-client set sshd unbanip 192.168.122.79
13.17. Port scanning (Exercise)¶
After unnecessary ports are closed and firewall implemented, the system should be scanned from a remote host with NMAP. To scan the TCP ports, for example on 192.168.5.42:
nmap -sT -O 192.168.5.42
ouput:
The output may look like the following:
Starting nmap ( http://www.insecure.org/nmap/ ) at 2021-04-05 20:56 EDT
Interesting ports on node18.linux.class (192.168.5.42):
(The 1653 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
513/tcp open login
514/tcp open shell
919/tcp open unknown
953/tcp open rndc
2049/tcp open nfs
32772/tcp open sometimes-rpc7
MAC Address: 00:10:5A:0A:B3:E8 (3com)
Device type: general purpose
Running: Linux 2.4.X|2.5.X|2.6.X
OS details: Linux 2.4.18 - 2.6.7
Uptime 8.143 days (since Mon Mar 28 16:30:58 2021)
To scan the UDP ports, for example on 192.168.5.42:
nmap -sU -v 192.168.5.42
Nessus is an extension of NMAP; it provides vulnerability details and security advises.
Exercise.
Scan the TCP ports on testub from your desktop:
nmap -sT -O 192.168.122.42
Scan the UDP ports on testub from your desktop:
nmap -sU -v 192.168.122.42
13.18. Vulnerability scanning (Exercise)¶
In the browser on your desktop, navigate to Nessus and click onto Nessus Essentials, free download.
Create an account for yourself on the Nessus page.
Download the Nessus deb package for your Ubuntu distribution, 64-bit, from the download page, for example Nessus-8.15.0-ubuntu1110_amd64.deb. Install the package and start Nessus service:
dpkg -i Nessus-8.15.0-ubuntu1110_amd64.deb
/etc/init.d/nessusd start
In the browser, login to the Nessus admin page, https://localhost:8834, with the credentials you’ve created during the registration stage.
Wait until the installation finishes, then use “Advanced scan” to scan the ports on smbhost (use the IP address) for vulnerabilities.
Start Win10 VM, and scan the ports on Win10 for vulnerabilities from Nessus.