{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5bb33f6",
   "metadata": {},
   "source": [
    "## Security topics"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e667273",
   "metadata": {},
   "source": [
    "- Vectors of attack review\n",
    "- Passwords and encryption types\n",
    "- Password cracking exercise\n",
    "- Network ssh brute force attacks\n",
    "- Network ports\n",
    "- Traffic sniffing with tcpdump\n",
    "- Iptables\n",
    "- Open port scanning\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc5fe2a6",
   "metadata": {},
   "source": [
    "## Examples of how systems get compromised.\n",
    "\n",
    "\n",
    "![How systems get compromized](img/system_compromise.gif)\n",
    "\n",
    "\n",
    "- Cracked, stollen and sniffed passwords\n",
    "- SSH client with a sniffer on a multi-user system: reads user name, password and the destination host.\n",
    "- SSH brute force attack guesses user credentials.\n",
    "- Accounts with empty passwords and root privileges\n",
    "- World writable files and directories can be used for planting trojans.\n",
    "- SETUID and SETGID executables\n",
    "- Trojans \n",
    "- Stack overflow attacks on vulnerable services\n",
    "- Worms\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4df80187",
   "metadata": {},
   "source": [
    "## Linux passwords.\n",
    "\n",
    "\n",
    "On a local system, passwords are stored in file `/etc/shadow`:\n",
    "\n",
    "\n",
    "`mike:$6$A0NKorlZ$l3YhLlm/Y1n2BW0YBiryNl5cS6vx5k.4j4LE/vb5FUOnD.uVXkiUA1kPSHLo5/6q5MzEJTal1OY1OiE4ReSpK0:17317:0:99999:7:::`\n",
    "\n",
    "The second field consits of 3 parts: the hashing algorithm, $6$, the salt $A0NKorlZ$, and the hashing function, crypt, value of (password,salt) parameters, \n",
    "\n",
    "`l3YhLlm/Y1n2BW0YBiryNl5cS6vx5k.4j4LE/vb5FUOnD.uVXkiUA1kPSHLo5/6q5MzEJTal1OY1OiE4ReSpK0`\n",
    "\n",
    "The password hash is generated by function crypt. From the output of man crypt we see the hash structure components:\n",
    "\n",
    "`$id$salt$encrypted`\n",
    "\n",
    "           The following values of id are supported:\n",
    "\n",
    "           ID(prefix) | Method\n",
    "           ------------------------------------------------------------\n",
    "                  1   | MD5\n",
    "                  2a  | Blowfish (not in mainline glibc; added in some\n",
    "                      | Linux distributions)\n",
    "                  5   | SHA-256 (since glibc 2.7)\n",
    "                  6   | SHA-512 (since glibc 2.7)\n",
    "                  y   | yescrypt, hash size 256 bits, salt size up to 512 bits\n",
    "\n",
    "So   `$5$salt$encrypted`   is   an   SHA-256   encoded    password    and\n",
    "`$6$salt$encrypted` is an SHA-512 encoded one.\n",
    "\n",
    "<hr> "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a3ae4d9",
   "metadata": {},
   "source": [
    "## MD5, SHA256, and SHA512 Encryption algorithms.\n",
    "\n",
    "\n",
    "- The crypt algorithms are the one way function. There is no reverse function to derive the original password from its hash.\n",
    "- md5-crypt can be divided into three phases. Initialization, loop, and finalization:\n",
    "\n",
    "              1. Generate a simple md5 hash based on the salt and password\n",
    "              2. Loop 1000 times, calculating a new md5 hash based on the previous hash concatenated with \n",
    "                 alternating the password and the salt.\n",
    "              3. Use a special base64 encoding on the final hash to create the password hash string\n",
    "- sha512-crypt allows to specify a custom number of rounds, from 1000 to 999999999. the default is 5000.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00023154",
   "metadata": {},
   "source": [
    "## cryptvm VM setup (Exercise).\n",
    "\n",
    "\n",
    "Clone your kvm1 virtual machine into a new VM, cryptvm.\n",
    "```bash\n",
    "virsh shutdown kvm1\n",
    "virt-clone -o kvm1 -n cryptvm -f /home/hostadm/KVM/cryptvm.qcow2\n",
    "```\n",
    "\n",
    "Start cryptvm and login to its console:\n",
    "```bash\n",
    "virsh start cryptvm\n",
    "virsh console cryptvm\n",
    "```\n",
    "Fix the hostname in `/etc/hostname` and reset the machine ID by running the script:\n",
    "```bash\n",
    "./vm_id_reset.sh\n",
    "```\n",
    "Reboot the VM.\n",
    "\n",
    "On the desktop, enter the IP address of cryptvm in `/etc/hosts` file to reslove its host name.\n",
    "\n",
    "Create user mike1:\n",
    "```bash\n",
    "groupadd -g 1002 mike1\n",
    "useradd -m -s /bin/bash -g mike1 -u 1002 mike1\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4dc37e6b",
   "metadata": {},
   "source": [
    "## User password with different encryptions (Exercise).\n",
    "\n",
    "On the desktop, install python module passlib:\n",
    "\n",
    "```bash\n",
    "conda install passlib\n",
    "```\n",
    "\n",
    "In Python, we'll setup 4 user names, mike1, mike2, mike3, and mike4 with password mike123, encrypted \n",
    " with 4 different algorithms: DES, MD5, SHA256, and SHA512, accordingly.\n",
    " \n",
    "Open Jupyter notebook, and paste the following content in the cell:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d9bde028",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mike1:O8x14EtLD7vDI\n",
      "mike2:$1$b1b2$b1ELOdgDydgNqFTzZPEWn.\n",
      "mike3:$5$b1b2$Tm93dbH8yrvOLawhu5c3pDV5YBYoFFP4ndArlklRyeA\n",
      "mike4:$6$b1b2$7.mG4cQmg8y.10Ncsi.nndGMVybyaE6gnENYTKjF4qDF5mzMVhrTmJa.S1JdAef9TPTf.yWIt9r/LUCbwyA0l.\n"
     ]
    }
   ],
   "source": [
    "from passlib.context import CryptContext\n",
    "\n",
    "# Users mike1, mike2, mike3, and mike3 with different password encryption algorithms\n",
    "users = { 'mike1':'des_crypt', \n",
    "          'mike2':'md5_crypt', \n",
    "          'mike3':'sha256_crypt',\n",
    "          'mike4':'sha512_crypt' }\n",
    "\n",
    "# Password and salt\n",
    "passwd = 'mike123'\n",
    "salt_add = 'b1b2'\n",
    "\n",
    "# Initialize list for password hashes\n",
    "out_passwd = []\n",
    "\n",
    "# DES hash\n",
    "ctx = CryptContext(schemes=users['mike1'])\n",
    "hash = ctx.hash(passwd)\n",
    "out_passwd.append(f'mike1:{hash}')\n",
    "\n",
    "# MD5 hash\n",
    "ctx = CryptContext(schemes=users['mike2'])\n",
    "hash = ctx.hash(passwd, salt=salt_add)\n",
    "out_passwd.append(f'mike2:{hash}')\n",
    "\n",
    "# SHA hashes\n",
    "for i in sorted(users)[2:]:\n",
    "    ctx = CryptContext(schemes=users[i])\n",
    "    hash = ctx.hash(passwd, salt=salt_add,rounds=5000)\n",
    "    out_passwd.append(f'{i}:{hash}')\n",
    "\n",
    "# Save password hashes in file passwd.txt\n",
    "with open('passwd.txt','w') as f:\n",
    "    for i in out_passwd:\n",
    "        f.write(f'{i}\\n')\n",
    "        \n",
    "# Check the content of file passwd.txt\n",
    "%cat passwd.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5d3e1c1",
   "metadata": {},
   "source": [
    "## Cracking passwords with John the Ripper (Exercise).\n",
    "\n",
    "\n",
    "On cryptvm, install John the Ripper:\n",
    "```bash\n",
    "apt install john\n",
    "mkdir john\n",
    "cd john\n",
    "```\n",
    "\n",
    "Get file passwd.txt from the desktop:\n",
    "```bash\n",
    "scp 192.168.122.1:Python/passwd.txt .\n",
    "```\n",
    "\n",
    "Crack DES passwords (default):\n",
    "```bash\n",
    "john passwd.txt        #this cracks password\n",
    "john --show passwd.txt #this shows  the cracked passwords\n",
    "```\n",
    "Crack MD5 passwords:\n",
    "```bash\n",
    "john --format=md5crypt passwd.txt      #this cracks password\n",
    "john --show passwd.txt                 #this shows  the cracked passwords\n",
    "```\n",
    "They should look as follows:\n",
    "```{addmonition} output\n",
    "mike1:mike123\n",
    "mike2:mike123\n",
    "\n",
    "2 password hashes cracked, 2 left\n",
    "```\n",
    "\n",
    "Note, John the Ripper can't handle advanced encryption algorithms, SHA-256 and SHA-512.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98462492",
   "metadata": {},
   "source": [
    "## SSH brute force attacks (Exercise)\n",
    "\n",
    "On the VM, assign password ```mike123``` to user mike1:\n",
    "```bash\n",
    "sudo passwd mike1\n",
    "```\n",
    "\n",
    "\n",
    "Install `crunch` package on the desktop, which is needed for generating a password dictionary.\n",
    "```bash\n",
    "sudo apt install crunch\n",
    "```\n",
    "\n",
    "Make `cryptvm` name resolvable by creating the entry in `/etc/hosts` file on the desktop.\n",
    "\n",
    "On the desktop, generate a password table, `passwords.txt`, by running `crunch`:\n",
    "```bash\n",
    "crunch  7 7 mike123 -o passwords.txt\n",
    "```\n",
    "The above creates 7 symbol words combined from the letters and numbers provided.\n",
    "\n",
    "Find the position of the correct password in the file:\n",
    "```bash\n",
    "grep -n mike123 passwords.txt\n",
    "```\n",
    "Shorten passwords.txt file to make the correct passwords to be within the first 10 lines for the scanner to \n",
    "complete its work faster>\n",
    "If it, for example, shows 22876-th position. \n",
    "Remove the first 22870 line in the file with command ```sed```:\n",
    "```bash\n",
    "sed -i 1,22870d passwords.txt\n",
    "```\n",
    "Check the position of the correct password again:\n",
    "```bash\n",
    "grep -n mike123 passwords.txt\n",
    "```\n",
    "\n",
    "Install package ```hydra``` on the desktop:\n",
    "```bash\n",
    "sudo apt install hydra\n",
    "```\n",
    "\n",
    "Run SSH bruteforce attacks onto account mike1 on the both VMs:\n",
    "```bash\n",
    "hydra -l mike1 -P passwords.txt cryptvm ssh\n",
    "```\n",
    "Within a few minutes, hydra should be able to identify the correct password for user mike1 from `passwords.txt` list.\n",
    "\n",
    "```{admonition} output\n",
    "[22][ssh] host: cryptvm   login: mike1   password: mike123\n",
    "```\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c929c896",
   "metadata": {},
   "source": [
    "## Identifying SSH login attacks in the system logs (Exercise)\n",
    " \n",
    "\n",
    "On `cryptvm` VM, check the lines in log file `auth.log` and see ssh login attempts to user account `mike1`:\n",
    "```bash\n",
    "grep mike1 /var/log/auth.log  | grep auth\n",
    "```\n",
    "See the successfull attempt to login:\n",
    "```bash\n",
    "grep mike1 /var/log/auth.log  | grep -E -v '(error|[Ff]ail)'\n",
    "```\n",
    "\n",
    "On a RedHat/Rocky system, the similar authentication logs go into file `/var/log/secure`\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "535997fa",
   "metadata": {},
   "source": [
    "## Open Ports List. (Exercise)\n",
    "\n",
    "Install package `net-tools` on `cryptvm` VM:\n",
    "```bash\n",
    "apt install net-tools\n",
    "```\n",
    "To see what ports are open, run command\n",
    "\n",
    "```bash\n",
    "netstat -nal\n",
    "```\n",
    "and check on TCP and UDP ports in the listing. To see what processes are bound to what ports, run as root\n",
    "```bash\n",
    "netstat -nalp | less\n",
    "```\n",
    "\n",
    "```{admonition} output:\n",
    "    Active Internet connections (servers and established)\n",
    "    Proto Recv-Q Send-Q Local Address       Foreign Address   State       PID/Program name\n",
    "    tcp        0      0 0.0.0.0:515         0.0.0.0:*         LISTEN       1742/lpd Waiting\n",
    "    tcp        0      0 127.0.0.1:25        0.0.0.0:*         LISTEN       1726/exim4\n",
    "    tcp        0      0 192.168.1.101:1040  128.6.238.10:22   ESTABLISHED  2229/ssh\n",
    "    tcp        0      0 192.168.1.101:1024  128.6.238.12:993  ESTABLISHED  2195/pine\n",
    "    tcp6       0      0 :::22               :::*              LISTEN       1813/sshd\n",
    "    udp        0      0 0.0.0.0:68          0.0.0.0:*                      2085/dhclient\n",
    "```\n",
    "Similarly,\n",
    "```bash\n",
    "netstat -n --inet --listening --programs\n",
    "```\n",
    "Also, the processes responsible for the open ports can be identified with\n",
    "```bash\n",
    "lsof -i\n",
    "```\n",
    "See example (Links to an external site.).\n",
    "\n",
    "Syntax of `lsof`:\n",
    "```c\n",
    "    lsof -i [TCP|UDP][@host][:port]\n",
    "```\n",
    "\n",
    "To list all open files for specific processes:\n",
    "```bash\n",
    "lsof -p PID\n",
    "lsof -c COMMAND\n",
    "lsof -u username\n",
    "```\n",
    "To list all open files\n",
    "```bash\n",
    "lsof\n",
    "```\n",
    "\n",
    "Exercise\n",
    "\n",
    "SSH to `cryptvm` VM from the desktop, become root, and run lsof to see the open internet ports:\n",
    "```bash\n",
    "ssh cryptvm\n",
    "sudo -s\n",
    "lsof -i -P\n",
    "```\n",
    "Note, option \"-P\" shows you the port number.\n",
    "\n",
    "You should see the ports opened for the following services: `dhclient3, udp/68, sshd, tcp/22`.\n",
    "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`.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82250ea9",
   "metadata": {},
   "source": [
    "## Closing ports by disabling network services.\n",
    " \n",
    "\n",
    "- The open ports are related to the aplications/processes, which start either at the system startup or through inetd/xinetd.\n",
    "For the Systemd aware applications,\n",
    "```bash\n",
    "systemctl stop service_name\n",
    "systemctl disable service_name\n",
    "```\n",
    "\n",
    "- Vulnerable services:\n",
    "`telnet, rsh, rcp, rexec, ftp, portmap, nfs, mountd, ypbind, ypserv`.\n",
    "Disable them if your computer is on the open Internet. But if you need them, install a firewall and implement the tcp_wrappers.\n",
    "\n",
    "- Relatively secure services:\n",
    "Services protected with SSL libraries for encrypted connection such as `SSH, LDAP, Apache; Kerberos`.\n",
    "\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e21576b",
   "metadata": {},
   "source": [
    "## Sniffing clear text traffic with tcpdump. (Exercise)\n",
    "\n",
    "\n",
    "The classical FTP service is known to be ```clear text```, without encryption.\n",
    "\n",
    "In this exercise we are going to install and run ```ftpd``` server on ```cryptvm```, connect via ftp from\n",
    " the desktop to ```cryptvm```, and sniff the netwoek traffic related to FTP via ```tcpdump```.\n",
    "\n",
    "It is better to use ```tmux``` terminal server here for completing the tasks below on both ```cryptvm``` and \n",
    " the desktop at the same time:\n",
    " \n",
    "On ```cryptvm``` install ftpd:\n",
    "```bash\n",
    "sudo apt install ftpd\n",
    "```\n",
    "Verify that port tcp/21 is open:\n",
    "```bash\n",
    "netstat -na | grep \"21 .* LISTEN\"\n",
    "```\n",
    "On ```cryptvm```, install tcpdump:\n",
    "```bash\n",
    "sudo apt install tcpdump\n",
    "```\n",
    "On ```cryptvm``` start running tcpdump to sniff the traffic from the desktop, 192.168.122.1, to the destination port 21 (for ftpd):\n",
    "```bash\n",
    "sudo tcpdump -i enp1s0 src 192.168.122.1 and dst port 21 -A\n",
    "```\n",
    "\n",
    "On the desktop, install ftp client:\n",
    "```bash\n",
    "sudo install ftp\n",
    "```\n",
    "On the desktop, run ftp to ```cryptvm``` and authenticate as user mike1 with his password.\n",
    "```bash\n",
    "ftp cryptvm\n",
    "```\n",
    "\n",
    "Watch for the tcpdump output on ```cryptvm```. You should be able to see the user name and password in clear text:\n",
    "\n",
    "```{admonition} among the output\n",
    "   FTP: USER mike1\n",
    "   FTP: PASS mike123\n",
    "```\n",
    "\n",
    "You can also type commands in the FTP prompt, like ```cd .ssh```, ```ls```, and see them in the output of tcpdump.\n",
    "\n",
    "To exit from the FTP shell, type \n",
    "```bash\n",
    "quit\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bcc0782",
   "metadata": {},
   "source": [
    "## IP filtering firewalls (iptables)\n",
    "\n",
    "Packet filtering is implemented through Linux Kernel.\n",
    "\n",
    "\n",
    "\n",
    "![](img/filter.jpg) \n",
    "\n",
    "Chains for network packets:\n",
    "\n",
    "    INPUT\n",
    "    OUTPUT\n",
    "    FORWARD\n",
    "    \n",
    "Chains are combined into tables:\n",
    "\n",
    "    filter (default)\n",
    "    NAT\n",
    "\n",
    "Special tables (not discussed here):\n",
    "\n",
    "    mangle\n",
    "    raw\n",
    "    \n",
    "Each of the chains filters data packets based on\n",
    "Source and Destination IP\n",
    "Source and Destination Port number\n",
    "Network interface\n",
    "State of the packet\n",
    "Target for the rule:\n",
    "\n",
    "    ACCEPT\n",
    "    DROP\n",
    "    REJECT\n",
    "    LOG \n",
    "\n",
    "To enter and exit user defined custom chains the following rules ar used:\n",
    "\n",
    "    NFQUEUE\n",
    "    RETURN\n",
    "    \n",
    "    \n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec03342a",
   "metadata": {},
   "source": [
    "## Simple iptables script\n",
    "\n",
    "\n",
    "\n",
    "```{admonition} executable script:\n",
    "    #!/bin/bash\n",
    "    IPT=/sbin/iptables\n",
    "\n",
    "    # Flush the tables\n",
    "    $IPT -F INPUT\n",
    "    $IPT -F OUTPUT\n",
    "    $IPT -F FORWARD\n",
    "\n",
    "    # Define default policy to DROP packets\n",
    "    $IPT -P INPUT   DROP\n",
    "    $IPT -P OUTPUT  DROP\n",
    "    $IPT -P FORWARD DROP\n",
    "\n",
    "    # Permit DNS traffic\n",
    "    $IPT -A INPUT -p udp --sport 53 -j ACCEPT\n",
    "    $IPT -A OUTPUT -p udp --dport 53 -j ACCEPT\n",
    "\n",
    "    # Accept local-network return traffic from private network 192.168.122.0/24:\n",
    "    $IPT -A INPUT -m state -p tcp --dport 1024:65535 --state ESTABLISHED,RELATED -s 192.168.122.0/24 -j ACCEPT\n",
    "    $IPT -A OUTPUT -m state -p tcp --sport 1024:65535 ! --state INVALID -d 192.168.122.0/24 -j ACCEPT\n",
    "\n",
    "    # Accept all HTTP connections\n",
    "    $IPT -A INPUT -m state -p tcp --dport 80 ! --state INVALID -j ACCEPT\n",
    "    $IPT -A OUTPUT -m state -p tcp --sport 80 --state ESTABLISHED,RELATED -j ACCEPT\n",
    "\n",
    "    # Accept local (192.168.122.0/24) SSH traffic\n",
    "    $IPT -A INPUT -m state -p tcp --dport 22 ! --state INVALID -s 192.168.122.0/24 -j ACCEPT\n",
    "    $IPT -A OUTPUT -m state -p tcp --sport 22 --state ESTABLISHED,RELATED -d 192.168.122.0/24 -j ACCEPT\n",
    "\n",
    "    # Accept all local (loopback) traffic on the lo interface\n",
    "    $IPT -A INPUT -s 127.0.0.1 -i lo -j ACCEPT\n",
    "    $IPT -A OUTPUT -d 127.0.0.1 -o lo -j ACCEPT\n",
    "\n",
    "    # Log all other traffic\n",
    "    $IPT -A INPUT -j LOG\n",
    "    $IPT -A OUTPUT -j LOG\n",
    "```\n",
    "\n",
    "To check the current iptables rules, run\n",
    "```bash\n",
    "/sbin/iptables -n -L\n",
    "```\n",
    "\n",
    "<hr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c730ff3d",
   "metadata": {},
   "source": [
    "## Configuring iptables firewall (Exercise)\n",
    "\n",
    "Make sure iptables have been installed on cryptvm VM:\n",
    "\n",
    "```bash\n",
    "dpkg -l | grep iptables\n",
    "```\n",
    "\n",
    "Check the `iptables` rules on `cryptvm`:\n",
    "\n",
    "```bash\n",
    "/sbin/iptables -n -L\n",
    "```\n",
    "On `cryptvm`, download the iptables script from `fw-script.sh` (Links to an external site.), make it executable, then run:\n",
    "```bash\n",
    "wget http://linuxcourse.rutgers.edu/Files/fw-script.sh\n",
    "chmod 755 fw-script.sh\n",
    "./fw-script.sh\n",
    "```\n",
    "Check the iptables rules again,\n",
    "```bash\n",
    "/sbin/iptables -n -L\n",
    "```\n",
    "You should see the new active rules.\n",
    "\n",
    "Try pinging your desktop private virtual IP address from `cryptvm`:\n",
    "```bash\n",
    "ping 192.168.122.1\n",
    "```\n",
    "Try pinging `cryptvm` VM from the desktop:\n",
    "```bash\n",
    "ping cryptvm\n",
    "```\n",
    "\n",
    "To enable ping, you need to add the following rules to your `fw-script.sh` (you can include them somwhere after the default policy)\n",
    "\n",
    "```{admonition} fw-script.sh:\n",
    "    # Echo - uncomment to allow your system to be pinged.\n",
    "    $IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 0 -j ACCEPT\n",
    "    $IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 8 -j ACCEPT\n",
    "    $IPT -A INPUT -p icmp -s 192.168.122.0/24 --icmp-type 11 -j ACCEPT\n",
    "    $IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 0 -j ACCEPT\n",
    "    $IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 8 -j ACCEPT\n",
    "    $IPT -A OUTPUT -p icmp -d 192.168.122.0/24 --icmp-type 11 -j ACCEPT\n",
    "    After the script is modified, you need to run the script,\n",
    "```\n",
    "Run it:\n",
    "```bash\n",
    "./fw-script.sh\n",
    "```\n",
    "\n",
    "Try to ssh to some host located outside of the lab, for example,  engsoft.rutgers.edu.\n",
    "Try running `apt update` command.\n",
    "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.\n",
    "\n",
    "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.\n",
    "The new rules should look as follows:\n",
    "```{admonition}\n",
    "    $IPT -A INPUT -m state -p tcp --dport 1024:65535 --state ESTABLISHED,RELATED -s 0/0 -j ACCEPT\n",
    "    $IPT -A OUTPUT -m state -p tcp --sport 1024:65535 ! --state INVALID -d 0/0 -j ACCEPT\n",
    "```\n",
    "After the script is modified, you need to run the script,\n",
    "```bash\n",
    "./fw-script.sh\n",
    "```\n",
    "Try ssh to the host and apt command again. They should run fine.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84d0d431",
   "metadata": {},
   "source": [
    "## fail2ban (Exercise)\n",
    "\n",
    "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. \n",
    "\n",
    "`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`.\n",
    "\n",
    "`Fail2ban` installation on Ubuntu VM,  `cryptvm`.\n",
    "\n",
    "First, flush the active iptables rules:\n",
    "```bash\n",
    "iptables -P INPUT   ACCEPT\n",
    "iptables -P OUTPUT  ACCEPT\n",
    "iptables -P FORWARD ACCEPT\n",
    "iptables -F\n",
    "```\n",
    "\n",
    "Install fail2ban package:\n",
    "```bash\n",
    "apt install fail2ban\n",
    "```\n",
    "\n",
    "Backup the default configuration file\n",
    "```bash\n",
    "cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local\n",
    "```\n",
    "\n",
    "Create a new configuration file, `/etc/fail2ban/jail.d/sshd.local`, with the following content:\n",
    "```bash\n",
    "[sshd] \n",
    "enabled = true \n",
    "port = 22 \n",
    "filter = sshd \n",
    "logpath = /var/log/auth.log \n",
    "maxretry = 5 \n",
    "bantime = 86400\n",
    "```\n",
    "Restart fail2ban:\n",
    "```bash\n",
    "systemctl restart fail2ban\n",
    "```\n",
    "Check the active fail2ban status:\n",
    "```bash\n",
    "fail2ban-client status\n",
    "```\n",
    "Try ssh to cryptvm from the other VM and use incorrect password 5 times.\n",
    "Check the iptables settings on cryptvm:\n",
    "```bash\n",
    "iptables -nL \n",
    "```\n",
    "Remove the banned IP address from the iptables, for example:\n",
    "```bash\n",
    "fail2ban-client set sshd unbanip 192.168.122.79\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fd6b76d",
   "metadata": {},
   "source": [
    "## Port scanning (Exercise)\n",
    "\n",
    "After unnecessary ports are closed and firewall implemented, the system should be scanned from a remote host with NMAP. Run nmap on the desktop to scan the ports on cryptvm.\n",
    "\n",
    "To scan the TCP ports, for example on 192.168.122.42:\n",
    "```bash\n",
    "nmap -sT -O  192.168.122.42\n",
    "```\n",
    "\n",
    "```{admonition} ouput:\n",
    "    The output may look like the following:\n",
    "    Starting nmap  ( http://www.insecure.org/nmap/ ) at 2021-04-05 20:56 EDT\n",
    "    Interesting ports on node18.linux.class (192.168.122.42):\n",
    "    (The 1653 ports scanned but not shown below are in state: closed)\n",
    "    PORT      STATE SERVICE\n",
    "    22/tcp    open  ssh\n",
    "    111/tcp   open  rpcbind\n",
    "    139/tcp   open  netbios-ssn\n",
    "    445/tcp   open  microsoft-ds\n",
    "    513/tcp   open  login\n",
    "    514/tcp   open  shell\n",
    "    919/tcp   open  unknown\n",
    "    953/tcp   open  rndc\n",
    "    2049/tcp  open  nfs\n",
    "    32772/tcp open  sometimes-rpc7\n",
    "    MAC Address: 00:10:5A:0A:B3:E8 (3com)\n",
    "    Device type: general purpose\n",
    "    Running: Linux 2.4.X|2.5.X|2.6.X\n",
    "    OS details: Linux 2.4.18 - 2.6.7\n",
    "    Uptime 8.143 days (since Mon Mar 28 16:30:58 2021)\n",
    "```\n",
    "\n",
    "To scan the UDP ports, for example on 192.168.122.42:\n",
    "```bash\n",
    "nmap -sU -v  192.168.122.42\n",
    "```\n",
    "Nessus is an extension of NMAP; it provides vulnerability details and security advises.\n",
    "\n",
    "Exercise.\n",
    "\n",
    "Scan the TCP ports on cryptvm from your desktop:\n",
    "```bash\n",
    "nmap -sT -O  cryptvm\n",
    "```\n",
    "\n",
    "Scan the UDP ports on cryptvm from your desktop:\n",
    "```bash\n",
    "nmap -sU -v  cryptvm\n",
    "```\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b995d6e",
   "metadata": {},
   "source": [
    "## References\n",
    "\n",
    "\n",
    "[Password hashing with MD5-crypt in relation to MD5](http://www.vidarholen.net/contents/blog/?p=32)\n",
    " \n",
    "[Implementation of SHA512-crypt vs MD5-crypt](http://www.vidarholen.net/contents/blog/?p=33)\n",
    " \n",
    "[How are passwords stored in Linux (Understanding hashing with shadow utils)](http://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils)\n",
    " \n",
    "[How to install fail2ban on Ubuntu Server 18.04 ](https://www.techrepublic.com/article/how-to-install-fail2ban-on-ubuntu-server-18-04)\n",
    "\n",
    "\n",
    "[How to install Fail2Ban on CentOS 7](https://www.howtoforge.com/tutorial/how-to-install-fail2ban-on-centos)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
