-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSWPAG.htm
More file actions
305 lines (289 loc) · 25.6 KB
/
Copy pathSWPAG.htm
File metadata and controls
305 lines (289 loc) · 25.6 KB
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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module client</title>
<meta charset="utf-8">
</head><body bgcolor="#f0f0f8">
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>client</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/edg/code/swpag-client/swpag_client/client.py">/home/edg/code/swpag-client/swpag_client/client.py</a></font></td></tr></table>
<p><tt># The SWPAG game client<br>
Written by subwire and the SWPAG team, 2017<br>
<br>
Because websites are so 1995.<br>
<br>
This client lets you interact with the SWPAG game, including <br>
getting the game status, obtaining a list of potential targets, and <br>
submitting flags.<br>
<br>
To get started, you will have received a "flag token" with your game registration.<br>
You may also need to know the URL of your game's "team interface".<br>
Note that for some games (e.g., iCTF) this will be automatically discovered for you.<br>
You will also need access to your team's virtual machine, on which you should run the client.<br>
<br>
You are heavily encouraged to use this library to help you automate the exploitation of services<br>
and the submission of flags.<br>
<br>
You can now do the following:<br>
<br>
For iCTF players:<br>
>>> from swpag_client import <a href="#Team">Team</a><br>
>>> t = <a href="#Team">Team</a>(None, "your_flag_token_here")<br>
(this will auto-detect the team interface's address for you)<br>
<br>
For general SWPAG users:<br>
<br>
>>> from swpag_client import <a href="#Team">Team</a><br>
>>> t = <a href="#Team">Team</a>("<a href="http://your.team.interface.hostname/">http://your.team.interface.hostname/</a>", "your_flag_token_here")<br>
<br>
With this team <a href="__builtin__.html#object">object</a>, you can then get game status information:<br>
<br>
>>> t.get_game_status()<br>
<br>
This includes information on scores, teams, services, and timing information regarding the game's "ticks".<br>
<br>
Your first task will be to explore the game services which you must attack and defend, and find exploits<br>
You will see them on your VM's filesystem, but to get a list of services with descriptions, you can run<br>
>>> t.get_service_list()<br>
<br>
This will produce a list of services, including the "service ID" of the service.<br>
<br>
Once you have reverse-engineered a service, and developed your new leet exploit, you then need to<br>
obtain a list of the other teams, which you can attack.<br>
However, each service hosted by each team may contain multiple flags; in order to prove your <br>
control over the vulnerable service, you must find the _correct_ flag, which the game tells you to find.<br>
Each flag is associated with a "flag ID", which gets cycled each game tick (see the game rules for<br>
more details). Your exploit needs to then obtain the flag associated with a given flag ID, hosted<br>
hosted by a given opponent team.<br>
<br>
With the service ID obtained above, you can then do the following:<br>
<br>
>>> t.get_targets(service_id)<br>
<br>
This will return a list of the teams' IP addresses, port numbers, and flag IDs.<br>
<br>
Finally, you need to capture and submit some flags!<br>
Once you've pwned the service, and captured the flag, all you need to do is:<br>
<br>
>>> t.submit_flag("FLGxxxxxxxxxxxxx")<br>
<br>
You can also submit a lot of flags at once:<br>
<br>
>>> t.submit_flag(["FLGxxxxxxxxxxxxx", "FLGyyyyyyyyyyyyy", ...])<br>
<br>
You'll get a status code (or a list of status codes) in return.<br>
<br>
The client can provide a wealth of information on the game, which is discussed in the documentation.<br>
<br>
Happy hacking!<br>
<br>
- the SWPAG team</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="base64.html">base64</a><br>
</td><td width="25%" valign=top><a href="json.html">json</a><br>
</td><td width="25%" valign=top><a href="random.html">random</a><br>
</td><td width="25%" valign=top><a href="requests.html">requests</a><br>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="client.html#Team">Team</a>
</font></dt></dl>
</dd>
</dl>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom> <br>
<font color="#000000" face="helvetica, arial"><a name="Team">class <strong>Team</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
<td colspan=2><tt>This <a href="__builtin__.html#object">object</a> represents a logged-in iCTF team.<br>
This <a href="__builtin__.html#object">object</a> can be used to perform actions on behalf of the team, such as submitting game artifacts<br> </tt></td></tr>
<tr><td> </td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Team-__init__"><strong>__init__</strong></a>(self, game_url<font color="#909090">=None</font>, flag_token<font color="#909090">=None</font>)</dt><dd><tt>Create a <a href="#Team">Team</a> <a href="__builtin__.html#object">object</a>, use to interact with SWPAG as a team.<br>
All you need to get started is the <a href="#Team">Team</a> Interface URL (don't forget the trailing /) and a token for your team.<br>
<br>
For example:<br>
<br>
from swpag import <a href="#Team">Team</a><br>
t = <a href="#Team">Team</a> ("<a href="http://team-interface-lsdkjflsj.shellweplayagame.org">http://team-interface-lsdkjflsj.shellweplayagame.org</a>", "lksjdflkjSDFJLK")<br>
iCTF 2018 NOTE:<br>
We love the cloud! We don't know where our team interface is either.<br>
Use this altnernate form to automatically discover the game url:<br>
from swpag import <a href="#Team">Team</a><br>
t = <a href="#Team">Team</a> (None, "lksjdflkjSDFJLK")<br>
<br>
:param game_url: The URL to your <a href="#Team">Team</a> Interface. Don't forget a trailing /<br>
:param flag_token: The Flag Token from the SWPAG website for your team.</tt></dd></dl>
<dl><dt><a name="Team-__str__"><strong>__str__</strong></a>(self)</dt></dl>
<dl><dt><a name="Team-bootstrap"><strong>bootstrap</strong></a>(self)</dt><dd><tt>Auto-bootstrap the <a href="#Team">Team</a> Interface location. <br>
:return:</tt></dd></dl>
<dl><dt><a name="Team-get_game_status"><strong>get_game_status</strong></a>(self)</dt><dd><tt>Return a dictionary containing game status information.<br>
This will include:<br>
- The scores of all teams<br>
- Game timing information<br>
- Information about services, including their status, number of exploitations, etc<br>
<br>
This API is suitable for use in the creation of frontends.<br>
<br>
The return value is a large dictionary, containing the following:<br>
- 'teams' : Basic team info, name, country, latitude, longitude, etc<br>
- 'service_states': For each team and service, provides its "state" (up/down/etc)<br>
- 'exploited_services': For each service that has been exploited, list who exploited it<br>
- 'first_bloods': For each service, which team scored on it first (they get extra points!)<br>
- 'scores': The scoring data for each team.<br>
- 'tick': Info about the game's current "tick" -- see <a href="#Team-get_tick_info">get_tick_info</a>()<br>
It will look something like:<br>
<br>
{<br>
'teams' :<br>
{<br>
<team_id> :<br>
{<br>
'country' : "ISO 2 letter country code",<br>
'logo' : <base64 logo>,<br>
'name' : "1338-offbyone"<br>
'url' : "<a href="http://teamurl.here">http://teamurl.here</a>"<br>
} }<br>
}<br>
'exploited_services' :<br>
{<br>
<service_id> :<br>
{<br>
'service_name' : "string_service_name",<br>
'teams' :<br>
[<br>
{<br>
'team_id' : <team_id>,<br>
'team_name' : "string team name"<br>
},<br>
...<br>
],<br>
'total_stolen_flags' : <integer><br>
}<br>
}<br>
'service_states' :<br>
{<br>
<team_id> :<br>
{<br>
<service_id> :<br>
{<br>
'service_name' : "string_service_name"<br>
'service_state' : "untested" | "up" | "down"<br>
}<br>
}<br>
},<br>
'first_bloods' :<br>
{<br>
<service_id> :<br>
{<br>
'created_on' : Timestamp eg. '2015-12-02 10:57:49',<br>
'team_id' : <ID of exploiting team><br>
}<br>
},<br>
'scores' :<br>
{<br>
<team_id> :<br>
{<br>
'attack_points' : <float number of points scored through exploitation>,<br>
'service_points' : <float number of points for having a "cool" service, see rules for details>,<br>
'sla' : <float SLA score><br>
'total_points' : <float normalized final score><br>
}<br>
},<br>
'tick' :<br>
{<br>
'approximate_seconds_left': <int seconds>,<br>
'created_on': Timestamp, like '2015-12-02 12:28:03',<br>
'tick_id': <int tick ID><br>
}<br>
}</tt></dd></dl>
<dl><dt><a name="Team-get_service_list"><strong>get_service_list</strong></a>(self)</dt><dd><tt>Returns the list of services, and some useful information about them.<br>
<br>
The output will look like:<br>
<br>
[<br>
{<br>
'service_id' : <int service id>,<br>
'team_id' : <team_id which created that service><br>
'service_name' : "string service_name",<br>
'description' : "Description of the service",<br>
'flag_id_description' : "Description of the 'flag_id' in this service, indicating which flag you should steal",<br>
'port' : <int port number><br>
}<br>
]</tt></dd></dl>
<dl><dt><a name="Team-get_targets"><strong>get_targets</strong></a>(self, service)</dt><dd><tt>Get a list of teams, their hostnames, and the currently valid flag_ids.<br>
Your exploit should then try to exploit each team, and steal the flag with the given ID.<br>
<br>
You can/should use this to write scripts to run your exploits!<br>
<br>
:param service: The name or ID of a service (see <a href="#Team-get_service_list">get_service_list</a>() for IDs and names)<br>
:return: A list of targets:<br>
[<br>
{<br>
'team_name' : "<a href="#Team">Team</a> name",<br>
'hostname' : "hostname",<br>
'port' : <int port number>,<br>
'flag_id' : "Flag ID to steal"<br>
},<br>
...<br>
]</tt></dd></dl>
<dl><dt><a name="Team-get_team_list"><strong>get_team_list</strong></a>(self)</dt><dd><tt>Return the list of teams!</tt></dd></dl>
<dl><dt><a name="Team-get_team_status"><strong>get_team_status</strong></a>(self)</dt><dd><tt>Get your team's current status</tt></dd></dl>
<dl><dt><a name="Team-get_tick_info"><strong>get_tick_info</strong></a>(self)</dt><dd><tt>Return information about the current game "tick".<br>
<br>
The iCTF game is divided into rounds, called "ticks". Scoring is computed at the end of each tick.<br>
New flags are set only at the next tick.<br>
<br>
If you're writing scripts or frontends, you should use this to figure out when to<br>
run them.<br>
<br>
The format looks like:<br>
{u'approximate_seconds_left': <int seconds>,<br>
u'created_on': Timestamp, like u'2015-12-02 12:28:03',<br>
u'tick_id': <int tick ID>}</tt></dd></dl>
<dl><dt><a name="Team-submit_flag"><strong>submit_flag</strong></a>(self, *args, **kwargs)</dt><dd><tt>Submit a list of one or more flags<br>
note: Requires a flag token<br>
:param flags: A list of flags<br>
:return: List containing a response for each flag, either:<br>
"correct" | "ownflag" (do you think this is defcon?)<br>
| "incorrect"<br>
| "alreadysubmitted"<br>
| "notactive",<br>
| "toomanyincorrect",</tt></dd></dl>
<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary for instance variables (if defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list of weak references to the object (if defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#eeaa77">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
<tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td>
<td width="100%"><dl><dt><a name="-flag_token"><strong>flag_token</strong></a>(func)</dt></dl>
<dl><dt><a name="-input"><strong>input</strong></a> = raw_input(...)</dt><dd><tt>raw_input([prompt]) -> string<br>
<br>
Read a string from standard input. The trailing newline is stripped.<br>
If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.<br>
On Unix, GNU readline is used if enabled. The prompt string, if given,<br>
is printed without a trailing newline before reading.</tt></dd></dl>
</td></tr></table>
</body></html>