├── util ├── __init__.py ├── styler.py ├── helpers.py ├── log.py └── validation.py ├── .gitignore ├── docs ├── assets │ ├── favicon.ico │ ├── images │ │ ├── attacks1.png │ │ ├── attacks2.png │ │ ├── attacks3.png │ │ ├── browser.png │ │ ├── manual.png │ │ └── dashboard.png │ ├── flag-line.svg │ └── demos │ │ ├── server-no-clients.cast │ │ ├── client-no-exploits.cast │ │ └── client.cast ├── user-manual │ ├── dashboard │ │ ├── dashboard.md │ │ ├── overview.md │ │ ├── manual.md │ │ └── browser.md │ ├── client │ │ ├── running.md │ │ ├── overview.md │ │ ├── configuration.md │ │ ├── exploit-guideline.md │ │ └── exploit-management.md │ └── server │ │ ├── running.md │ │ ├── overview.md │ │ ├── submitter-guideline.md │ │ └── configuration.md ├── troubleshooting.md ├── index.md ├── install.md └── quickstart.md ├── web ├── public │ └── favicon.ico ├── src │ ├── main.js │ ├── game.js │ ├── socket.js │ ├── api.js │ ├── timers.js │ ├── counters.js │ ├── App.vue │ └── components │ │ ├── Navigation.vue │ │ ├── ManualSubmit.vue │ │ ├── Dashboard.vue │ │ ├── Analytics.vue │ │ └── FlagBrowser.vue ├── vite.config.js ├── index.html ├── .gitignore └── package.json ├── database.py ├── setup.py ├── models.py ├── mkdocs.yml ├── cli.py ├── README.md ├── handler.py ├── dsl.py ├── runner.py ├── client.py └── server.py /util/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | __pycache__ 3 | *.egg-info 4 | dist 5 | site -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/favicon.ico -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /docs/assets/images/attacks1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/attacks1.png -------------------------------------------------------------------------------- /docs/assets/images/attacks2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/attacks2.png -------------------------------------------------------------------------------- /docs/assets/images/attacks3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/attacks3.png -------------------------------------------------------------------------------- /docs/assets/images/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/browser.png -------------------------------------------------------------------------------- /docs/assets/images/manual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/manual.png -------------------------------------------------------------------------------- /docs/assets/images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dusanlazic/fast/HEAD/docs/assets/images/dashboard.png -------------------------------------------------------------------------------- /web/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /web/src/game.js: -------------------------------------------------------------------------------- 1 | import api from '@/api.js' 2 | 3 | export const game = { 4 | async initialize() { 5 | this.flagFormat = (await api.getFlagFormat()).format 6 | } 7 | } -------------------------------------------------------------------------------- /docs/assets/flag-line.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database.py: -------------------------------------------------------------------------------- 1 | from peewee import Model, Proxy, SqliteDatabase 2 | 3 | db = Proxy() 4 | 5 | 6 | class BaseModel(Model): 7 | class Meta: 8 | database = db 9 | 10 | 11 | fallbackdb = SqliteDatabase('fallback.db') 12 | 13 | 14 | class FallbackBaseModel(Model): 15 | class Meta: 16 | database = fallbackdb 17 | -------------------------------------------------------------------------------- /web/vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | ], 11 | resolve: { 12 | alias: { 13 | '@': fileURLToPath(new URL('./src', import.meta.url)) 14 | } 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 || status | 64 |value | 65 |response | 66 | 67 | 68 |
|---|---|---|
|
70 | {{ result.status }}
71 | |
74 | {{ result.value }} | 75 |{{ result.response }} | 76 |
18 | Current tick
19 |
30 |
34 | {{ counters.tick.received }} 35 |
36 |
43 |
47 | {{ counters.tick.duplicates }} 48 |
49 |
56 |
60 | {{ counters.tick.queued }} 61 |
62 |
69 |
73 | {{ counters.tick.exploits.size }} 74 |
75 |
81 | Flag store
82 |
94 |
98 |
102 | {{ counters.store.queued }} 103 |
104 |
112 |
117 | {{ counters.store.accepted }} 118 |
119 |
127 |
132 | {{ counters.store.rejected }} 133 |
134 |
140 | Exploits
141 |
228 |
229 | {{ exploit.name }}
230 |
242 |
245 |
248 |
|
171 | tick
172 | |
174 |
175 | timestamp
176 | |
178 |
179 | player
180 | |
182 |
183 | exploit
184 | |
186 |
187 | target
188 | |
190 |
191 | status
192 | |
194 |
195 | value
196 | |
198 |
199 | response
200 | |
205 |
206 |
|---|
| {{ result.tick }} | 225 |{{ result.timestamp.split("T")[1].split(".")[0] }} | 226 |{{ result.player }} | 227 |{{ result.exploit }} | 228 |{{ result.target }} | 229 |{{ result.status }} | 230 |{{ truncateEnd(result.value, 18, '...') }} | 231 |{{ truncateStart(result.response, 18, '...') }} | 232 |