-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspyawn.py
118 lines (103 loc) · 3.61 KB
/
spyawn.py
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
from flask import Flask, request
import docker
import json
import time
import random
import os
import requests
client = docker.from_env()
config = json.load(open("config.json"))
if not os.path.isdir("data"):
os.mkdir("data")
if not os.path.isdir("rates"):
os.mkdir("rates")
app = Flask(__name__)
port_range = (50000, 60000)
@app.after_request
def after_request(response):
response.headers["Access-Control-Allow-Origin"] = "*"
return response
def make_container(uid, chal):
container = None
port = None
while True:
try:
port = random.randint(port_range[0], port_range[1])
container = client.containers.run(chal, ports={str(config[chal]["internal_port"]) + "/tcp": port}, name=chal+str(uid), **(config[chal]["container"]))
break
except Exception as e:
time.sleep(0.5)
print(e)
print("CREATED: " + str(uid) + " " + chal)
with open("data/" + str(uid) + "." + chal, "w") as f:
json.dump({"time": round(time.time() + config[chal]["container"]["healthcheck"]["interval"]//1000000000), "port": port}, f)
def del_container(uid, chal):
container = None
print("KILLED: " + str(uid) + " " + chal)
try:
container = client.containers.get(chal + str(uid))
container.kill()
except Exception as e:
print(e)
with open("data/" + str(uid) + "." + chal, "w") as f:
json.dump({"time": 0, "port": 0}, f)
def verify_id(uid):
r = requests.get("http://5.161.201.219:8000/api/checkTeamId/" + str(uid))
return r.json()["teamIdExists"]
def ratelimit(ip):
if not os.path.isfile("rates/" + ip):
with open("rates/" + ip, "w") as f:
f.write("0")
with open("rates/" + ip) as f:
prev_t = int(f.read())
if prev_t == round(time.time()):
return False
with open("rates/" + ip, "w") as f:
f.write(str(round(time.time())))
return True
def aux_get(uid, chal):
res = {"time": 0, "port": 0}
try:
res = json.load(open("data/" + str(uid) + "." + chal))
except:
pass
return res
@app.route("/get/<int:uid>/<chal>")
def get(uid, chal):
if not ratelimit(request.remote_addr):
return {"status": "error", "message": "rate limit exceeded"}
if not verify_id(uid):
return {"status": "error", "message": "invalid team"}
return aux_get(uid, chal)
@app.route("/remove/<int:uid>/<chal>")
def remove(uid, chal):
if not ratelimit(request.remote_addr):
return {"status": "error", "message": "rate limit exceeded"}
if not verify_id(uid):
return {"status": "error", "message": "invalid team"}
if chal not in config:
return {"status": "error", "message": "invalid chal"}
chal_dat = aux_get(uid, chal)
if chal_dat["time"] < round(time.time()):
return {"status": "error", "message": "chal already deleted"}
del_container(uid, chal)
return {"status": "yay"}
@app.route("/create/<int:uid>/<chal>")
def create(uid, chal):
if not ratelimit(request.remote_addr):
return {"status": "error", "message": "rate limit exceeded"}
if not verify_id(uid):
return {"status": "error", "message": "invalid team"}
if chal not in config:
return {"status": "error", "message": "invalid chal"}
chal_dat = aux_get(uid, chal)
if chal_dat["time"] > round(time.time()):
return {"status": "error", "message": "already active chal"}
del_container(uid, chal)
make_container(uid, chal)
return {"status": "yay"}
@app.route("/reloadconfig")
def reloadconfig():
global config
config = json.load(open("config.json"))
return "😳"