blob: 729bb684906d6edc8c44cce0eab77d9d74ebacd5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#!/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
<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
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.
Make sure that your system time is set CORRECTLY TO THE SECOND, it's used
to get the current round id. Current time: `date`.
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
EOF
exit 1
fi
set -xeuo pipefail
startunix=`date +%s --utc --date $GAME_START`
current=`date +%s --utc`
if [ ${ROUND_ID:-x} = x ]
then
export ROUND_ID=`$((($current-$startunix)/$ROUND_DURATION))` # BREAKS WHEN THERE ARE LEAP SECONDS DURING GAME
fi
subcommand=$1
service=$2
exploit=$3
# tees stdout, collects flags, puts stdout to stderr, prints counts
exploit_pipe()
{
stdoutwhere=/dev/null
[ ${EXPLOIT_STDOUT:-x} = x ] && stdoutwhere=/dev/stderr
tee $stdoutwhere | grep -Eo "$FLAG_REGEX" | while read 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')
}
# 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
}
# 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 3 ]
then
target_team=$3
fi
timeout $EXPLOIT_TIMEOUT $exploit `game_target_ip $target_team` `get_flag_ids $target_team $ROUND_ID` | expoit_pipe $subcommand
exit_code=$?
if [ ! $exit_code -eq 0 ] && [ ! $exit_code -eq 124 ]
then
send_error $target_team "$exploit exited with $exit_code"
fi
;;
loop)
for round in {$ROUND_ID..}
do
for target_team in $GAME_TEAMS
do
ROUND_ID=$round $0 once $target_team
done
done
;;
esac
|