-
Notifications
You must be signed in to change notification settings - Fork 9
264 lines (221 loc) · 8.36 KB
/
run-server.yml
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# This GitHub Actions workflow installs several useful tools for CTFs, and
# starts a server so the user can connect and work in the virtual environment.
# This is a pretty safe environment for running random binaries from CTFs, and
# you mostly don't have to worry about fucking anything up since it starts
# fresh every time.
# Created by Jacob Strieb
# December 2020
name: Run Collaborative CTF Environment
# Only run when manually triggered
on:
workflow_dispatch:
inputs:
ngrok_token:
description: Token to use for ngrok (optional)
required: false
additional_packages:
description: Install CTF packages
required: true
type: boolean
default: true
jobs:
start_server:
name: Set up and start the collaborative CTF server
runs-on: ubuntu-20.04
steps:
- name: Install base packages
run: |
# Fix certificate issue with pyopenssl
python3 -m pip install --upgrade pip setuptools wheel pyopenssl
python -m pip install --upgrade pip setuptools wheel pyopenssl
sudo apt-get update
# NOTE: upgrading takes way too long, and doesn't seem totally
# necessary; hence it has been commented out
# sudo apt-get --yes upgrade
# NOTE: many of these are already installed; included for posterity
# TODO: add other packages for CTF stuff
PACKAGES=(
binutils
curl
wget
gcc
tmux
neovim
)
sudo apt-get --yes install ${PACKAGES[@]}
- name: Install additional packages
if: ${{ inputs.additional_packages }}
run: |
# NOTE: many of these are already installed; included for posterity
# TODO: add other packages for CTF stuff
PACKAGES=(
nmap
htop
gdb
netcat
socat
build-essential
imagemagick
jq
binwalk
exiftool
hashcat
qemu
valgrind
)
sudo apt-get --yes install ${PACKAGES[@]}
PIP_PACKAGES=(
pwntools
ciphey
ofrak
)
python3 -m pip install --upgrade ${PIP_PACKAGES[@]}
# Install pup, not available on apt
mkdir -p ~/Downloads;
cd ~/Downloads;
wget \
--output-document pup_v0.4.0_linux_amd64.zip \
"https://github.com/ericchiang/pup/releases/download/v0.4.0/pup_v0.4.0_linux_amd64.zip";
unzip pup_v0.4.0_linux_amd64.zip;
sudo mv ./pup /usr/local/bin/pup;
# Make CTF files from the repo available in the ~/ctf directory
- uses: actions/checkout@v2
- name: Move checked out repository to ~/ctf
run: |
cd
mv "$GITHUB_WORKSPACE" ~/ctf
# Re-create the workspace directory, otherwise subsequent steps start
# in a folder that doesn't exist and immediately fail
mkdir --parents "$GITHUB_WORKSPACE"
- name: Install dotfiles
run: |
cd ~/ctf/dotfiles
bash install.sh
cp ./ttyd_run.sh ~/ttyd_run.sh
cp ./ngrok.yml ~/ngrok.yml
# Change the runner password to "ctf"; by default it has no password,
# which complicates some things like connecting via SSH
echo "runner:ctf" | sudo chpasswd
# Add a command to kill the action by killing the "sleep" process
echo 'alias quit="pkill sleep"' >> ~/.bashrc
- name: Install ngrok and run in the background as a daemon
run: |
# Only proceed if there is a user-supplied authtoken for ngrok.
# Prefer one submitted with a workflow dispatch, but accept one
# stored as a repository secret.
NGROK_AUTHTOKEN="${{ github.event.inputs.ngrok_token }}"
if [ -z "$NGROK_AUTHTOKEN" ]; then
NGROK_AUTHTOKEN="${{ secrets.NGROK_TOKEN }}"
fi
if [ -z "$NGROK_AUTHTOKEN" ]; then
exit 0
fi
# Add the authtoken to the ngrok configuration file
echo "authtoken: $NGROK_AUTHTOKEN" >> ~/ngrok.yml
# Download and install ngrok
cd
wget \
--quiet \
--output-document ngrok.zip \
"https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip"
unzip ngrok.zip
sudo mv ngrok /usr/local/bin/ngrok
touch ~/ngrok.log
# Run ngrok in the background as a daemon
start-stop-daemon \
--start \
--background \
--chdir ~/ctf \
--exec /usr/local/bin/ngrok \
-- \
start \
-config ~/ngrok.yml \
ttyd ssh
- name: Install ttyd and run in the background as a daemon
run: |
# xterm is required for tmux/ttyd. Installed here to highlight that
# this is the specific part of the script that requires it.
sudo apt-get --yes install xterm
# Download and install ttyd
cd
wget \
--quiet \
--output-document ttyd \
"https://github.com/tsl0922/ttyd/releases/download/1.6.1/ttyd_linux.x86_64"
chmod +x ttyd
sudo mv ttyd /usr/local/bin/ttyd
# Run ttyd in the background as a daemon
start-stop-daemon \
--start \
--background \
--chdir ~/ctf \
--exec /usr/local/bin/ttyd \
-- \
--port 7681 \
--credential runner:ctf \
/bin/bash ~/ttyd_run.sh
- name: Install Tor and run a hidden service in the background as a daemon
run: |
sudo apt-get --yes install tor
# Sometimes it's already running for some reason...?
sudo service tor stop
sudo killall tor || true
# Generate a random port for Tor to use since the default is often
# taken
export TOR_SOCKS_PORT="$((1025 + RANDOM % 8975))"
# Run a hidden service in the background as a daemon -- allow
# connecting to the ttyd instance via a browser and allow SSH
tor \
--runasdaemon 1 \
--socksport $TOR_SOCKS_PORT \
--hiddenservicedir /home/runner/tor_service \
--hiddenserviceport "80 127.0.0.1:7681" \
--hiddenserviceport "22 127.0.0.1:22"
- name: Install PyJam and create a tunnel in the background
run: |
sudo apt-get install -y wireguard
curl https://tunnel.pyjam.as/7681 > /tmp/7681.conf
wg-quick up /tmp/7681.conf
- name: Display connection information
run: |
# Start a tmux session in the background whose window group everyone
# will share
tmux new-session -d -c ~/ctf -s ctf
echo Waiting for things to start up...
sleep 20s
echo
echo When connecting, use username "'runner'" and password "'ctf'"
echo
# Print Tor connection info
echo To connect securely over Tor:
printf "http://%s\n" "$(cat ~/tor_service/hostname)"
printf \
"ssh -o ProxyCommand='nc -x localhost:9150 %%h %%p' ssh://runner@%s\n\n" \
"$(cat ~/tor_service/hostname)"
# Print ngrok connection info (if applicable)
NGROK_AUTHTOKEN="${{ github.event.inputs.ngrok_token }}"
if [ -z "$NGROK_AUTHTOKEN" ]; then
NGROK_AUTHTOKEN="${{ secrets.NGROK_TOKEN }}"
fi
if [ -n "$NGROK_AUTHTOKEN" ]; then
echo "To connect using ngrok (i.e., not Tor):"
cat ~/ngrok.log \
| jq .url \
| grep -v "null" \
| tr -d '"' \
| sed 's/tcp:\/\/\(.*\)/ssh ssh:\/\/runner@\1/g' \
| sort
fi
echo 'To connect via PyJam (over HTTPS):'
cat /tmp/7681.conf \
| grep https \
| sed 's/.*\(https:\/\/[^ ]*\).*/\1/g'
- name: Wait...
run: |
# Wait... This process will be killed to end the Action. Return a
# non-failure exit code in any case so that there are no unnecessary
# notifications about a failed Actions workflow.
sleep 6h || true
- name: Clean up
run: |
echo Done!