Kennen Sie CTF (Capture The Flag)? Über CTF können Sie lernen, während Sicherheitsprobleme auftreten. Ich dachte, ich würde versuchen, das Problem zu erklären, während ich selbst einen anfälligen Server erstelle. Ich habe einen Server für das elementare Problem der CTF erstellt.
Aufgrund seiner Natur ist der Server anfällig. Bitte implementieren Sie den Inhalt dieses Artikels nicht, da er sich in einer Produktionsumgebung befindet.
Ein Wettbewerb, um versteckte Flaggen in Problemen zu finden und Punkte zu sammeln. Es werden Fragen zu verschiedenen Fragen im Zusammenhang mit der Computersicherheit gestellt. Dieses Mal konzentrieren wir uns auf das Webfeld im Zusammenhang mit Schwachstellen in Webanwendungen.
Mit anderen Worten, es gibt 3 Daten in Form von "myctf {flag}" auf diesem Websystem. Bitte finden Sie sie.
Docker Network Erstellen Sie ein Netzwerk zwischen Containern mit Docker-Netzwerk.
$ docker network create ctf-network
Docker Compose
docker-compose.yml
version: '3.3'
services:
app-python:
container_name: app-python
build:
context: ./python
dockerfile: Dockerfile
tty: true
volumes:
- ${PWD}/python/src:/app
ports:
- "80:8000"
networks:
- ctf-network
db1:
container_name: mysql
build:
context: ./mysql
dockerfile: Dockerfile
environment:
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- MYSQL_ROOT_PASSWORD=password
volumes:
- ./mysql/mysql_conf:/etc/mysql/conf.d
- ./mysql/initdb.d:/docker-entrypoint-initdb.d
networks:
- ctf-network
networks:
ctf-network:
Bitte ändern Sie Benutzer und Passwort entsprechend.
MySQL Es scheint, dass SQLite erschwinglich ist und häufig in CTF verwendet wird, aber da es mit Docker erstellt wurde, habe ich mich für MySQL entschieden.
DockerFile
mysql/Dockerfile
FROM mysql:8.0
ADD ./ctf/flag.md /var/ctf/flag.md
RUN mkdir /var/log/mysql
RUN chown mysql:adm /var/log/mysql
Betten Sie das Flag in / var / ctf / flag.md
ein.
Wenn in der richtigen Reihenfolge gelöst, ist dies die letzte Flagge.
mysql/ctf/flag.md
## flag.md
myctf{mission_complete}
Fügen Sie eine MySQL-Konfigurationsdatei hinzu.
mysql/mysql_conf/custom.cnf
[mysqld]
default_authentication_plugin=mysql_native_password
character-set-server=utf8
collation-server=utf8_general_ci
general_log=ON
general_log_file=/var/log/mysql/query.log
secure-file-priv = ""
[client]
default-character-set=utf8
Fügen Sie die Einstellung "Secure-File-Priv" hinzu, um auf die Datei zuzugreifen.
sql:mysql/initdb.d/init.sql
SET CHARSET UTF8;
DROP DATABASE IF EXISTS ctf_db;
CREATE DATABASE ctf_db;
USE ctf_db;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(30) NOT NULL,
last_name VARCHAR(30) NOT NULL,
job VARCHAR(30) NOT NULL,
delete_flag BOOLEAN NOT NULL DEFAULT FALSE
)DEFAULT CHARACTER SET=utf8;
INSERT INTO users (first_name, last_name, job)
VALUES
("Taro", "Yamada", "Servertechniker"),
("Jiro", "Suzuki", "Front-End-Ingenieur"),
("Saburo", "Tanaka", "Infrastrukturingenieur"),
("Hanako", "Sato", "Designer");
INSERT INTO users (first_name, last_name, job, delete_flag)
VALUES ("Ichiro", "Watanabe", "myctf{scf_sql_injection_flag}", TRUE); /*1. Flagge(Gleicher Tisch) */
DROP TABLE IF EXISTS flag;
CREATE TABLE flag (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
flag VARCHAR(60) NOT NULL,
create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)DEFAULT CHARACTER SET=utf8;
INSERT INTO flag (flag)
VALUES ("myctf{next_flag_[/var/ctf/flag.md]}"); /*Zweite Flagge(Ein weiterer Tisch) */
In die Datenbank sind zwei Flags eingebettet. Das erste Flag ist, dass die Benutzertabelle eine logische Löschtabelle mit delete_flag ist, die in die Daten eingebettet ist, die gelöscht werden sollen. Das zweite Flag ist in die Flag-Tabelle eingebettet, auf die auf diesem System nicht verwiesen wird.
Python
PHP wird hauptsächlich für CTF-Webprobleme verwendet, aber da die Back-End-Umgebung bei der Arbeit Python ist, habe ich es in Python implementiert. Das war nüchtern und schwierig. (Ich habe es zuerst aus dem PHP-System gemacht) Ich bin der Meinung, dass Python häufig in CTF verwendet wird, beispielsweise in automatisierten Skripten für die Flaggenerfassung.
Wenn Sie eine Webanwendung mit Python erstellen, ist es schwierig, wenn Sie keine Frameworks wie Django und Flask verwenden. Um jedoch Schwachstellen zu erstellen, werde ich so viel wie möglich erstellen, ohne mich auf Frameworks zu verlassen.
DockerFile
python/Dockerfile
FROM python:3.8
WORKDIR /app
CMD bash -c "pip install -r ./requirements.txt && python app.py"
EXPOSE 8000
Requirements Files
Einige verwenden externe Bibliotheken. Beschreiben Sie die Lyle Rally, die in den Anforderungsdateien installiert werden soll.
python/src/requirements.txt
Jinja2~=2.10
PyMySQL~=0.9
Es war schwierig, die HTML-Syntax mit Python zu codieren, daher werde ich Jinja2 als Vorlagen-Engine verwenden.
python/src/app.py
import socketserver
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
import pymysql.cursors
from jinja2 import Template, Environment, FileSystemLoader
PORT = 8000
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
conn = pymysql.connect(host='mysql',
user='root',
password='password',
db='ctf_db',
charset='utf8',
autocommit=True,
cursorclass=pymysql.cursors.DictCursor)
try:
url = urlparse(self.path)
if url.path == '/':
params = parse_qs(url.query)
query = params.get('q', [''])[0]
with conn.cursor() as cursor:
sql = f"SELECT * FROM users WHERE delete_flag=FALSE AND job LIKE '%{query}%';"
cursor.execute(sql)
users = cursor.fetchall()
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('index.html')
data = {
'query': query,
'users': users
}
disp_text = template.render(data)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(disp_text.encode('utf-8'))
else:
self.send_response(404)
self.send_header('Content-type', 'text/html')
self.end_headers()
except Exception as e:
print(e)
self.send_response(500)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(str(e).encode('utf-8'))
finally:
conn.close()
with socketserver.TCPServer(("", PORT), MyHandler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
Bitte ändern Sie Benutzer und Passwort in die von Docker Compose geänderten Werte. Bei der Generierung der SQL-Anweisung wird das Urteil "delete_flag = FALSE" berücksichtigt, da es sich um eine logische Löschung handelt.
python/src/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>CTF Erfahrung</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<form class="form-inline my-3">
<div class="form-group mb-2">
<input type="text" name="q" class="form-control" placeholder="Jobsorte suchen" value="{{ query }}">
</div>
<button type="submit" class="btn btn-primary mb-2 mx-sm-4">Suche</button>
</form>
{% if query != '' %}
<p><span class="text-danger">{{ query }}</span>Suchergebnisse</p>
{% endif %}
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Nachname</th>
<th scope="col">Name</th>
<th scope="col">Besetzung</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.last_name }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.job }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
Dies ist die Struktur des Verzeichnisses.
├─ docker-compose.yml
├─ mysql
│ ├─ Dockerfile
│ ├─ ctf
│ │ └─ flag.md
│ ├─ initdb.d
│ │ └─ init.sql
│ └─ mysql_conf
│ └─ custom.cnf
└─ python
├─ Dockerfile
└─ src
├─ app.py
├─ index.html
└─ requirements.txt
Lauf
$ docker-compose up -d
Nachdem der Container gestartet wurde, greifen Sie über einen Webbrowser auf "http: // localhost" zu.
Sie sollten eine Seite sehen, die wie das Bild aussieht.
Geben Sie "Ingenieur" in das Textfeld für die Jobsuche ein und klicken Sie auf die Schaltfläche "Suchen".
Es sollte durchsucht worden sein.
Diesmal handelt es sich nur um ein SQL-Injection-Problem. Es gibt auch klassisches Cross-Site-Scripting im Internet und viele andere Sicherheitslücken. Vielmehr ist es voller Schwachstellen, und von der Seite der Problemlösung ist möglicherweise nicht klar, mit was man anfangen soll. Wenn ich Lust dazu habe, werde ich versuchen, ein Cross-Site-Scripting-Problem zu erstellen.
Die Sicherheitsstudiensitzung kann zu einem "Verbrechen im Zusammenhang mit betrügerischen elektromagnetischen Befehlsaufzeichnungen" werden. Obwohl es manchmal abgesagt wurde (http://ozuma.sakura.ne.jp/sumida/2019/03/15/77/), Dieser Artikel selbst, als Erklärung für die Sicherheitsanfälligkeit, Ich bete, dass Sie keine "Straftat in Bezug auf illegale elektromagnetische Befehlsaufzeichnungen" darstellen.
Das fertige Repository ist hier Die PHP-Version des parallel erstellten Repositorys ist hier. Klicken Sie hier, um das mit go language + PostgreSQL erstellte Repository aufzurufen (https://github.com/fiotto/ctf-server-web-for-golang). Da die go-Sprache eine statisch typisierte Sprache ist, ist es schwierig, die Tabellendefinition zu erraten, da ein Fehler auftritt, wenn Sie UNION mit dem falschen Typ verwenden.
Die Antwortmethode für diese Frage finden Sie unter CTF-Anfänger haben versucht, einen Fragenserver (Web) zu erstellen [Antwort].
Recommended Posts