Network Monitoring With Slack Alerting

Last November I hacked together a script that continually monitored your network and sent a slack alert when something change.   It worked but I was never 100% happy with it so I spent some time this weekend and rewrote it so that is hopefully more user friendly and functional. Some changes in this version includes the ability to set timeouts between scans, better output on the machine running the script, better logging and the start of a framework to add new tools.

All you need to run this project for yourself is a Ubuntu install with NMap, PripsSlackCLI and a copy of the script.

Once running here are what a slack alert looks like:

Here is what the script looks like running:

Here is a copy of the script:

#!/bin/bash -u
#
# Requires NMAP, NDIFF, PRIPS and Slackcli
# https://candrholdings.github.io/slack-cli/
# NETOWORKS should be the list of networks you want to monitor. 
# INTERVAL how many seconds to wait between scans
# SLACKTOKEN from here https://api.slack.com/web
# 

NETWORKS="192.168.0.0/24"
TARGETS=$(for NETWORK in ${NETWORKS}; do prips $NETWORK; done)
INTERVAL="1800"
SLACKTOKEN="Get This From https://api.slack.com/web"
OPTIONS='-T4 --open --exclude-ports 25'


cd  ~/scan
LAST_RUN_FILE='.lastrun'

while true; do

    # If the last run file exists, we should only sleep for the time
    # specified minus the time that's already elapsed.
    if [ -e "${LAST_RUN_FILE}" ]; then
        LAST_RUN_TS=$(date -r ${LAST_RUN_FILE} +%s)
        NOW_TS=$(date +%s)
        LAST_RUN_SECS=$(expr ${NOW_TS} - ${LAST_RUN_TS})
        SLEEP=$(expr ${INTERVAL} - ${LAST_RUN_SECS})
        if [ ${SLEEP} -gt 0 ]; then
            UNTIL_SECS=$(expr ${NOW_TS} + ${SLEEP})
            echo $(date) "- sleeping until" $(date --date="@${UNTIL_SECS}") "(${SLEEP}) seconds"
            sleep ${SLEEP}
        fi
    fi

    START_TIME=$(date +%s)
    echo '' 
    echo '=================='
    echo '' 


    DATE=`date +%Y-%m-%d_%H-%M-%S`
    for TARGET in ${TARGETS}; do
        CUR_LOG=scan-${TARGET/\//-}-${DATE}
        PREV_LOG=scan-${TARGET/\//-}-prev
        DIFF_LOG=scan-${TARGET/\//-}-diff

	echo ''        
	echo $(date) "- starting ${TARGET}"
	

        # Scan the target
        nmap ${OPTIONS} ${TARGET} -oX ${CUR_LOG} >/dev/null

        # If there's a previous log, diff it
        if [ -e ${PREV_LOG} ]; then

            # Exclude the Nmap version and current date - the date always changes
            ndiff ${PREV_LOG} ${CUR_LOG} | egrep -v '^(\+|-)N' > ${DIFF_LOG}
            if [ -s ${DIFF_LOG} ]; then
			printf "Changes Detected, Sending to Slack."
			nmap -sV ${TARGET} | grep open | grep -v "#" > openports.txt
			slackcli -t $SLACKTOKEN -h nmap -m "Changes were detected on ${TARGET}. The following ports are now open: " 
			sleep 1
			cat openports.txt | slackcli -t $SLACKTOKEN -h nmap -c 
			rm openports.txt
                # Set the current nmap log file to reflect the last date changed
                ln -sf ${CUR_LOG} ${PREV_LOG}
            else
                # No changes so remove our current log
		printf "No Changes Detected."
                rm ${CUR_LOG}
            fi
            rm ${DIFF_LOG}
        else
            # Create the previous scan log
            ln -sf ${CUR_LOG} ${PREV_LOG}
        fi
    done

    touch ${LAST_RUN_FILE}
    END_TIME=$(date +%s)
    echo
    echo $(date) "- finished all targets in" $(expr ${END_TIME} - ${START_TIME}) "second(s)"
done

Some Quick Notes:

  • You will want to run this in screen so that it runs continually.
  • I excluded port 25 because it was reporting as “filtered” every other scan causing false alerts.
  • NDIFF really needs to be updated.  Its output is ridiculously bad.
  • Let me know on twitter if you have any questions.

Disallow Million Most Common Passwords

I was working on a project recently and was asked if it was possible to stop users from setting common passwords.   Using the pam_cracklib module and @DanielMiessler  common passwords list it is as simple as these 3 commands:

sudo apt-get install libpam-cracklib -y
sudo wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/10_million_password_list_top_1000000.txt /usr/share/dict/ -O /usr/share/dict/million.txt
sudo create-cracklib-dict /usr/share/dict/million.txt

Seriously,  that’s it.

Here is what a user will see when they attempt to use a password from the list: 

Getting Started With Mod_Security

 

Mod_Security is the most widely known and used server based Web Application Firewall but I had not had a chance to play with it so I decided to take sometime this weekend to build a website (modsec.handsonhacking.org) to test it.   Here is a small walk through on how I did it.

Base Server Install:

I used AWS Lightsail to build a webserver using Ubuntu 16.04,  Apache2,  LetsEncrypt , and this HTML5 Template.

Install and configure the website with these commands:

sudo apt update && sudo apt upgrade -y
sudo apt install apache2 git -y
sudo rm /var/www/html/index.html
sudo git clone https://github.com/themefisher/Blue-Onepage-HTML5-Business-Template.git /var/www/html/
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
sudo certbot

Mod_Security Install

Install Mod_Security with these commands:

sudo apt-get install libapache2-modsecurity
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

Move from logging to blocking move with these commands:

sudo nano /etc/modsecurity/modsecurity.conf
# Change SecRuleEngine DetectionOnly
SecRuleEngine On

It should look like this:Install the updated OWASP ModSecurity Core Rule Set:

sudo rm -rf /usr/share/modsecurity-crs
sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs

Enable them in the apache config file:

sudo nano /etc/apache2/mods-enabled/security2.conf
Add:
     IncludeOptional /usr/share/modsecurity-crs/*.conf
     IncludeOptional /usr/share/modsecurity-crs/rules/*.conf

It should look like this:

Move the OWASP rules from logging to blocking:

cd /usr/share/modsecurity-crs
sudo cp crs-setup.conf.example crs-setup.conf
sudo nano crs-setup.conf

Comment Out: 
#SecDefaultAction "phase:1,log,auditlog,pass"
#SecDefaultAction "phase:2,log,auditlog,pass"

Uncomment:
SecDefaultAction "phase:1,log,auditlog,deny,status:403"
SecDefaultAction "phase:2,log,auditlog,deny,status:403"

It should look like this:

Next restart apache to enable mod_security:

sudo systemctl restart apache2

Testing

To test I used burp suite to scan modsec.handsonhacking.org to generate plenty of “bad traffic”.

Run this to see what is being blocked in real time:

sudo tail -f /var/log/apache2/modsec_audit.log

Next Steps

Now that I have mod_security running I need to find a better logging solution.   So far I have quickly looked at waf-fle and auditconsole but they both look to be abandoned.  It looks like there are people who are doing a lot with ELK but I have not found anything solid yet.  I am really surprised there isn’t a ready made Dashboard but I will keep looking.

Warning:

I have spent all of four hours playing with this on non-production traffic.  Please do not just install this in front of your website and then blame me when things break.

Closing:

Overall with the help of @infosecdad  and @lojikil guiding me through some of the places where documentation is lacking it was fairly easy to get this setup and going.   If you have any questions please reach out to me on twitter at @JGamblin. 

MAC Address Randomization for MacOS

One of the things that even the new MacOS beta is missing is MAC Address Randomization on boot.  After spending a few hours working on it I put together this completely hack-y solution that uses Spoof and an automator Script saved as an application.

Here is how I configured it:

on run {input, parameters}
	
	delay 4
	tell application "Terminal"	
		activate
		
	end tell
	
	tell application "System Events"
		delay 0.3
		keystroke "sudo spoof randomize en0"
		keystroke return
		delay 0.5
		keystroke "#SADLYYOURPASSWORDHERE"
		keystroke return
		delay 5
	end tell
	
	tell application "Terminal" to quit
	return input
	
end run
  • Change “#SADLYYOURPASSWORDHERE” to your local password.
  • Test & Save:

  • Add to System Preferences -> Users & Groups -> Login items

Overall this is a pretty simple solution.  I dont love it because you have to save your local password in the script and I am looking for a way to change that but it looks like to change the MAC address you have to be root.  I will update this post if I figure out a way to remove the password.

My Security Summer Camp Talk List

Security summer camp is about a week away so I spent some time this afternoon trying to figure out what talks and events I want to make sure I attend.

BSides Las Vegas:

A Day in the Life of a Product Security Incident Response Manager
From SOC to CSIRT
Hadoop Safari : Hunting For Vulnerabilities
Introduction to Reversing and Pwning
YARA-as-a-Service (YaaS): Real-Time Serverless Malware Detection
Abusing Webhooks for Command and Control
BSides Las Vegas Full Schedule

Blackhat:

Breaking Electronic Door Locks Like You’re On CSI: Cyber
Free-Fall: Hacking Tesla From Wireless To Can Bus
Blackhat Full Sechedule

Defcon 25:

Meet the Feds (who care about security research)
There’s no place like 127.0.0.1 – Achieving reliable DNS rebinding in modern browsers
Wiping Out CSRF
Real-time RFID Cloning in the Field
Exploiting 0ld Mag-stripe information with New technology
Secret Tools: Learning About Government Surveillance Software You Can’t Ever See
Next-Generation Tor Onion Services
Using GPS Spoofing to Control Time
Cisco Catalyst Exploitation
Defcon Full Schedule

Other Events:

IOACTIVE IOASIS
ShabbatCon
Defcon Parties List