Connaissez-vous CTF (Capture The Flag)? Grâce à CTF, vous pouvez apprendre tout en rencontrant des problèmes de sécurité. J'ai pensé que j'essaierais d'expliquer le problème en créant moi-même un serveur vulnérable. J'ai fait un serveur pour le problème élémentaire de CTF.
En raison de sa nature, le serveur est vulnérable. Veuillez ne pas implémenter le contenu de cet article car il se trouve dans un environnement de production.
Un concours pour trouver des drapeaux cachés dans les problèmes et gagner des points. Des questions seront posées sur divers problèmes liés à la sécurité informatique. Cette fois, nous nous concentrerons sur le domaine du Web concernant les vulnérabilités des applications Web.
myctf {flag}
.En d'autres termes, il y a 3 données sous la forme de myctf {flag}
sur ce système Web, alors veuillez les trouver.
Docker Network Créez un réseau entre les conteneurs avec le réseau docker.
$ 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:
Veuillez modifier correctement l'utilisateur et le mot de passe.
MySQL Il semble que SQLite soit abordable et souvent utilisé dans CTF, mais comme il est construit avec Docker, j'ai choisi MySQL.
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
Incorporez le drapeau dans / var / ctf / flag.md
.
S'il est résolu dans l'ordre, ce sera le dernier drapeau.
mysql/ctf/flag.md
## flag.md
myctf{mission_complete}
Ajoutez un fichier de configuration MySQL.
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
Ajoutez le paramètre secure-file-priv
pour accéder au fichier.
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", "Ingénieur côté serveur"),
("Jiro", "Suzuki", "Ingénieur front-end"),
("Saburo", "Tanaka", "Ingénieur infrastructure"),
("Hanako", "Sato", "designer");
INSERT INTO users (first_name, last_name, job, delete_flag)
VALUES ("Ichiro", "Watanabe", "myctf{scf_sql_injection_flag}", TRUE); /*1er drapeau(Même tableau) */
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]}"); /*Deuxième drapeau(Une autre table) */
Deux indicateurs sont intégrés dans la base de données. Le premier indicateur est que la table users est une table de suppression logique utilisant delete_flag, qui est incorporée dans les données censées être supprimées. Le deuxième indicateur est intégré dans la table des indicateurs, qui n'est pas référencée sur ce système.
Python
PHP est principalement utilisé pour les problèmes Web CTF, mais comme l'environnement back-end au travail est Python, je l'ai implémenté en Python. C'était sobre et difficile. (Je l'ai d'abord fait à partir du système PHP) Je pense que Python est souvent utilisé dans le CTF réel, comme les scripts automatisés pour l'acquisition de drapeaux.
Lors de la création d'une application web avec Python, ce sera difficile si vous n'utilisez pas de frameworks tels que Django et Flask, mais afin de créer des vulnérabilités, je vais créer autant que possible sans compter sur des frameworks.
DockerFile
python/Dockerfile
FROM python:3.8
WORKDIR /app
CMD bash -c "pip install -r ./requirements.txt && python app.py"
EXPOSE 8000
Requirements Files
Certains utilisent des bibliothèques externes. Décrivez le Lyle Rally à installer dans les fichiers d'exigences.
python/src/requirements.txt
Jinja2~=2.10
PyMySQL~=0.9
Il était difficile de coder en dur la syntaxe HTML avec python, je vais donc utiliser Jinja2 comme moteur de modèle.
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()
Veuillez corriger l'utilisateur et le mot de passe en fonction des valeurs modifiées par Docker Compose.
Dans la génération de l'instruction SQL, le jugement de delete_flag = FALSE
est inclus car il s'agit d'une suppression logique.
python/src/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Expérience CTF</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="Recherche de type d'emploi" value="{{ query }}">
</div>
<button type="submit" class="btn btn-primary mb-2 mx-sm-4">Chercher</button>
</form>
{% if query != '' %}
<p><span class="text-danger">{{ query }}</span>Résultats de recherche</p>
{% endif %}
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Nom de famille</th>
<th scope="col">Nom</th>
<th scope="col">Occupation</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>
C'est la structure du répertoire.
├─ 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
Exécuter
$ docker-compose up -d
Une fois le conteneur démarré, accédez à http: // localhost
à partir d'un navigateur Web.
Vous devriez voir une page qui ressemble à l'image.
Entrez «ingénieur» dans la zone de texte de recherche d'emploi et cliquez sur le bouton «rechercher».
Il aurait dû être fouillé.
Cette fois, c’est juste un problème d’injection SQL, Il existe également des scripts intersites Web classiques et de nombreuses autres vulnérabilités. Au contraire, il est plein de vulnérabilités, et du côté de la résolution de problèmes, il peut ne pas être clair par quoi commencer. Si j'en ai envie, j'essaierai de créer un problème de script intersite.
La session d'étude de sécurité peut devenir un "crime lié aux enregistrements électromagnétiques de commande frauduleuse" Bien qu'il ait parfois été annulé (http://ozuma.sakura.ne.jp/sumida/2019/03/15/77/), Cet article lui-même, pour expliquer la vulnérabilité, Je prie pour que vous ne soyez pas une "infraction pénale concernant les enregistrements électromagnétiques de commande illégale".
Le référentiel complété est ici La version PHP du référentiel qui a été créé en parallèle est ici Cliquez ici pour le référentiel créé avec go language + PostgreSQL (https://github.com/fiotto/ctf-server-web-for-golang) Comme le langage go est un langage typé statiquement, il est difficile de deviner la définition de la table car une erreur se produira si vous UNION avec le mauvais type.
Pour la méthode de réponse de cette question, voir Les débutants de la CTF ont essayé de créer un serveur de questions (Web) [Réponse].
Recommended Posts