Skip to content

Instantly share code, notes, and snippets.

@RoseSecurity
Created August 14, 2024 22:42
Show Gist options
  • Save RoseSecurity/5fc65f37fafc182568fa0dbdc9953db8 to your computer and use it in GitHub Desktop.
Save RoseSecurity/5fc65f37fafc182568fa0dbdc9953db8 to your computer and use it in GitHub Desktop.
Aqueduct is a honeypot designed to simulate city water control systems, allowing users to monitor and record unauthorized interactions with virtual alternators and wells.
from flask import Flask, request, render_template, redirect, url_for, jsonify
from pydantic import BaseModel, ValidationError
from gevent.pywsgi import WSGIServer
import json
import datetime
app = Flask(__name__)
# Model for metadata of the control request
class ControlRequest(BaseModel):
control: str
action: str
timestamp: str = datetime.datetime.now().isoformat()
ip_address: str
def record_request(data):
with open('logs.json', 'a') as f:
json.dump(data, f)
f.write('\n')
# Render the water control home page
@app.route('/')
def index():
return render_template('index.html')
@app.route('/lift-station-details.html', methods=['GET', 'POST'])
def lift_station_details():
if request.method == 'POST':
control_request_data = {
"control": request.form.get('station'),
"action": request.form.get('action'),
"ip_address": request.remote_addr
}
try:
data = ControlRequest(**control_request_data)
record_request(data.dict())
return jsonify({"status": "success"}), 200
except ValidationError as e:
return jsonify({"status": "error", "errors": e.errors()}), 400
return render_template('lift-station-details.html')
@app.route('/well-details.html', methods=['GET', 'POST'])
def well_details():
if request.method == 'POST':
control_request_data = {
"control": request.form.get('control'),
"action": request.form.get('action'),
"ip_address": request.remote_addr
}
try:
data = ControlRequest(**control_request_data)
record_request(data.dict())
return jsonify({"status": "success"}), 200
except ValidationError as e:
return jsonify({"status": "error", "errors": e.errors()}), 400
return render_template('well-details.html')
if __name__ == '__main__':
http_server = WSGIServer(('', 80), app)
http_server.serve_forever()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>City Water System</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #c0c0c0;
margin: 0;
padding: 20px;
}
.container {
background-color: #d4d0c8;
border: 2px outset #fff;
padding: 10px;
}
h1 {
text-align: center;
margin-top: 0;
}
.header {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
}
.using-tower {
border: 1px inset #fff;
padding: 5px;
background-color: #fff;
}
.main-content {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 20px;
}
.ground-storage, .tower {
border: 1px solid #000;
padding: 10px;
text-align: center;
}
.storage-level, .tower-level {
height: 200px;
width: 100px;
border: 1px solid #000;
margin: 10px auto;
position: relative;
}
.storage-fill, .tower-fill {
background-color: blue;
position: absolute;
bottom: 0;
width: 100%;
}
.boosters {
display: grid;
gap: 10px;
}
.booster {
border: 1px solid #000;
padding: 10px;
}
.booster-status {
display: inline-block;
padding: 2px 5px;
color: #fff;
}
.lead { background-color: green; }
.lag { background-color: gray; }
.standby { background-color: orange; }
.pump {
width: 50px;
height: 30px;
background-color: #ccc;
margin: 10px auto;
}
.well-details, .buttons {
display: grid;
gap: 10px;
}
.well, .button {
border: 1px outset #fff;
padding: 5px;
text-align: left;
}
.well-status {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
}
.active { background-color: green; }
.inactive { background-color: red; }
.button {
background-color: #d4d0c8;
cursor: pointer;
text-decoration: none;
color: black;
}
.button:active {
border-style: inset;
}
.alarms {
background-color: red;
color: white;
padding: 5px;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1>CITY WATER SYSTEM</h1>
<div class="header">
<div class="using-tower">USING TOWER FOR PUMPS</div>
</div>
<div class="main-content">
<div class="left-column">
<div class="ground-storage">
<h3>GROUND STORAGE</h3>
<div class="storage-level">
<div class="storage-fill" style="height: 69.1%;"></div>
</div>
<div>8.3 FT</div>
<div>69.1 %</div>
</div>
<div class="well-details">
<h3>WELL DETAILS</h3>
<div class="well"><span class="well-status inactive"></span>#1 FLOW: 0</div>
<div class="well"><span class="well-status active"></span>#8 FLOW: 39</div>
<div class="well"><span class="well-status inactive"></span>#4 FLOW: 0</div>
<div class="well"><span class="well-status active"></span>#5 FLOW: 341</div>
<div class="well"><span class="well-status active"></span>#6 FLOW: 235</div>
<div class="well"><span class="well-status inactive"></span>#7 FLOW: 0</div>
</div>
</div>
<div class="middle-column">
<div class="switch-lead">SWITCH LEAD PUMPS</div>
<div class="boosters">
<div class="booster">
<span class="booster-status lag">LAG</span>
WEST BOOSTER
<div class="pump"></div>
<div>FLOW: 0</div>
<div>RUN HOURS: 0.0</div>
</div>
<div class="booster">
<span class="booster-status lead">LEAD</span>
MIDDLE BOOSTER
<div class="pump"></div>
<div>FLOW: 0</div>
<div>RUN HOURS: 0.0</div>
</div>
<div class="booster">
<span class="booster-status standby">STANDBY</span>
EAST BOOSTER
<div class="pump"></div>
<div>FLOW: 0</div>
<div>RUN HOURS: 0.0</div>
</div>
</div>
</div>
<div class="right-column">
<div class="tower">
<h3>TOWER LEVEL</h3>
<div class="tower-level">
<div class="tower-fill" style="height: 95%;"></div>
</div>
<div>114.8 FT</div>
<div>TOWER PRESSURE: 49.7</div>
</div>
<div>CITY HALL PRESSURE: 46.9</div>
<div class="buttons">
<a href="well-details.html" class="button">WELL DETAILS</a>
<a href="lift-station-details.html" class="button">LIFT STATIONS</a>
<div class="button">CHLORINE</div>
<div class="button">COMMUNICATION STATISTICS</div>
<div class="alarms">ALARMS ACTIVE</div>
<div class="button">WELL SETPOINTS</div>
<div class="button">BOOSTER SETPOINTS</div>
</div>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>City Water System - Lift Station Details</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #c0c0c0;
margin: 0;
padding: 20px;
}
.container {
background-color: #d4d0c8;
border: 2px outset #fff;
padding: 20px;
}
h1, h2 {
text-align: center;
margin-top: 0;
}
.lift-stations {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.station {
border: 1px solid #000;
padding: 15px;
background-color: #fff;
}
.station-header {
font-weight: bold;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.station-status {
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
}
.operational { background-color: green; }
.warning { background-color: yellow; }
.alarm { background-color: red; }
.pump-details {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.pump {
border: 1px outset #d4d0c8;
padding: 10px;
background-color: #f0f0f0;
}
.button {
display: block;
width: 200px;
margin: 20px auto;
padding: 10px;
text-align: center;
background-color: #d4d0c8;
border: 1px outset #fff;
text-decoration: none;
color: black;
cursor: pointer;
}
.button:active {
border-style: inset;
}
</style>
</head>
<body>
<div class="container">
<h1>CITY WATER SYSTEM</h1>
<h2>Lift Station Details</h2>
<div class="lift-stations">
<div class="station">
<div class="station-header">
<span>Lift Station #1</span>
<span class="station-status operational"></span>
</div>
<div>Level: 5.2 ft</div>
<div>Flow: 150 GPM</div>
<div class="pump-details">
<div class="pump">
<div>Pump 1</div>
<div>Status: Running</div>
<div>Runtime: 3.5 hrs</div>
</div>
<div class="pump">
<div>Pump 2</div>
<div>Status: Standby</div>
<div>Runtime: 0 hrs</div>
</div>
</div>
</div>
<div class="station">
<div class="station-header">
<span>Lift Station #2</span>
<span class="station-status warning"></span>
</div>
<div>Level: 7.8 ft</div>
<div>Flow: 200 GPM</div>
<div class="pump-details">
<div class="pump">
<div>Pump 1</div>
<div>Status: Running</div>
<div>Runtime: 5.2 hrs</div>
</div>
<div class="pump">
<div>Pump 2</div>
<div>Status: Running</div>
<div>Runtime: 4.8 hrs</div>
</div>
</div>
</div>
<div class="station">
<div class="station-header">
<span>Lift Station #3</span>
<span class="station-status alarm"></span>
</div>
<div>Level: 9.5 ft</div>
<div>Flow: 50 GPM</div>
<div class="pump-details">
<div class="pump">
<div>Pump 1</div>
<div>Status: Fault</div>
<div>Runtime: 1.2 hrs</div>
</div>
<div class="pump">
<div>Pump 2</div>
<div>Status: Running</div>
<div>Runtime: 7.5 hrs</div>
</div>
</div>
</div>
</div>
<a href="/" class="button">Back to Main Dashboard</a>
</div>
</body>
</html>
flask
jsonify
requests
pydantic
gevent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>City Water Control System</title>
<style>
body {
font-family: 'MS Sans Serif', Arial, sans-serif;
background-color: #c0c0c0;
color: #000;
margin: 0;
padding: 20px;
}
h1 {
text-align: center;
background-color: #000080;
color: #fff;
padding: 10px;
margin-top: 0;
}
.main-container {
display: flex;
justify-content: space-around;
margin-top: 20px;
}
.group-box {
background-color: #d4d0c8;
border: 2px outset #fff;
padding: 10px;
width: 45%;
}
.group-box h2 {
background-color: #000080;
color: #fff;
margin: -10px -10px 10px -10px;
padding: 5px;
font-size: 1.2em;
}
.control-box {
background-color: #d4d0c8;
border: 1px solid #888;
padding: 10px;
margin-bottom: 10px;
}
.control-box h3 {
margin-top: 0;
font-size: 1em;
}
label {
display: inline-block;
width: 80px;
margin-bottom: 5px;
}
select, button {
width: 120px;
background-color: #fff;
color: #000;
border: 1px inset #888;
padding: 2px;
}
button {
background-color: #d4d0c8;
border: 2px outset #fff;
padding: 5px;
margin-top: 5px;
cursor: pointer;
}
button:active {
border-style: inset;
}
form {
display: inline;
}
</style>
</head>
<body>
<h1>City Water Control System</h1>
<div class="main-container">
<div class="group-box">
<h2>Well Controls</h2>
<div class="control-box">
<h3>Well 1</h3>
<form action="/well-details.html" method="post">
<input type="hidden" name="control" value="Well 1">
<label for="well1_status">Status:</label>
<select name="action" id="well1_status">
<option value="lead">Lead</option>
<option value="standby">Standby</option>
<option value="off">Off</option>
</select><br>
<button type="submit">Set Well 1</button>
</form>
</div>
<div class="control-box">
<h3>Well 2</h3>
<form action="/well-details.html" method="post">
<input type="hidden" name="control" value="Well 2">
<label for="well2_status">Status:</label>
<select name="action" id="well2_status">
<option value="lead">Lead</option>
<option value="standby">Standby</option>
<option value="off">Off</option>
</select><br>
<button type="submit">Set Well 2</button>
</form>
</div>
<div class="control-box">
<h3>Well 3</h3>
<form action="/well-details.html" method="post">
<input type="hidden" name="control" value="Well 3">
<label for="well3_status">Status:</label>
<select name="action" id="well3_status">
<option value="lead">Lead</option>
<option value="standby">Standby</option>
<option value="off">Off</option>
</select><br>
<button type="submit">Set Well 3</button>
</form>
</div>
</div>
<div class="group-box">
<h2>Alternator Controls</h2>
<div class="control-box">
<h3>Alternator 1</h3>
<form action="/well-details.html" method="post">
<input type="hidden" name="control" value="Alternator 1">
<label for="alt1_status">Status:</label>
<select name="action" id="alt1_status">
<option value="on">On</option>
<option value="off">Off</option>
</select><br>
<button type="submit">Set Alternator 1</button>
</form>
</div>
<div class="control-box">
<h3>Alternator 2</h3>
<form action="/well-details.html" method="post">
<input type="hidden" name="control" value="Alternator 2">
<label for="alt2_status">Status:</label>
<select name="action" id="alt2_status">
<option value="on">On</option>
<option value="off">Off</option>
</select><br>
<button type="submit">Set Alternator 2</button>
</form>
</div>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment