commit 49cbd4460d3b05f710702097767361df768e5e30 Author: Marc Date: Wed Dec 11 21:11:53 2019 +0000 Files: Initial commit of Shark files diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f0a9778 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "www"] + path = www + url = git@github.com:hak5/unified-ui.git + branch = master diff --git a/etc/banner b/etc/banner new file mode 100644 index 0000000..afaf440 --- /dev/null +++ b/etc/banner @@ -0,0 +1,4 @@ + + \_____)\_____ Shark Jack _____/(_____/ + /--v____ __°< by Hak5 >°__ ____v--\ + )/ \( diff --git a/etc/config/network b/etc/config/network new file mode 100644 index 0000000..40d9dfa --- /dev/null +++ b/etc/config/network @@ -0,0 +1,14 @@ + +config interface 'loopback' + option ifname 'lo' + option proto 'static' + option ipaddr '127.0.0.1' + option netmask '255.0.0.0' + +config interface 'lan' + option ifname 'eth0' + option proto 'static' + option ipaddr '172.16.24.1' + option netmask '255.255.255.0' + option ip6assign '60' + diff --git a/etc/init.d/shark b/etc/init.d/shark new file mode 100755 index 0000000..ae2474e --- /dev/null +++ b/etc/init.d/shark @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common + +START=99 + +start() { + logger -t Shark "[*] Starting Hak5 Shark Jack" + /usr/bin/shark_framework +} + +stop() { + logger -t Shark "[*] Stopping Hak5 Shark Jack" + sync + /usr/bin/LED OFF + halt +} diff --git a/etc/opkg/customfeeds.conf b/etc/opkg/customfeeds.conf new file mode 100644 index 0000000..4a1ea06 --- /dev/null +++ b/etc/opkg/customfeeds.conf @@ -0,0 +1,2 @@ +# Hak5 Packages +src/gz 1907_shark http://downloads.hak5.org/packages/shark/1907/ diff --git a/etc/ssh/sshd_config b/etc/ssh/sshd_config new file mode 100644 index 0000000..8ddc398 --- /dev/null +++ b/etc/ssh/sshd_config @@ -0,0 +1,4 @@ +PermitRootLogin yes +PubkeyAuthentication yes +AuthorizedKeysFile .ssh/authorized_keys +Subsystem sftp internal-sftp diff --git a/etc/uci-defaults/99-shark.sh b/etc/uci-defaults/99-shark.sh new file mode 100755 index 0000000..1edea6c --- /dev/null +++ b/etc/uci-defaults/99-shark.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# Firstboot setup script for the Shark Jack by Hak5 + + +# Change root password +echo -e "hak5shark\nhak5shark\n" | passwd + +# Change the hostname +uci set system.@system[0].hostname=shark +uci commit system +echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname + +# Disable Telnet server +/etc/init.d/telnet disable +/etc/init.d/telnet stop + +# Disable AutoSSH +/etc/init.d/autossh disable +/etc/init.d/autossh stop + +# Disable SSH server +/etc/init.d/sshd disable +/etc/init.d/sshd stop + +# Disable odhcpd +/etc/init.d/odhcpd disable +/etc/init.d/odhcpd stop + +# Disable uHTTPd web server +/etc/init.d/uhttpd disable +/etc/init.d/uhttpd stop + +# Enable Shark service +/etc/init.d/shark enable +/etc/init.d/shark start + + +# Ensure the script is deleted after execution +exit 0 diff --git a/root/VERSION b/root/VERSION new file mode 100644 index 0000000..9084fa2 --- /dev/null +++ b/root/VERSION @@ -0,0 +1 @@ +1.1.0 diff --git a/root/payload/payload.sh b/root/payload/payload.sh new file mode 100644 index 0000000..62bf26d --- /dev/null +++ b/root/payload/payload.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Title: Sample Nmap Payload for Shark Jack +# Author: Hak5 +# Version: 1.0 +# +# Scans target subnet with Nmap using specified options. Saves each scan result +# to loot storage folder. +# +# Red ...........Setup +# Amber..........Scanning +# Green..........Finished +# +# See nmap --help for options. Default "-sP" ping scans the address space for +# fast host discovery. + +NMAP_OPTIONS="-sP --host-timeout 30s --max-retries 3" +LOOT_DIR=/root/loot/nmap +SCAN_DIR=/etc/shark/nmap + + +function finish() { + LED CLEANUP + # Kill Nmap + wait $1 + kill $1 &> /dev/null + + # Sync filesystem + echo $SCAN_M > $SCAN_FILE + sync + sleep 1 + + LED FINISH + sleep 1 + + # Halt system + halt +} + +function setup() { + LED SETUP + # Create loot directory + mkdir -p $LOOT_DIR &> /dev/null + + # Create tmp scan directory + mkdir -p $SCAN_DIR &> /dev/null + + # Create tmp scan file if it doesn't exist + SCAN_FILE=$SCAN_DIR/scan-count + if [ ! -f $SCAN_FILE ]; then + touch $SCAN_FILE && echo 0 > $SCAN_FILE + fi + + # Find IP address and subnet + NETMODE DHCP_CLIENT + while [ -z "$SUBNET" ]; do + sleep 1 && find_subnet + done +} + +function find_subnet() { + 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\//') +} + +function run() { + # Run setup + setup + + SCAN_N=$(cat $SCAN_FILE) + SCAN_M=$(( $SCAN_N + 1 )) + + LED ATTACK + # Start scan + nmap $NMAP_OPTIONS $SUBNET -oN $LOOT_DIR/nmap-scan_$SCAN_M.txt &>/dev/null & + tpid=$! + + finish $tpid +} + + +# Run payload +run & diff --git a/usr/bin/BATTERY b/usr/bin/BATTERY new file mode 100755 index 0000000..d43b853 --- /dev/null +++ b/usr/bin/BATTERY @@ -0,0 +1,25 @@ +#!/bin/bash + +function setup() { + echo $1 > /sys/class/gpio/export 2>/dev/null + echo in > /sys/class/gpio/gpio$1/direction 2>/dev/null +} + +function check_gpio() { + if [ ! -d /sys/class/gpio/gpio$1 ]; then + setup $1 + fi + state=$(cat /sys/class/gpio/gpio$1/value) + echo $state +} + +gpio40=$(check_gpio 40) +gpio41=$(check_gpio 41) + +if [ $gpio40 -eq "0" ] && [ $gpio41 -eq "0" ]; then + echo "discharging" +elif [ $gpio40 -eq "0" ]; then + echo "full" +elif [ $gpio41 -eq "0" ]; then + echo "charging" +fi diff --git a/usr/bin/DO_A_BARREL_ROLL b/usr/bin/DO_A_BARREL_ROLL new file mode 100755 index 0000000..3953454 --- /dev/null +++ b/usr/bin/DO_A_BARREL_ROLL @@ -0,0 +1,2 @@ +#!/bin/bash +while true;do LED R;LED Y;LED G;LED C;LED B;LED M;done > /dev/null 2>&1 & diff --git a/usr/bin/LED b/usr/bin/LED new file mode 100755 index 0000000..b20a51a --- /dev/null +++ b/usr/bin/LED @@ -0,0 +1,243 @@ +#!/bin/bash + +RED_LED="/sys/class/leds/shark:red:system/brightness" +GREEN_LED="/sys/class/leds/shark:green:system/brightness" +BLUE_LED="/sys/class/leds/shark:blue:system/brightness" + +colors=(0 0 0) +pattern=(1 0 0 0 0 0) + +function convert() { + echo $([[ $1 -lt 20 ]] && echo 0.02 || echo $1 1000 | awk '{ print $1/$2 }') +} + +function parse_color() { + case $1 in + "R") + colors=(1 0 0) + ;; + "G") + colors=(0 1 0) + ;; + "B") + colors=(0 0 1) + ;; + "Y") + colors=(1 1 0) + ;; + "C") + colors=(0 1 1) + ;; + "M") + colors=(1 0 1) + ;; + "W") + colors=(1 1 1) + ;; + *) + return 1 + ;; + esac +} + +function parse_pattern() { + local INVERTED="0" + [[ "$(echo $1 | head -c1)" == "I" ]] && { + INVERTED="1" + } + case $1 in + "SLOW") + pattern=(0 0 1 $(convert 1000) $(convert 1000) 1) + ;; + "FAST") + pattern=(0 0 1 $(convert 100) $(convert 100) 1) + ;; + "VERYFAST") + pattern=(0 0 1 $(convert 10) $(convert 10) 1) + ;; + "ISINGLE" | "SINGLE") + pattern=(0 $INVERTED 1 $(convert 100) $(convert 1000) 1) + ;; + "IDOUBLE" | "DOUBLE") + pattern=(0 $INVERTED 2 $(convert 100) $(convert 1000) 1) + ;; + "ITRIPLE" | "TRIPLE") + pattern=(0 $INVERTED 3 $(convert 100) $(convert 1000) 1) + ;; + "IQUAD" | "QUAD") + pattern=(0 $INVERTED 4 $(convert 100) $(convert 1000) 1) + ;; + "IQUIN" | "QUIN") + pattern=(0 $INVERTED 5 $(convert 100) $(convert 1000) 1) + ;; + "SUCCESS") + pattern=(0 0 1 $(convert 10) $(convert 10) 0) + ;; + *) + [[ $1 =~ ^-?[0-9]+$ ]] && pattern=(0 0 1 $(convert $1) $(convert $1) 1) || pattern=(1 0 0 0 0 0) + ;; + esac + return 0 +} + +function parse_state() { + + local STATENUM="1" + [[ $1 =~ ^[A-Z]+[1-5]$ ]] && { + STATENUM="${1: -1}" + } + + case $1 in + "SETUP") + parse_color "M" + parse_pattern "SOLID" + ;; + "FAIL" | FAIL[1-3]) + parse_color "R" + parse_pattern "SLOW" + pattern[3]=$(convert $(echo -n 1000 | head -c $((5-$STATENUM)))) + ;; + "ATTACK" | STAGE[1-5]) + parse_color "Y" + parse_pattern "SINGLE" + pattern[2]=$STATENUM + ;; + "SPECIAL" | SPECIAL[1-5]) + parse_color "C" + parse_pattern "ISINGLE" + pattern[2]=$STATENUM + ;; + "CLEANUP") + parse_color "W" + parse_pattern "FAST" + ;; + "FINISH") + parse_color "G" + parse_pattern "SUCCESS" + ;; + "OFF") + ;; + *) + return 1 + ;; + esac + return 0 +} + +function clear_led() { + echo 0 > $RED_LED 2>&1 + echo 0 > $GREEN_LED 2>&1 + echo 0 > $BLUE_LED 2>&1 +} + +function light_led() { + echo ${colors[0]} > $RED_LED 2>&1 + echo ${colors[1]} > $GREEN_LED 2>&1 + echo ${colors[2]} > $BLUE_LED 2>&1 +} + +function blink_loop() { + local sc=1 + until [[ "$sc" == "10" ]]; do + for i in $(seq 1 ${pattern[2]}); do + [[ "${pattern[1]}" == "0" ]] && light_led || clear_led + sleep ${pattern[3]} + [[ "${pattern[1]}" == "0" ]] && clear_led || light_led + sleep ${pattern[3]} + done + sleep ${pattern[4]} + [[ "${pattern[5]}" == "0" ]] && sc=$((sc+1)) + done + [[ "${pattern[5]}" == "0" ]] && light_led +} + +function run_led() { + parse_state $1 || { + parse_color $1 || return 1 + [[ "$#" == "2" ]] && parse_pattern $2 + } + + [[ "${pattern[0]}" == "1" ]] && { + light_led & + return 0 + } || { + blink_loop & + return 0 + } + return 1 +} + +function show_usage() { + cat << EOF +Usage: LED [COLOR] [PATTERN] or LED [STATE] + +COLORS: + R Red + G Green + B Blue + Y, R G Yellow (Commonly known as Amber) + C, G B Cyan (Commonly known as Light Blue) + M, R B Magenta (Commonly known as Violet or Purple) + W, R G B White (Combination of R + G + B) + +PATTERNS: + SOLID *Default. No blink. Used if pattern argument is omitted + SLOW Symmetric 1000ms ON, 1000ms OFF, repeating + FAST Symmetric 100ms ON, 100ms OFF, repeating + VERYFAST Symmetric 10ms ON, 10ms OFF, repeating + + SINGLE 1 100ms blink(s) ON followed by 1 second OFF, repeating + DOUBLE 2 100ms blink(s) ON followed by 1 second OFF, repeating + TRIPLE 3 100ms blink(s) ON followed by 1 second OFF, repeating + QUAD 4 100ms blink(s) ON followed by 1 second OFF, repeating + QUIN 5 100ms blink(s) ON followed by 1 second OFF, repeating + + ISINGLE 1 100ms blink(s) OFF followed by 1 second ON, repeating + IDOUBLE 2 100ms blink(s) OFF followed by 1 second ON, repeating + ITRIPLE 3 100ms blink(s) OFF followed by 1 second ON, repeating + IQUAD 4 100ms blink(s) OFF followed by 1 second ON, repeating + IQUIN 5 100ms blink(s) OFF followed by 1 second ON, repeating + + SUCCESS 1000ms VERYFAST blink followed by SOLID + # Custom value in ms for continuous symmetric blinking + +STATES: +In addition to the combinations of COLORS and PATTERNS listed above, +these standardized LED STATES may be used to indicate payload status: + + SETUP M SOLID Magenta solid + + FAIL R SLOW Red slow blink + FAIL1 R SLOW Red slow blink + FAIL2 R FAST Red fast blink + FAIL3 R VERYFAST Red very fast blink + + ATTACK Y SINGLE Yellow single blink + STAGE1 Y SINGLE Yellow single blink + STAGE2 Y DOUBLE Yellow double blink + STAGE3 Y TRIPLE Yellow triple blink + STAGE4 Y QUAD Yellow quadruple blink + STAGE5 Y QUIN Yellow quintuple blink + + SPECIAL C ISINGLE Cyan inverted single blink + SPECIAL1 C ISINGLE Cyan inverted single blink + SPECIAL2 C IDOUBLE Cyan inverted double blink + SPECIAL3 C ITRIPLE Cyan inverted triple blink + SPECIAL4 C IQUAD Cyan inverted quadruple blink + SPECIAL5 C IQUIN Cyan inverted quintuple blink + + CLEANUP W FAST White fast blink + FINISH G SUCCESS Green very fast blink followed by SOLID + + OFF Turns the LED off + + +Examples: + LED Y SINGLE + LED M 500 + LED SETUP +EOF +} + +ps | grep LED | grep -v grep | awk '{print $1}' | grep -v $$ | xargs kill -9 &> /dev/null +run_led $@ || show_usage diff --git a/usr/bin/NETMODE b/usr/bin/NETMODE new file mode 100755 index 0000000..f9c695b --- /dev/null +++ b/usr/bin/NETMODE @@ -0,0 +1,23 @@ +#!/bin/bash + +function show_usage() { + echo "Usage: $0 [DHCP_CLIENT|DHCP_SERVER]" + echo "" +} + +case $1 in + "DHCP_CLIENT") + uci set network.lan.proto='dhcp' + ;; + "DHCP_SERVER") + uci set network.lan.proto='none' + /etc/init.d/odhcpd start + ;; + *) + show_usage + exit 0 + ;; +esac + +uci commit network +/etc/init.d/network restart diff --git a/usr/bin/SWITCH b/usr/bin/SWITCH new file mode 100755 index 0000000..6c9cc2e --- /dev/null +++ b/usr/bin/SWITCH @@ -0,0 +1,25 @@ +#!/bin/bash + +function setup() { + echo $1 > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio$1/direction +} + +function check_gpio() { + if [ ! -d /sys/class/gpio/gpio$1 ]; then + setup $1 + fi + state=$(cat /sys/class/gpio/gpio$1/value) + echo $state +} + +gpio0=$(check_gpio 0) +gpio2=$(check_gpio 2) + +if [ $gpio0 -eq "0" ] && [ $gpio2 -eq "0" ]; then + echo "switch1" +elif [ $gpio0 -eq "0" ]; then + echo "switch3" +elif [ $gpio2 -eq "0" ]; then + echo "switch2" +fi diff --git a/usr/bin/cleanup b/usr/bin/cleanup new file mode 100755 index 0000000..679e8be --- /dev/null +++ b/usr/bin/cleanup @@ -0,0 +1,12 @@ +#!/bin/bash + +# List of directories to clean +DIRS=( + ~/.ssh + /root/loot +) + +# Clean up each directory +for d in ${DIRS[@]}; do + [[ -d $d ]] && rm -rf $d +done diff --git a/usr/bin/shark_framework b/usr/bin/shark_framework new file mode 100755 index 0000000..33ed895 --- /dev/null +++ b/usr/bin/shark_framework @@ -0,0 +1,248 @@ +#!/bin/bash + +LOG="logger -t Shark [*]" +LOG_ERR="logger -t Shark -p 3 [!]" + +MODE="OFF" +SWITCH_POSITION=$(/usr/bin/SWITCH) + +function upgrade_leds() { + /usr/bin/LED OFF + while true + do + echo 1 > /sys/class/leds/shark:red:system/brightness + sleep 0.2 + echo 0 > /sys/class/leds/shark:red:system/brightness + echo 1 > /sys/class/leds/shark:blue:system/brightness + sleep 0.2 + echo 0 > /sys/class/leds/shark:blue:system/brightness + done +} + +# $1: Upgrade file +# $2: MD5 file +# $3: Upgrade file size in bytes +function extract_md5() { + dd if=$1 of=$2 skip=$3 bs=1 count=33 +} + +# $1: Upgrade file +# $2: MD5 file +function verify_md5() { + expected=$(cat $2) + checksum=$(md5sum $1 | awk '{print $1}') + [[ $expected = $checksum ]] && { + return 0 + } + return 1 +} + +# $1: Upgrade file +# $2: Upgrade file size in bytes +function truncate_upgrade() { + dd if=/dev/null of=$1 bs=1 seek=$2 +} + +function execute_upgrade() { + # Check for upgrade file in default location + $LOG "Checking for firmware upgrade" + upgrade_file=$(ls /root/upgrade-*.bin 2>/dev/null | tail -n1) + + [[ -f $upgrade_file ]] && { + # Upgrade file found + $LOG "Firmware upgrade found" + + $LOG "Verifying firmware upgrade" + upgrade_file_size=$(( $(ls -l $upgrade_file | awk '{print $5}') - 33 )) + + # Extract md5sum from upgrade file + extract_md5 $upgrade_file /tmp/upgrade.md5 $upgrade_file_size + + cp $upgrade_file /tmp/upgrade.bin + truncate_upgrade /tmp/upgrade.bin $upgrade_file_size + + # Verify upgrade file + verify_md5 /tmp/upgrade.bin /tmp/upgrade.md5 || { + # Upgrade file not verified; exit + $LOG "Firmware upgrade not verified. File may be corrupt" + LED FAIL & + return 1 + } + $LOG "Firmware upgrade verified" + LED OFF && LED SUCCESS + + # Check battery state first + $LOG "Checking device power state" + battery_state=$(/usr/bin/BATTERY) + [[ $battery_state = "discharging" ]] && { + # Device is not plugged in + $LOG "Device is not powered. Do not attempt firmware upgrade" + return 1 + } + $LOG "Device is powered" + + # Remove upgrade file + rm -rf $upgrade_file + sync + + # Upgrade file verified; run upgrade + $LOG "Executing UPGRADE" + sleep 2 && upgrade_leds & + echo "sysupgrade -n /tmp/upgrade.bin" | at now + + exit + } || { + # Upgrade file not found; enter arming mode + $LOG "Firmware upgrade not found" + return 1 + } +} + +function execute_payload() { + $LOG "Executing PAYLOAD" + + if [ ! -d /root/loot ]; then + mkdir -p /root/loot; + fi + + payload_path="/root/payload" + payload=$(ls $payload_path/payload* 2>/dev/null | tail -n1) + + case $(basename $payload) in + "payload.py") + echo "python $payload &> /dev/null" | at now + ;; + "payload.php") + echo "php-cli $payload &> /dev/null" | at now + ;; + "payload" | "payload.sh" | "payload.txt") + sed -i 's/\r//g' $payload + echo "bash -C '$payload'" | at now + ;; + *) + /usr/bin/LED FAIL + ;; + esac +} + +function configure_network() { + cp /usr/lib/config/${SWITCH_POSITION}/network /etc/config/network + /etc/init.d/network restart +} + +function start_http() { + /etc/init.d/uhttpd start +} + +function stop_http() { + /etc/init.d/uhttpd stop +} + +function start_ssh() { + /etc/init.d/sshd start +} + +function stop_ssh() { + /etc/init.d/sshd stop +} + +function enter_attack_mode() { + $LOG "Entering ATTACK mode" + MODE="ATTACK" + /usr/bin/LED OFF + + configure_network + stop_http + stop_ssh + + execute_payload + + enter_idle_mode +} + +function enter_arming_mode() { + $LOG "Entering ARMING mode" + MODE="ARMING" + /usr/bin/LED OFF + + configure_network + start_http + start_ssh + + enter_idle_mode +} + +function enter_off_mode() { + $LOG "Entering OFF mode" + MODE="OFF" + /usr/bin/LED OFF + + stop_http + stop_ssh + + enter_idle_mode +} + +function enter_idle_mode() { + $LOG "Entering IDLE mode" + while true + do + if [[ $MODE = "ARMING" ]] || [[ $MODE = "OFF" ]]; then + BATTERY_STATE=$(/usr/bin/BATTERY) + case $BATTERY_STATE in + "charging") + /usr/bin/LED B SLOW + ;; + "full") + /usr/bin/LED B + ;; + *) + /usr/bin/LED Y SLOW + if [[ $MODE = "OFF" ]]; then + sleep 2 && halt + fi + ;; + esac + fi + + SWITCH_POSITION=$(/usr/bin/SWITCH) + case $SWITCH_POSITION in + "switch3") + if [[ $MODE != "ATTACK" ]]; then + enter_attack_mode + fi + ;; + "switch2") + if [[ $MODE != "ARMING" ]]; then + execute_upgrade || enter_arming_mode + fi + ;; + *) + if [[ $MODE != "OFF" ]]; then + enter_off_mode + fi + ;; + esac + sleep 1 + done +} + + +function run() { + case $SWITCH_POSITION in + "switch3") + enter_attack_mode + ;; + "switch2") + execute_upgrade || enter_arming_mode + ;; + *) + enter_off_mode + ;; + esac +} + + +# Start framework after a short wait +sleep 2 +run &> /dev/null & diff --git a/usr/lib/config/switch2/network b/usr/lib/config/switch2/network new file mode 100644 index 0000000..4ae66f0 --- /dev/null +++ b/usr/lib/config/switch2/network @@ -0,0 +1,14 @@ + +config interface 'loopback' + option ifname 'lo' + option proto 'static' + option ipaddr '127.0.0.1' + option netmask '255.0.0.0' + +config interface 'lan' + option ifname 'eth0' + option proto 'static' + option ipaddr '172.16.24.1' + option netmask '255.255.255.0' + option ip6assign '60' + diff --git a/usr/lib/config/switch3/network b/usr/lib/config/switch3/network new file mode 100644 index 0000000..9af9e8a --- /dev/null +++ b/usr/lib/config/switch3/network @@ -0,0 +1,11 @@ + +config interface 'loopback' + option ifname 'lo' + option proto 'static' + option ipaddr '127.0.0.1' + option netmask '255.0.0.0' + +config interface 'lan' + option ifname 'eth0' + option proto 'none' + diff --git a/www b/www new file mode 160000 index 0000000..4094356 --- /dev/null +++ b/www @@ -0,0 +1 @@ +Subproject commit 4094356dec25ea2dafd8b385887be0fe16a7d282