summaryrefslogtreecommitdiffstats
path: root/iv/orodja/napad/exploit.sh
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