Initial commit
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import io
|
||||
import pandas as pd
|
||||
import requests
|
||||
import re
|
||||
|
||||
class Art(Challenge):
|
||||
flag_location = 'flags/art.txt'
|
||||
history_location = 'history/art.txt'
|
||||
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
word = self.random_string(8)
|
||||
url = f'http://localhost:{self.port}/art/{word}'
|
||||
r = requests.get(url, timeout=5)
|
||||
assert r.text == f'<iframe height="100%" width="100%" frameborder="0" src=https://asciified.thelicato.io/api/v2/ascii?text={word}></iframe>', 'Unexpected response'
|
||||
self.logger.info('Check passed for art')
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check art: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,35 @@
|
||||
from .Challenge import Challenge
|
||||
from pwn import *
|
||||
|
||||
class BackToBasic(Challenge):
|
||||
flag_location = 'flags/back-to-basic.txt'
|
||||
history_location = 'history/back-to-basic.txt'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
r = remote("localhost",self.port)
|
||||
assert b"idea?" in r.recvline(), "Failed First"
|
||||
|
||||
r.sendline(b"testt")
|
||||
|
||||
assert b"thing" in r.recvline(), "Failed Last"
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check back-to-basic: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,124 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
from fastecdsa.curve import Curve
|
||||
from fastecdsa.point import Point
|
||||
import requests
|
||||
import time
|
||||
import os
|
||||
import json
|
||||
|
||||
|
||||
class Burvesigner(Challenge):
|
||||
flag_location = 'flags/burvesigner.txt'
|
||||
history_location = 'history/burvesigner.txt'
|
||||
priv_location = 'files/burvesigner.priv'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.priv_location, 'wb') as f:
|
||||
f.write(os.urandom(256))
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
url = f'http://localhost:{self.port}'
|
||||
flag = open(self.flag_location).read()
|
||||
|
||||
# C1: login guest success
|
||||
guest_data = {
|
||||
'username': 'guest',
|
||||
'password': 'guest',
|
||||
}
|
||||
response = requests.post(url, data=guest_data, timeout=5)
|
||||
guest_token = response.cookies["token"]
|
||||
assert "Welcome, guest!" in response.text, "Guest cannot login"
|
||||
assert "flashes" not in response.text, "Guest cannot login"
|
||||
self.logger.info(f'C1 success for burvesigner')
|
||||
|
||||
# C2: login admin success
|
||||
admin_data = {
|
||||
'username': 'merricx_number_1_fans',
|
||||
'password': getattr(self.settings, f'PASSWORD_{self.port}'),
|
||||
}
|
||||
response = requests.post(url, data=admin_data, timeout=5)
|
||||
admin_token = response.cookies["token"]
|
||||
assert "Welcome, merricx_number_1_fans!" in response.text, "Admin cannot login"
|
||||
assert flag in response.text, "Flag is missing in admin page"
|
||||
assert "flashes" not in response.text, "Admin cannot login"
|
||||
self.logger.info(f'C2 success for burvesigner')
|
||||
|
||||
# C3: login guest fail
|
||||
guest_data = {
|
||||
'username': 'guest',
|
||||
'password': 'Guest',
|
||||
}
|
||||
response = requests.post(url, data=guest_data, timeout=5).text
|
||||
assert "Welcome, guest!" not in response, "Guest with wrong credential can login"
|
||||
assert "flashes" in response, "Guest with wrong credential can login"
|
||||
self.logger.info(f'C3 success for burvesigner')
|
||||
|
||||
# C4: login admin fail
|
||||
admin_data = {
|
||||
'username': 'merricx_number_1_fans',
|
||||
'password': 'password',
|
||||
}
|
||||
response = requests.post(url, data=admin_data, timeout=5).text
|
||||
assert "Welcome, merricx_number_1_fans!" not in response, "Admin with wrong credential can login"
|
||||
assert flag not in response, "Flag is showing in admin page with wrong credential"
|
||||
assert "flashes" in response, "Admin with wrong credential can login"
|
||||
self.logger.info(f'C4 success for burvesigner')
|
||||
|
||||
self.logger.info('calling sleep(5)')
|
||||
time.sleep(5)
|
||||
|
||||
# C5: cek apakah token guest di C1 sudah expired atau belum
|
||||
response = requests.get(url, cookies={"token": guest_token}, timeout=5)
|
||||
assert "Welcome, guest!" in response.text, "Guest token expires early"
|
||||
assert "flashes" not in response.text, "Guest token expires early"
|
||||
self.logger.info(f'C5 success for burvesigner')
|
||||
|
||||
# C6: cek apakah token admin di C2 sudah expired atau belum
|
||||
response = requests.get(url, cookies={"token": admin_token}, timeout=5)
|
||||
assert "Welcome, merricx_number_1_fans!" in response.text, "Admin token expires early"
|
||||
assert flag in response.text, "Admin token expires early"
|
||||
assert "flashes" not in response.text, "Admin token expires early"
|
||||
self.logger.info(f'C6 success for burvesigner')
|
||||
|
||||
# C7: cek endpoint /params
|
||||
response = requests.get(url + "/params", timeout=5).text
|
||||
response = response.replace("<pre>", "").replace("</pre>", "")
|
||||
params = json.loads(response)
|
||||
assert params["p"] and params["a"] and params["b"] and params["n"], "Missing p, a, b and/or n parameter(s)"
|
||||
assert params["G"][0] and params["G"][1] and params["Y"][0] and params["Y"][1], "Missing G and/or Y point(s)"
|
||||
self.logger.info(f'C7 success for burvesigner')
|
||||
|
||||
# C8: cek apakah curve C valid dan point G di C
|
||||
C = Curve("burvesigner", params["p"], params["a"], params["b"], params["n"], params["G"][0], params["G"][1])
|
||||
assert C.G == Point(params["G"][0], params["G"][1], C), "Point G is not valid"
|
||||
self.logger.info(f'C8 success for burvesigner')
|
||||
|
||||
# C9: cek apakah point G * priv = Y
|
||||
t = params["p"].bit_length() // 8
|
||||
priv = open(self.priv_location, "rb").read()[:t]
|
||||
x = int.from_bytes(priv, "little")
|
||||
Y = Point(params["Y"][0], params["Y"][1], C)
|
||||
assert C.G * x == Y, "Point Y is not valid"
|
||||
self.logger.info(f'C9 success for burvesigner')
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check burvesigner: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,34 @@
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
|
||||
from config import get_settings
|
||||
|
||||
|
||||
class Challenge(object):
|
||||
name = __name__
|
||||
settings = get_settings()
|
||||
port = 0
|
||||
|
||||
def __init__(self, port):
|
||||
self.port = port
|
||||
self.add_logger()
|
||||
|
||||
def add_logger(self):
|
||||
self.logger = logging.getLogger()
|
||||
|
||||
def random_string(self, length):
|
||||
charset = string.ascii_uppercase + string.ascii_lowercase + string.digits
|
||||
return ''.join(random.choice(charset) for i in range(length))
|
||||
|
||||
def distribute(self, flag):
|
||||
raise NotImplementedError
|
||||
|
||||
def check(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def credentials(self):
|
||||
return {
|
||||
'username': 'root',
|
||||
'password': getattr(self.settings, f'PASSWORD_{self.port}'),
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import requests
|
||||
import os
|
||||
|
||||
MOCK_URL = 'http://google.com'
|
||||
MOCK_DATA = '<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">'
|
||||
|
||||
class Crawlback(Challenge):
|
||||
flag_location = 'flags/crawlback.txt'
|
||||
history_location = 'history/crawlback.txt'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
r = requests.post(f"http://localhost:{self.port}/crawlback.php", data={'url': MOCK_URL})
|
||||
|
||||
assert r.text.split('\n').pop(0) == MOCK_DATA
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check crawlback: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,67 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import requests
|
||||
import zlib
|
||||
import gzip
|
||||
import json
|
||||
|
||||
MOCK_URL = 'http://google.com'
|
||||
MOCK_DATA_WGET = 'Google</title>'
|
||||
MOCK_DATA_CURL = '<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">'
|
||||
|
||||
class GemasFetcher(Challenge):
|
||||
flag_location = 'flags/gemas-fetcher.txt'
|
||||
history_location = 'history/gemas-fetcher.txt'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
sess = requests.Session()
|
||||
|
||||
## register
|
||||
username = self.random_string(5)
|
||||
password = self.random_string(5)
|
||||
r = sess.post(f"http://localhost:{self.port}/auth/register", data={"username":username,"password": password}, allow_redirects=False)
|
||||
assert r.headers.get("location") == "/auth/login", "Register Failed"
|
||||
|
||||
## login
|
||||
r = sess.post(f"http://localhost:{self.port}/auth/login", data={"username":username,"password": password}, allow_redirects=False)
|
||||
assert r.headers.get("location") == "/dashboard", "Login Failed"
|
||||
|
||||
## wget
|
||||
content = {"provider": "wget","url":MOCK_URL}
|
||||
files = {"file": ("visit", b"\x00\x00"+gzip.compress(zlib.compress(json.dumps(content).encode())))}
|
||||
r = sess.post(f"http://localhost:{self.port}/dashboard/fetch_by_file", files=files)
|
||||
assert MOCK_DATA_WGET in r.text, "wget Failed"
|
||||
|
||||
## curl
|
||||
content = {"provider": "curl","url":MOCK_URL}
|
||||
files = {"file": ("visit", b"\x00\x01"+gzip.compress(zlib.compress(json.dumps(content).encode())))}
|
||||
r = sess.post(f"http://localhost:{self.port}/dashboard/fetch_by_file", files=files)
|
||||
assert r.text.split('\n').pop(0) == MOCK_DATA_CURL, "curl Failed"
|
||||
|
||||
## python
|
||||
content = {"provider": "python","url":MOCK_URL}
|
||||
files = {"file": ("visit", b"\x00\x02"+gzip.compress(zlib.compress(json.dumps(content).encode())))}
|
||||
r = sess.post(f"http://localhost:{self.port}/dashboard/fetch_by_file", files=files)
|
||||
assert r.text.startswith('"PCFkb2N0eXBlIGh0bWw'), "python Failed"
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check gemas-fetcher: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,67 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import requests
|
||||
|
||||
class GemasNotes(Challenge):
|
||||
history_location = 'history/gemas-notes.txt'
|
||||
host = "http://localhost:12000"
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
username = "gemasflagreceiver"
|
||||
password = "AuTeEbn%.Q5$pC_ge6"
|
||||
result = requests.post(f"{self.host}/flag_receiver", json={"flag": flag}, auth=(username,password)).json()
|
||||
if not result.get("success"):
|
||||
return False
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} updated in gemas-notes database')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could send flag to gemas-notes challenge: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
url = f'http://localhost:{self.port}'
|
||||
|
||||
# login
|
||||
token = requests.post(f"{url}/api/login",json={"email":"checker@gemasnotes.id", "password":"uRIqCvJ<IGb;VDT14"}).json()["token"]
|
||||
header = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
# get count
|
||||
old_count = requests.post(f"{url}/api/notes/count", headers=header, json={"count_by":"title", "keyword":""}).json()["count"]
|
||||
|
||||
# create notes
|
||||
notes = {"title":self.random_string(10), "content":self.random_string(20), "tags":self.random_string(10)}
|
||||
status_code = requests.put(f"{url}/api/notes", headers=header, json=notes).status_code
|
||||
assert status_code in [200, 201], "Cannot Create Note"
|
||||
|
||||
# get notes
|
||||
all_notes = requests.get(f"{url}/api/notes").json()
|
||||
note = list(filter(lambda x: x["title"] == notes["title"], all_notes))
|
||||
assert len(note) != 0, "Note was not created"
|
||||
|
||||
# get new count
|
||||
new_count = requests.post(f"{url}/api/notes/count", headers=header, json={"count_by":"title", "keyword":""}).json()["count"]
|
||||
assert old_count != new_count, "Invalid count"
|
||||
|
||||
# update notes
|
||||
new_content = self.random_string(20)
|
||||
notes["id"] = note[0]["id"]
|
||||
notes["content"] = new_content
|
||||
status_code = requests.patch(f"{url}/api/notes", headers=header, json=notes).status_code
|
||||
assert status_code in [200, 204], "Cannot Update Note"
|
||||
|
||||
# delete notes
|
||||
status_code = requests.delete(f"{url}/api/notes/{notes['id']}", headers=header, json=notes).status_code
|
||||
assert status_code == 200, "Cannot Delete Note"
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check gemas-notes: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,42 @@
|
||||
import requests
|
||||
from base64 import b64decode
|
||||
|
||||
from .Challenge import Challenge
|
||||
|
||||
|
||||
class Hirnfick(Challenge):
|
||||
flag_location = 'flags/hirnfick.txt'
|
||||
history_location = 'history/hirnfick.txt'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(
|
||||
f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
res = requests.post(
|
||||
f"http://localhost:{self.port}/api/run",
|
||||
timeout=5,
|
||||
json={
|
||||
"code":
|
||||
"+[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+."
|
||||
})
|
||||
|
||||
assert b64decode(res.json()["output"]) == b"HirnFick 1.0\nHello, World!"
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check hirnfick: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,109 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class Pasta(Challenge):
|
||||
flag_location = 'flags/pasta.txt'
|
||||
history_location = 'history/pasta.txt'
|
||||
host = "http://localhost:13000"
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
url = f'http://localhost:{self.port}'
|
||||
username = f"checker-{self.random_string(8)}"
|
||||
pwd = self.random_string(12)
|
||||
flag = open(self.flag_location).read()
|
||||
|
||||
admin_data = {
|
||||
'username': 'deomkicer_number_1_fans',
|
||||
'password': getattr(self.settings, f'PASSWORD_{self.port}'),
|
||||
}
|
||||
|
||||
# login admin and check flag
|
||||
response = requests.post(
|
||||
f"{url}/auth",
|
||||
json=admin_data).json()
|
||||
|
||||
token = response.get('token')
|
||||
assert token, "Token is missing in login admin"
|
||||
check_flag = requests.get(f"{url}/flag", headers={'Authorization': f"Bearer {token}"}).json()
|
||||
assert check_flag.get('flag') == flag, "Flag is missing/mismatch"
|
||||
|
||||
# register
|
||||
response = requests.post(
|
||||
f"{url}/register",
|
||||
json={
|
||||
"username": f"{username}",
|
||||
"password": f"{pwd}"}).json()
|
||||
|
||||
assert response.get('success') == "User registered succesfully", "Register failed"
|
||||
|
||||
# login with version 1
|
||||
response = requests.post(
|
||||
f"{url}/auth?version=1",
|
||||
json={
|
||||
"username": f"{username}",
|
||||
"password": f"{pwd}"}).json()
|
||||
|
||||
token = response.get('token')
|
||||
assert token, "Token is missing in login v1"
|
||||
check_home = requests.get(f"{url}/", headers={'Authorization': f"Bearer {token}"}).json()
|
||||
assert check_home.get('username') == username, "Different username found in login v1"
|
||||
|
||||
# login with version 2
|
||||
response = requests.post(
|
||||
f"{url}/auth?version=2",
|
||||
json={
|
||||
"username": f"{username}",
|
||||
"password": f"{pwd}"}).json()
|
||||
|
||||
token = response.get('token')
|
||||
assert token, "Token is missing in login v2"
|
||||
check_home = requests.get(f"{url}/", headers={'Authorization': f"Bearer {token}"}).json()
|
||||
assert check_home.get('username') == username, "Different username found in login v2"
|
||||
|
||||
# login with version 3
|
||||
response = requests.post(
|
||||
f"{url}/auth?version=3",
|
||||
json={
|
||||
"username": f"{username}",
|
||||
"password": f"{pwd}"}).json()
|
||||
|
||||
token = response.get('token')
|
||||
assert token, "Token is missing in login v3"
|
||||
check_home = requests.get(f"{url}/", headers={'Authorization': f"Bearer {token}"}).json()
|
||||
assert check_home.get('username') == username, "Different username found in login v3"
|
||||
|
||||
# login with version 4
|
||||
response = requests.post(
|
||||
f"{url}/auth?version=4",
|
||||
json={
|
||||
"username": f"{username}",
|
||||
"password": f"{pwd}"}).json()
|
||||
|
||||
token = response.get('token')
|
||||
assert token, "Token is missing in login v4"
|
||||
check_home = requests.get(f"{url}/", headers={'Authorization': f"Bearer {token}"}).json()
|
||||
assert check_home.get('username') == username, "Different username found in login v4"
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check pasta: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,44 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import requests
|
||||
import os
|
||||
|
||||
|
||||
class S3(Challenge):
|
||||
flag_location = 'flags/s3.txt'
|
||||
history_location = 'history/s3.txt'
|
||||
host = 'http://localhost:20000'
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
filename = self.random_string(8) + ".txt"
|
||||
content = self.random_string(64)
|
||||
|
||||
r = requests.post(f"http://localhost:{self.port}/upload", files={'file': (filename, content)})
|
||||
assert r.status_code == 200
|
||||
assert r.text == f'Download <a href="/download?filename={filename}">here</a>'
|
||||
|
||||
r = requests.get(f"http://localhost:{self.port}/download?filename={filename}")
|
||||
assert r.status_code == 200
|
||||
assert r.text == content
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check s3: {e}')
|
||||
return False
|
||||
@@ -0,0 +1,66 @@
|
||||
from .Challenge import Challenge
|
||||
|
||||
import io
|
||||
import pandas as pd
|
||||
import requests
|
||||
import re
|
||||
|
||||
MOCK_DATA = [
|
||||
{'name': 'John','age': 30, 'city': 'New York'},
|
||||
{'name': 'Mary', 'age': 25, 'city': 'San Francisco'},
|
||||
{'name': 'Peter', 'age': 45, 'city': 'Chicago'},
|
||||
]
|
||||
|
||||
MOCK_RESULT = {
|
||||
"Sheet1":{
|
||||
"!ref":"A1:C4",
|
||||
"A1":{"t":"s","v":"name","h":"name","w":"name"},"B1":{"t":"s","v":"age","h":"age","w":"age"},"C1":{"t":"s","v":"city","h":"city","w":"city"},
|
||||
"A2":{"t":"s","v":"John","h":"John","w":"John"},"B2":{"t":"n","v":30,"w":"30"},"C2":{"t":"s","v":"New York","h":"New York","w":"New York"},
|
||||
"A3":{"t":"s","v":"Mary","h":"Mary","w":"Mary"},"B3":{"t":"n","v":25,"w":"25"},"C3":{"t":"s","v":"San Francisco","h":"San Francisco","w":"San Francisco"},
|
||||
"A4":{"t":"s","v":"Peter","h":"Peter","w":"Peter"},"B4":{"t":"n","v":45,"w":"45"},"C4":{"t":"s","v":"Chicago","h":"Chicago","w":"Chicago"},
|
||||
"!margins":{"left":0.75,"right":0.75,"top":1,"bottom":1,"header":0.5,"footer":0.5}
|
||||
}
|
||||
}
|
||||
|
||||
class XL(Challenge):
|
||||
flag_location = 'flags/xl.txt'
|
||||
history_location = 'history/xl.txt'
|
||||
|
||||
|
||||
def distribute(self, flag):
|
||||
try:
|
||||
with open(self.flag_location, 'w') as f:
|
||||
f.write(flag)
|
||||
|
||||
with open(self.history_location, 'a') as f:
|
||||
f.write(flag + '\n')
|
||||
|
||||
self.logger.info(f'Flag {flag} written to {self.flag_location}')
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not write flag to {self.flag_location}: {e}')
|
||||
return False
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
url = f'http://localhost:{self.port}'
|
||||
files = {'file': self.generate_mock_file()}
|
||||
r = requests.post(url, files=files, timeout=5)
|
||||
assert r.json() == MOCK_RESULT, 'Unexpected response'
|
||||
self.logger.info('Check passed for xl')
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f'Could not check xl: {e}')
|
||||
return False
|
||||
|
||||
def generate_mock_file(self):
|
||||
memory_file = io.BytesIO()
|
||||
|
||||
df = pd.DataFrame(MOCK_DATA)
|
||||
df.to_excel(memory_file, index=False)
|
||||
|
||||
memory_file.seek(0)
|
||||
return memory_file
|
||||
Reference in New Issue
Block a user