summaryrefslogtreecommitdiffstats
path: root/iv/orodja/napad/exploit.sh
diff options
context:
space:
mode:
Diffstat (limited to 'iv/orodja/napad/exploit.sh')
-rwxr-xr-xiv/orodja/napad/exploit.sh151
1 files changed, 151 insertions, 0 deletions
diff --git a/iv/orodja/napad/exploit.sh b/iv/orodja/napad/exploit.sh
new file mode 100755
index 0000000..9e2cafb
--- /dev/null
+++ b/iv/orodja/napad/exploit.sh
@@ -0,0 +1,151 @@
+#!/bin/sh
+if [ x$1 = x ]
+then
+cat >&2 <<EOF
+No command. Usage: $0 <subcommand> [args ...] Subcommands:
+ once <service> <exploit> [team=$GAME_NOP_TEAM] # runs exploit once
+ loop <service> <exploit> # once per team per round, waits for next round
+<exploit> is an executable file. Flags, grepped from stdout, are submitted.
+It is called for every target with the following environment variables:
+ TARGET_IP: target IP address (uses game_target_ip from config)
+ TARGET_EXTRA: Flag IDs JSON object (uses game_flag_ids_url in config)
+ FLAG_ID_<key>: Every JSON value from flag IDs individually
+Example environment is therefore:
+ TARGET_IP=1.1.1.1 TARGET_EXTRA='{"a": "1", "b": "2"}' FLAG_ID_a=1 FLAG_ID_b=2
+In loop mode, exploit is first exec'd rapidly for still valid old rounds.
+Max execution time is $EXPLOIT_TIMEOUT seconds (EXPLOIT_TIMEOUT in config)
+Exploits are not run in parallel.
+Make sure that your system time is set CORRECTLY TO THE SECOND, it's used
+ to get the current round id. Check this on http://time.is
+Configuration values are also available in environment of exploits.
+<service> is the name of the service (used for getting flag IDs)
+Set the following environment variables to alter behaviour:
+ EXPLOIT_STDOUT=1: stdout of exploit will be printed to stderr/terminal
+ EXPLOIT_LOOP_ONCE=1: exit after executing for all valid rounds instead of
+ waiting for the next round. Only valid for loop subcommand.
+ EXPLOIT_VERBOSE=1: print _every_ line executed by $0 (set -x)
+ EXPLOIT_NOTPARALLEL=1: disable parallel even if parallel is available
+$EXPLOIT_ADDITIONAL_HELP_TEXT
+EOF
+ exit 1
+fi
+[ ${EXPLOIT_VERBOSE:-false} = false ] || set -x
+set -euo pipefail
+current_round_id()
+{ # BREAKS WHEN THERE ARE LEAP SECONDS DURING GAME
+ startunix=`date +%s --utc --date $GAME_START`
+ current=`date +%s --utc`
+ echo $((($current-$startunix)/$ROUND_DURATION))
+}
+if [ ${ROUND_ID:-x} = x ]
+then
+ export ROUND_ID=`current_round_id`
+fi
+subcommand=$1
+service=$2
+exploit=$3
+# tees stdout, collects flags, puts stdout to stderr, prints counts
+# args: team
+exploit_pipe()
+{
+ stdoutwhere=/dev/null
+ [ ! ${EXPLOIT_STDOUT:-false} = false ] && stdoutwhere=/dev/stderr
+ tee $stdoutwhere | { grep -Eo "$FLAG_REGEX_SEARCH" || :; } | while read -r line
+ do
+ echo $line $1 $ROUND_ID $service $exploit `whoami`@`hostname``pwd`
+ done | { nc -N $SUBMISSION_HOST $SUBMISSION_PORT || return $((200+$?)); } | cut -d\ -f1,2 | sort | uniq -c | tr $'\n' ' ' | cat <(printf "team=%-2d round=%d: " $1 $ROUND_ID) /dev/stdin <(echo) >&2
+}
+# args: team round
+get_flag_ids()
+{
+ set +e
+ output_flagids=$(curl --fail-with-body --no-progress-meter "`game_flag_ids_url "$service" $1 $2`")
+ curl_exit_code=$?
+ set -e
+ echo $output_flagids
+ if [ ! $curl_exit_code -eq 0 ]
+ then
+ send_error $1 "round=$round failed to get flag ids: $output_flagids" >&2
+ return 99
+ fi
+}
+# args: team message
+send_error()
+{
+ echo [$0] ERROR: team=$1: $2
+ exploit_error_handler "$service" $1 `pwd` `whoami`@`hostname` $2
+}
+case $subcommand in
+ once)
+ target_team=$GAME_NOP_TEAM
+ if [ $# -ge 4 ]
+ then
+ target_team=$4
+ fi
+ export TARGET_IP=`game_target_ip $target_team`
+ export TARGET_EXTRA="`get_flag_ids $target_team $ROUND_ID`"
+ source <(echo "$TARGET_EXTRA" | jq -r 'to_entries|map("export FLAG_ID_\(.key|sub("'"'"'";""))='"'"'\(.value|tostring|sub("'"'"'";"'"'\\\"'\\\"'"'"))'"'"'")|.[]')
+ set +e
+ timeout $EXPLOIT_TIMEOUT $exploit | exploit_pipe $target_team
+ exit_code=$?
+ set -e
+ if [ $exit_code -gt 200 ]
+ then
+ send_error $target_team "submission netcat failed with $(($exit_code-200))"
+ exit $exit_code
+ fi
+ if [ ! $exit_code -eq 0 ] && [ ! $exit_code -eq 124 ]
+ then
+ send_error $target_team "$exploit exited with $exit_code"
+ fi
+ if [ $exit_code -eq 124 ]
+ then
+ echo [$0] team=$target_team $exploit timed out >&2
+ fi
+ exit $exit_code
+ ;;
+ loop)
+ if parallel --version > /dev/null && [ ${EXPLOIT_NOTPARALLEL:-false} = false ]
+ then
+ commands_evaluator="parallel --color-failed"
+ commands_output="/dev/stdout"
+ have_parallel=true
+ echo "[$0] using parallel executions (:" >&2
+ else
+ commands_evaluator="cat /dev/stdin"
+ commands_output="/dev/null"
+ have_parallel=false
+ echo "[$0] parallel not found or disabled! zaporedno izvajanje ):" >&2
+ fi
+ round=$(($ROUND_ID-$GAME_VALID_ROUNDS))
+ while :
+ do
+ for target_team in $GAME_TEAMS
+ do
+ cmd2exec="ROUND_ID=$round $0 once '$service' $exploit $target_team"
+ if $have_parallel
+ then
+ echo $cmd2exec
+ else
+ eval $cmd2exec
+ fi
+ done | $commands_evaluator > $commands_output
+ round=$(($round+1))
+ we_slept=false
+ while [ `current_round_id` -lt $round ]
+ do # oh no we pollin thats ugly af, who cares we have
+ if [ ! ${EXPLOIT_LOOP_ONCE:-false} = false ]
+ then
+ echo [$0] breaking due to EXPLOIT_LOOP_ONCE
+ break
+ fi
+ we_slept=true
+ sleep 1 # INFINITE CPU POWAH!
+ done
+ if $we_slept
+ then # execute exploit at random time instead of at start
+ sleep $(($RANDOM%$ROUND_DURATION/2))
+ fi
+ done
+ ;;
+esac