Housekeeping (#7)

* fix LED killing

* do not autostart unneeded services

ntp: we don't want to leak in attack mode and arming mode doesn't even
have internet.  user's who want this can start it themselves
dnsmasq: we should start this when needed rather than killing it when
not needed, speed boot by not starting then killing

* NETMODE: use dnsmasq

netmode was improperly calling odhcpd when we use dnsmasq, just call
dnsmasq

* start dnsmasq when needed

have shark service start dnsmasq in arming mode and stop it in attack
and off mode

* randomize mac with macchanger

currently mac is randomized because it is unable to read the actual mac.
If there gets fixed then the mac won't be randomized.  Let's
intentionally randomize the mac to be sure we are random enough

* ensure netmode dhcp_server provides default gateway

* prototype out switching between gateway and no gateway

* actually disable gateway in arming mode

* disable openvpn

I don't know why this is trying to start, but let's not

* better LED anti-suicide

* permissions count

* execute_payload: fix shellcheck warnings

* convert BATTERY to posix

runtime cut from 0.051s to 0.021s on average

* shellcheck cleanup

simplify script while doing it, use faster sh instead of bash

* DO_A_BARREL_ROOL: this was posix anyway, so use posix

* execute_payload: mostly posix, consider refactor

* cleanup LED a bit

partially elminate bashisms when possible to do cleanly
shellcheck fixes for anti-hari kari (and it's faster)

* POSIX NETMODE

this was already posix except for function definitions

* POSIX shark_framework

fix minor logic error and posixify

* shark_framework: save an awk

* SWITCH: posix

* LED: fix logic for SC2015 warnings

* move wait_for_link and add wait_for_no_link

a few additional fixes based on testing

* fix macchanger and wait_for_link

* remove unneeded note

* This is where you change the mac address

* We do not need network in off mode, no services anyway

* ensure no dhcp during attack mode until requested

* bash or python, but not php

* The function is simple enough to not need a comment --Foxtrot
dev
Zero_Chaos 2020-01-23 21:44:17 -05:00 committed by Marc
parent 6cb3073db3
commit 5aa0ef7c56
9 changed files with 205 additions and 132 deletions

View File

@ -26,6 +26,18 @@ echo $(uci get system.@system[0].hostname) > /proc/sys/kernel/hostname
/etc/init.d/odhcpd disable /etc/init.d/odhcpd disable
/etc/init.d/odhcpd stop /etc/init.d/odhcpd stop
# Disable dnsmasq (controlled by shark service or NETMODE)
/etc/init.d/dnsmasq disable
/etc/init.d/dnsmasq stop
# Disable ntpd
/etc/init.d/sysntpd disable
/etc/init.d/sysntpd stop
# Disable openvpn
/etc/init.d/openvpn disable
/etc/init.d/openvpn stop
# Disable uHTTPd web server # Disable uHTTPd web server
/etc/init.d/uhttpd disable /etc/init.d/uhttpd disable
/etc/init.d/uhttpd stop /etc/init.d/uhttpd stop

View File

@ -1,25 +1,25 @@
#!/bin/bash #!/bin/sh
function setup() { setup() {
echo $1 > /sys/class/gpio/export 2>/dev/null echo "${1}" > /sys/class/gpio/export 2>/dev/null
echo in > /sys/class/gpio/gpio$1/direction 2>/dev/null echo in > "/sys/class/gpio/gpio${1}/direction" 2>/dev/null
} }
function check_gpio() { check_gpio() {
if [ ! -d /sys/class/gpio/gpio$1 ]; then if [ ! -d "/sys/class/gpio/gpio${1}" ]; then
setup $1 setup "${1}"
fi fi
state=$(cat /sys/class/gpio/gpio$1/value) state=$(cat "/sys/class/gpio/gpio${1}/value")
echo $state echo "${state}"
} }
gpio40=$(check_gpio 40) gpio40=$(check_gpio 40)
gpio41=$(check_gpio 41) gpio41=$(check_gpio 41)
if [ $gpio40 -eq "0" ] && [ $gpio41 -eq "0" ]; then if [ "${gpio40}" -eq "0" ] && [ "${gpio41}" -eq "0" ]; then
echo "discharging" echo "discharging"
elif [ $gpio40 -eq "0" ]; then elif [ "${gpio40}" -eq "0" ]; then
echo "full" echo "full"
elif [ $gpio41 -eq "0" ]; then elif [ "${gpio41}" -eq "0" ]; then
echo "charging" echo "charging"
fi fi

View File

@ -1,2 +1,18 @@
#!/bin/bash #!/bin/sh
while true;do LED R;LED Y;LED G;LED C;LED B;LED M;done > /dev/null 2>&1 &
roll() {
while true; do
LED R
LED Y
LED G
LED C
LED B
LED M
done
}
if pgrep -f DO_A_BARREL_ROLL | grep -qvE "$$|${PPID}"; then
kill "$(pgrep -f DO_A_BARREL_ROLL | grep -vE "$$|${PPID}" | tr '\n' ' ')" > /dev/null 2>&1
fi
roll > /dev/null 2>&1 &

View File

@ -8,7 +8,11 @@ colors=(0 0 0)
pattern=(1 0 0 0 0 0) pattern=(1 0 0 0 0 0)
function convert() { function convert() {
echo $([[ $1 -lt 20 ]] && echo 0.02 || echo $1 1000 | awk '{ print $1/$2 }') if [ "${1}" -lt 20 ]; then
echo 0.02
else
echo "${1}" 1000 | awk '{ print $1/$2 }'
fi
} }
function parse_color() { function parse_color() {
@ -42,7 +46,7 @@ function parse_color() {
function parse_pattern() { function parse_pattern() {
local INVERTED="0" local INVERTED="0"
[[ "$(echo $1 | head -c1)" == "I" ]] && { [[ "$(echo ${1} | head -c1)" == "I" ]] && {
INVERTED="1" INVERTED="1"
} }
case $1 in case $1 in
@ -99,7 +103,7 @@ function parse_state() {
"FAIL" | FAIL[1-3]) "FAIL" | FAIL[1-3])
parse_color "R" parse_color "R"
parse_pattern "SLOW" parse_pattern "SLOW"
pattern[3]=$(convert $(echo -n 1000 | head -c $((5-$STATENUM)))) pattern[3]=$(convert "$(echo -n 1000 | head -c $((5-STATENUM)))")
;; ;;
"ATTACK" | STAGE[1-5]) "ATTACK" | STAGE[1-5])
parse_color "Y" parse_color "Y"
@ -135,39 +139,47 @@ function clear_led() {
} }
function light_led() { function light_led() {
echo ${colors[0]} > $RED_LED 2>&1 echo "${colors[0]}" > $RED_LED 2>&1
echo ${colors[1]} > $GREEN_LED 2>&1 echo "${colors[1]}" > $GREEN_LED 2>&1
echo ${colors[2]} > $BLUE_LED 2>&1 echo "${colors[2]}" > $BLUE_LED 2>&1
} }
function blink_loop() { function blink_loop() {
local sc=1 local sc=1
until [[ "$sc" == "10" ]]; do until [[ "$sc" == "10" ]]; do
for i in $(seq 1 ${pattern[2]}); do for i in $(seq 1 ${pattern[2]}); do
[[ "${pattern[1]}" == "0" ]] && light_led || clear_led if [ "${pattern[1]}" == "0" ];then
sleep ${pattern[3]} light_led
[[ "${pattern[1]}" == "0" ]] && clear_led || light_led else
sleep ${pattern[3]} clear_led
fi
sleep "${pattern[3]}"
if [ "${pattern[1]}" == "0" ];then
clear_led
else
light_led
fi
sleep "${pattern[3]}"
done done
sleep ${pattern[4]} sleep "${pattern[4]}"
[[ "${pattern[5]}" == "0" ]] && sc=$((sc+1)) [[ "${pattern[5]}" == "0" ]] && sc=$((sc+1))
done done
[[ "${pattern[5]}" == "0" ]] && light_led [[ "${pattern[5]}" == "0" ]] && light_led
} }
function run_led() { function run_led() {
parse_state $1 || { parse_state "${1}" || {
parse_color $1 || return 1 parse_color "${1}" || return 1
[[ "$#" == "2" ]] && parse_pattern $2 [[ "$#" == "2" ]] && parse_pattern "${2}"
} }
[[ "${pattern[0]}" == "1" ]] && { if [ "${pattern[0]}" == "1" ];then
light_led & light_led &
return 0 return 0
} || { else
blink_loop & blink_loop &
return 0 return 0
} fi
return 1 return 1
} }
@ -243,5 +255,12 @@ Examples:
EOF EOF
} }
pkill -9 LED &> /dev/null #so pgrep/pkill exclude their own pid, but not their parent
run_led $@ || show_usage #the parent is this script, which we don't want to kill
if pgrep -f LED | grep -qvE "$$|${PPID}"; then
kill "$(pgrep -f LED | grep -vE "$$|${PPID}" | tr '\n' ' ')" > /dev/null 2>&1
fi
if pgrep -f DO_A_BARREL_ROLL | grep -qvE "$$|${PPID}"; then
kill "$(pgrep -f DO_A_BARREL_ROLL | grep -vE "$$|${PPID}" | tr '\n' ' ')" > /dev/null 2>&1
fi
run_led "$@" || show_usage

View File

@ -1,34 +1,37 @@
#!/bin/bash #!/bin/sh
function show_usage() { show_usage() {
echo "Usage: $0 [DHCP_CLIENT|DHCP_SERVER|AUTO]" echo "Usage: $0 [DHCP_CLIENT|DHCP_SERVER|AUTO]"
echo "" echo ""
} }
function shut_it_all_down() { shut_it_all_down() {
#we are restarting, possibly with new config, or reversing dhcp roles /etc/init.d/dnsmasq stop
#kill 'em all, let the user sort them out pkill -9 dnsmasq #just in case
/etc/init.d/odhcpd stop
pkill -9 dnsmasq #odhcpd starts dnsmasq but fails to stop it
pkill -9 udhcpc #this is the observed dhcp client pkill -9 udhcpc #this is the observed dhcp client
pkill -9 odhcpcd #just in case pkill -9 odhcpcd #just in case
} }
function configure_client() { configure_dhcp_client() {
shut_it_all_down shut_it_all_down
uci set network.lan.proto='dhcp' uci set network.lan.proto='dhcp'
} }
function configure_server() { configure_dhcp_server() {
shut_it_all_down shut_it_all_down
uci set network.lan.proto='static' uci set network.lan.proto='static'
uci set network.lan.ipaddr='172.16.24.1' uci set network.lan.ipaddr='172.16.24.1'
uci set network.lan.netmask='255.255.255.0' uci set network.lan.netmask='255.255.255.0'
uci set network.lan.ip6assign='60' uci set network.lan.ip6assign='60'
/etc/init.d/odhcpd start #remove old dhcp options before setting new
uci -q delete dhcp.lan.dhcp_option
uci add_list dhcp.lan.dhcp_option="3,172.16.24.1"
#disables gateway
#uci add_list dhcp.lan.dhcp_option="3"
/etc/init.d/dnsmasq start
} }
function blink() { blink() {
count 3 count 3
while [ "${count}" -gt 0 ]; do while [ "${count}" -gt 0 ]; do
LED "${1}" LED "${1}"
@ -41,10 +44,10 @@ function blink() {
case $1 in case $1 in
"DHCP_CLIENT") "DHCP_CLIENT")
configure_client configure_dhcp_client
;; ;;
"DHCP_SERVER") "DHCP_SERVER")
configure_server configure_dhcp_server
;; ;;
"AUTO") "AUTO")
#make sure nothing interferes #make sure nothing interferes
@ -54,10 +57,10 @@ case $1 in
if echo "${sniffed}" | grep -q 'DHCP-Message Option 53, length 1: Discover' && \ if echo "${sniffed}" | grep -q 'DHCP-Message Option 53, length 1: Discover' && \
! echo "${sniffed}" | grep -q 'DHCP-Message Option 53, length 1: Request'; then ! echo "${sniffed}" | grep -q 'DHCP-Message Option 53, length 1: Request'; then
#we saw a dhcp discover but no dhcp request, so someone wants a dhcp server and didn't find one #we saw a dhcp discover but no dhcp request, so someone wants a dhcp server and didn't find one
configure_server configure_dhcp_server
echo 'blink SETUP Y' | at now echo 'blink SETUP Y' | at now
else else
configure_client configure_dhcp_client
echo 'blink SETUP W' | at now echo 'blink SETUP W' | at now
fi fi
;; ;;

View File

@ -1,11 +1,11 @@
#!/bin/bash #!/bin/sh
function setup() { setup() {
echo "${1}" > /sys/class/gpio/export echo "${1}" > /sys/class/gpio/export
echo in > "/sys/class/gpio/gpio${1}/direction" echo in > "/sys/class/gpio/gpio${1}/direction"
} }
function check_gpio() { check_gpio() {
if [ ! -d "/sys/class/gpio/gpio${1}" ]; then if [ ! -d "/sys/class/gpio/gpio${1}" ]; then
setup "${1}" setup "${1}"
fi fi

View File

@ -1,12 +1,6 @@
#!/bin/bash #!/bin/sh
# List of directories to clean
DIRS=(
~/.ssh
/root/loot
)
# Clean up each directory # Clean up each directory
for d in ${DIRS[@]}; do for d in "${HOME}/.ssh" "/root/loot"; do
[[ -d $d ]] && rm -rf $d [ -d "${d}" ] && rm -rf "${d}"
done done

37
usr/bin/execute_payload Normal file → Executable file
View File

@ -1,32 +1,49 @@
#!/bin/bash #!/bin/bash
LOG="logger -t Shark [*]" LOG="logger -t Shark [*]"
$LOG "Executing PAYLOAD" $LOG "Prepping PAYLOAD environment"
if [ ! -d /root/loot ]; then if [ ! -d /root/loot ]; then
mkdir -p /root/loot; mkdir -p /root/loot;
fi fi
wait_for_link() {
LED SETUP
until swconfig dev switch0 port 0 get link | grep -q 'link:up'; do
sleep 1
done
LED LINKSETUP
}
wait_for_no_link() {
LED LINKSETUP
until swconfig dev switch0 port 0 get link | grep -q 'link:down'; do
sleep 1
done
LED SETUP
}
payload_path="/root/payload" payload_path="/root/payload"
payload=$(ls $payload_path/payload* 2>/dev/null | tail -n1) payload=$(find "${payload_path}"/payload* 2>/dev/null | tail -n1)
extension_path="/root/payload/extensions/" extension_path="/root/payload/extensions/"
if [ -d "${extension_path}" ] && [ -n "$(ls -A ${extension_path})" ]; then if [ -d "${extension_path}" ] && [ -n "$(ls -A ${extension_path})" ]; then
for extension in ${extension_path}*; do for extension in "${extension_path}"*; do
source "${extension}" # shellcheck source=/dev/null
. "${extension}"
done done
#declare is the only non-posix, and likely isn't needed
eval "$(declare -F | sed -e 's/-f /-fx /')" eval "$(declare -F | sed -e 's/-f /-fx /')"
fi fi
wait_for_link
$LOG "Running requested PAYLOAD"
case $(basename "${payload}") in case $(basename "${payload}") in
"payload.py") "payload.py")
python "${payload}" &> /dev/null python "${payload}" > /dev/null 2>&1
;;
"payload.php")
php-cli "${payload}" &> /dev/null
;; ;;
"payload" | "payload.sh" | "payload.txt") "payload" | "payload.sh" | "payload.txt")
sed -i 's/\r//g' $payload sed -i 's/\r//g' "${payload}"
bash -C "${payload}" &> /dev/null bash -C "${payload}" > /dev/null 2>&1
;; ;;
*) *)
/usr/bin/LED FAIL /usr/bin/LED FAIL

View File

@ -1,12 +1,12 @@
#!/bin/bash #!/bin/sh
LOG="logger -t Shark [*]" export LOG="logger -t Shark [*]"
LOG_ERR="logger -t Shark -p 3 [!]" export LOG_ERR="logger -t Shark -p 3 [!]"
MODE="OFF" MODE="OFF"
SWITCH_POSITION=$(/usr/bin/SWITCH) SWITCH_POSITION=$(/usr/bin/SWITCH)
function upgrade_leds() { upgrade_leds() {
/usr/bin/LED OFF /usr/bin/LED OFF
while true while true
do do
@ -22,16 +22,16 @@ function upgrade_leds() {
# $1: Upgrade file # $1: Upgrade file
# $2: MD5 file # $2: MD5 file
# $3: Upgrade file size in bytes # $3: Upgrade file size in bytes
function extract_md5() { extract_md5() {
dd if=$1 of=$2 skip=$3 bs=1 count=33 dd if="${1}" of="${2}" skip="${3}" bs=1 count=33
} }
# $1: Upgrade file # $1: Upgrade file
# $2: MD5 file # $2: MD5 file
function verify_md5() { verify_md5() {
expected=$(cat $2) expected=$(cat "${2}")
checksum=$(md5sum $1 | awk '{print $1}') checksum=$(md5sum "${1}" | awk '{print $1}')
[[ $expected = $checksum ]] && { [ "${expected}" = "${checksum}" ] && {
return 0 return 0
} }
return 1 return 1
@ -39,50 +39,50 @@ function verify_md5() {
# $1: Upgrade file # $1: Upgrade file
# $2: Upgrade file size in bytes # $2: Upgrade file size in bytes
function truncate_upgrade() { truncate_upgrade() {
dd if=/dev/null of=$1 bs=1 seek=$2 dd if=/dev/null of="${1}" bs=1 seek="${2}"
} }
function execute_upgrade() { execute_upgrade() {
# Check for upgrade file in default location # Check for upgrade file in default location
$LOG "Checking for firmware upgrade" $LOG "Checking for firmware upgrade"
upgrade_file=$(ls /root/upgrade-*.bin 2>/dev/null | tail -n1) upgrade_file=$(find /root/upgrade-*.bin -type f 2>/dev/null | tail -n1)
[[ -f $upgrade_file ]] && { if [ -f "${upgrade_file}" ]; then
# Upgrade file found # Upgrade file found
$LOG "Firmware upgrade found" $LOG "Firmware upgrade found"
$LOG "Verifying firmware upgrade" $LOG "Verifying firmware upgrade"
upgrade_file_size=$(( $(ls -l $upgrade_file | awk '{print $5}') - 33 )) upgrade_file_size=$(( $(wc -c "${upgrade_file}") - 33 ))
# Extract md5sum from upgrade file # Extract md5sum from upgrade file
extract_md5 $upgrade_file /tmp/upgrade.md5 $upgrade_file_size extract_md5 "${upgrade_file}" /tmp/upgrade.md5 "${upgrade_file_size}"
cp $upgrade_file /tmp/upgrade.bin cp "${upgrade_file}" /tmp/upgrade.bin
truncate_upgrade /tmp/upgrade.bin $upgrade_file_size truncate_upgrade /tmp/upgrade.bin "${upgrade_file_size}"
# Verify upgrade file # Verify upgrade file
verify_md5 /tmp/upgrade.bin /tmp/upgrade.md5 || { if ! verify_md5 /tmp/upgrade.bin /tmp/upgrade.md5; then
# Upgrade file not verified; exit # Upgrade file not verified; exit
$LOG "Firmware upgrade not verified. File may be corrupt" $LOG "Firmware upgrade not verified. File may be corrupt"
LED FAIL & LED FAIL &
return 1 return 1
} fi
$LOG "Firmware upgrade verified" $LOG "Firmware upgrade verified"
LED OFF && LED SUCCESS LED OFF && LED SUCCESS
# Check battery state first # Check battery state first
$LOG "Checking device power state" $LOG "Checking device power state"
battery_state=$(/usr/bin/BATTERY) battery_state=$(/usr/bin/BATTERY)
[[ $battery_state = "discharging" ]] && { if [ "${battery_state}" = "discharging" ]; then
# Device is not plugged in # Device is not plugged in
$LOG "Device is not powered. Do not attempt firmware upgrade" $LOG "Device is not powered. Do not attempt firmware upgrade"
return 1 return 1
} fi
$LOG "Device is powered" $LOG "Device is powered"
# Remove upgrade file # Remove upgrade file
rm -rf $upgrade_file rm -rf "${upgrade_file}"
sync sync
# Upgrade file verified; run upgrade # Upgrade file verified; run upgrade
@ -91,88 +91,99 @@ function execute_upgrade() {
echo "sysupgrade -n /tmp/upgrade.bin" | at now echo "sysupgrade -n /tmp/upgrade.bin" | at now
exit exit
} || { else
# Upgrade file not found; enter arming mode # Upgrade file not found; enter arming mode
$LOG "Firmware upgrade not found" $LOG "Firmware upgrade not found"
return 1 return 1
} fi
} }
function wait_for_link() { configure_network() {
LED LINKSETUP
until swconfig dev switch0 port 0 get link | grep -q 'link:up'; do
sleep 1
done
LED SETUP
}
function configure_network() {
cp "/usr/lib/hak5/shark/config/${SWITCH_POSITION}/network" /etc/config/network cp "/usr/lib/hak5/shark/config/${SWITCH_POSITION}/network" /etc/config/network
/etc/init.d/network restart /etc/init.d/network restart
} }
function start_http() { start_http() {
/etc/init.d/uhttpd start /etc/init.d/uhttpd start
} }
function stop_http() { stop_http() {
/etc/init.d/uhttpd stop /etc/init.d/uhttpd stop
} }
function start_ssh() { start_ssh() {
/etc/init.d/sshd start /etc/init.d/sshd start
} }
function stop_ssh() { stop_ssh() {
/etc/init.d/sshd stop /etc/init.d/sshd stop
} }
function enter_attack_mode() { start_dnsmasq() {
#remove old dhcp options before setting new
uci -q delete dhcp.lan.dhcp_option
#disables gateway, netmode re-enables it
uci add_list dhcp.lan.dhcp_option="3"
uci commit
/etc/init.d/dnsmasq start
}
stop_dnsmasq() {
/etc/init.d/dnsmasq stop
}
enter_attack_mode() {
$LOG "Entering ATTACK mode" $LOG "Entering ATTACK mode"
MODE="ATTACK" MODE="ATTACK"
/usr/bin/LED OFF /usr/bin/LED OFF
stop_dnsmasq
ip link set eth0 down
macchanger -r eth0
configure_network configure_network
#nothing starts this, but ensure it only runs with
pkill -9 udhcpc
stop_http stop_http
stop_ssh stop_ssh
wait_for_link
echo "execute_payload" | at now echo "execute_payload" | at now
enter_idle_mode enter_idle_mode
} }
function enter_arming_mode() { enter_arming_mode() {
$LOG "Entering ARMING mode" $LOG "Entering ARMING mode"
MODE="ARMING" MODE="ARMING"
/usr/bin/LED OFF /usr/bin/LED OFF
configure_network configure_network
start_dnsmasq
start_http start_http
start_ssh start_ssh
enter_idle_mode enter_idle_mode
} }
function enter_off_mode() { enter_off_mode() {
$LOG "Entering OFF mode" $LOG "Entering OFF mode"
MODE="OFF" MODE="OFF"
/usr/bin/LED OFF /usr/bin/LED OFF
/etc/init.d/network stop
stop_dnsmasq
stop_http stop_http
stop_ssh stop_ssh
enter_idle_mode enter_idle_mode
} }
function enter_idle_mode() { enter_idle_mode() {
$LOG "Entering IDLE mode" $LOG "Entering IDLE mode"
while true while true
do do
if [[ $MODE = "ARMING" ]] || [[ $MODE = "OFF" ]]; then if [ "${MODE}" = "ARMING" ] || [ "${MODE}" = "OFF" ]; then
#ARMING mode is basically always idle which means this overrides user LED #ARMING mode is basically always idle which means this overrides user LED
#status once per second. Don't override user status with idle status. #status once per second. Don't override user status with idle status.
#pgrep LED > /dev/null || /usr/bin/LED whatever
BATTERY_STATE=$(/usr/bin/BATTERY) BATTERY_STATE=$(/usr/bin/BATTERY)
case $BATTERY_STATE in case $BATTERY_STATE in
"charging") "charging")
@ -183,8 +194,9 @@ function enter_idle_mode() {
;; ;;
*) *)
pgrep LED > /dev/null || /usr/bin/LED Y SLOW pgrep LED > /dev/null || /usr/bin/LED Y SLOW
if [[ $MODE = "OFF" ]]; then if [ "${MODE}" = "OFF" ]; then
sleep 2 && halt sleep 2
halt
fi fi
;; ;;
esac esac
@ -193,17 +205,17 @@ function enter_idle_mode() {
SWITCH_POSITION=$(/usr/bin/SWITCH) SWITCH_POSITION=$(/usr/bin/SWITCH)
case $SWITCH_POSITION in case $SWITCH_POSITION in
"switch3") "switch3")
if [[ $MODE != "ATTACK" ]]; then if [ "${MODE}" != "ATTACK" ]; then
enter_attack_mode enter_attack_mode
fi fi
;; ;;
"switch2") "switch2")
if [[ $MODE != "ARMING" ]]; then if [ "${MODE}" != "ARMING" ]; then
execute_upgrade || enter_arming_mode execute_upgrade || enter_arming_mode
fi fi
;; ;;
*) *)
if [[ $MODE != "OFF" ]]; then if [ "${MODE}" != "OFF" ]; then
enter_off_mode enter_off_mode
fi fi
;; ;;
@ -213,7 +225,7 @@ function enter_idle_mode() {
} }
function run() { run() {
case $SWITCH_POSITION in case $SWITCH_POSITION in
"switch3") "switch3")
enter_attack_mode enter_attack_mode
@ -230,4 +242,4 @@ function run() {
# Start framework after a short wait # Start framework after a short wait
sleep 2 sleep 2
run &> /dev/null & run > /dev/null 2>&1 &