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.sh130
1 files changed, 98 insertions, 32 deletions
diff --git a/iv/orodja/napad/exploit.sh b/iv/orodja/napad/exploit.sh
index 729bb68..b482c06 100755
--- a/iv/orodja/napad/exploit.sh
+++ b/iv/orodja/napad/exploit.sh
@@ -1,84 +1,150 @@
#!/bin/sh
if [ x$1 = x ]
then
-echo >&2 <<EOF
-No command. Subcommands:
- $0 once <service> <exploit> [team=$GAME_NOP_TEAM] # runs exploit once
- $0 loop <service> <exploit> # runs an exploit in a loop once per round
+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. Args are target IP and flag IDs JSON object.
- Example: <exploit> 10.1.2.3 '{"user": "root", "pass": "hunter2"}'
-Flag IDs are also available in the environment as variables FLAG_ID_<key>:
- {"user": "root", "pass": "hunter2"} will be in environment as vars
- FLAG_ID_user=root and FLAG_ID_pass=hunter2
+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 executed in parallel.
+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. Current time: `date`.
+ 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)
-If the env. var EXPLOIT_STDOUT is set, stdout of exploit will be printed to stderr:
- "EXPLOIT_STDOUT=1 $0 loop <service> <exploit>" will also print stdout to term
-If the env. var EXPLOIT_LOOP_ONCE is set (only valid for loop mode), looping will
- stop after looping through all valid rounds and teams:
- "EXPLOIT_LOOP_ONCE=1 $0 loop <service> <exploit>" won't wait for next round
+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
EOF
exit 1
fi
-set -xeuo pipefail
-startunix=`date +%s --utc --date $GAME_START`
-current=`date +%s --utc`
+[ ${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-$startunix)/$ROUND_DURATION))` # BREAKS WHEN THERE ARE LEAP SECONDS DURING GAME
+ 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:-x} = x ] && stdoutwhere=/dev/stderr
- tee $stdoutwhere | grep -Eo "$FLAG_REGEX" | while read line
+ [ ! ${EXPLOIT_STDOUT:-false} = false ] && stdoutwhere=/dev/stderr
+ tee $stdoutwhere | { grep -Eo "$FLAG_REGEX_SEARCH" || :; } | while read -r line
do
- echo $line `whoami`@`hostname``pwd` $exploit $service
- done | nc -v $SUBMISSION_HOST $SUBMISSION_PORT | cut -d\ -f1 | sort | uniq -c | tr $'\n' ' ' | cat /dev/stdin <(echo $'\t<= izkupiček poslanih zastavic')
+ 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()
{
- output_flagids=$(curl --fail-with-body --no-progress-bar `game_flag_ids_url $service $1 $2`)
- echo [$0] ERROR: failed to get flag ids: $output_flagids >&2
+ 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
+ exploit_error_handler "$service" $1 `pwd` `whoami`@`hostname` $2
}
case $subcommand in
once)
target_team=$GAME_NOP_TEAM
- if [ $# -ge 3 ]
+ if [ $# -ge 4 ]
then
- target_team=$3
+ target_team=$4
fi
- timeout $EXPLOIT_TIMEOUT $exploit `game_target_ip $target_team` `get_flag_ids $target_team $ROUND_ID` | expoit_pipe $subcommand
+ 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)
- for round in {$ROUND_ID..}
+ 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
- ROUND_ID=$round $0 once $target_team
+ 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