[PYTHON] CTF-Anfänger haben versucht, einen Problemserver (Web) zu erstellen [Problem]

Einführung

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.

wichtiger Punkt

Aufgrund seiner Natur ist der Server anfällig. Bitte implementieren Sie den Inhalt dieses Artikels nicht, da er sich in einer Produktionsumgebung befindet.

Annahme

Was ist CTF (Capture The Flag)?

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.

Technologieauswahl

Regeln auf diesem Issue-Server

Mit anderen Worten, es gibt 3 Daten in Form von "myctf {flag}" auf diesem Websystem. Bitte finden Sie sie.

Erstellen Sie einen Server

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

Datei, in der das Flag beschrieben wird

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}

Einstellungsdatei

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-Datei für die Datenbankinitialisierung

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.

Ausführungsdatei

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.

jinja2 Vorlagendatei

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>

Starten und überprüfen

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.

2019-12-04 12.06.27 localhost e3de80904c2e.png

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".

2019-12-04 12.06.52 localhost c4217ceed7b3.png

Es sollte durchsucht worden sein.

Andere

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.

Schließlich

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

CTF-Anfänger haben versucht, einen Problemserver (Web) zu erstellen [Problem]
Lassen Sie uns einen WEB-Server mit Chromebook einrichten
Ich habe eine Web-API erstellt
Ich habe versucht, eine Super-Resolution-Methode / ESPCN zu erstellen
Ich habe versucht, eine Super-Resolution-Methode / SRCNN build zu erstellen
Ich habe versucht, eine Super-Resolution-Methode / SRCNN build zu erstellen
Ich habe versucht, eine Super-Resolution-Methode / SRCNN build zu erstellen
Anfänger haben versucht, eine Cloud-native Webanwendung mit Datastore / GAE zu erstellen
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 1-
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 2-
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 0-
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 5-
[Teil 2] Erstellen wir einen Webserver mit EC2 Linux
[Go + Gin] Ich habe versucht, eine Docker-Umgebung zu erstellen
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 4-
[Anfänger] [Python / Django] Ein junger Webingenieur hat ein Django-Tutorial ausprobiert - Teil 3-
Quellkompilierung Apache2.4 (httpd 2.4.43) + PHP7.4 unter Linux zum Erstellen eines Webservers --3 MySQL 8.0 Einführung
Memo Ein Anfänger hat versucht, eine Java-Umgebung zu erstellen und unter Ubuntu 18.04.2 LTS ins Japanische zu übersetzen.
Erstellen Sie mit hug einen Web-API-Server mit explosiver Geschwindigkeit
Ich habe versucht, das Problem der Kombinationsoptimierung mit Qiskit zu lösen
Erstellen Sie mit Falcon einen Light-Speed-Web-API-Server
[Einführung in AWS] Memorandum zum Erstellen eines Webservers auf AWS
Python-Anfänger versuchte, bei einem IT-Unternehmen zu praktizieren
Ich habe versucht, eine Serverumgebung zu erstellen, die unter Windows 10 ausgeführt wird
So erstellen Sie einen NEM-Knoten (aktuelle Version) (NIS1: NEM Infrastructure Server)
Ich habe mit Razpai einen Webserver erstellt, um Anime zu schauen
Erstellen Sie eine Webanwendung mit Django
Ich habe versucht, eine SATA-Software-RAID-Konfiguration zu erstellen, die das Betriebssystem unter Ubuntu Server startet
Ich habe versucht, mit einem Remote-Server über Socket-Kommunikation mit Python zu kommunizieren.
Ich habe versucht, eine Mac Python-Entwicklungsumgebung mit pythonz + direnv zu erstellen
Starten Sie einen Webserver mit Bottle and Flask (ich habe auch versucht, Apache zu verwenden)
Ich habe versucht, einen Linebot zu erstellen (Implementierung)
Erstellen Sie einen Pypi-Cache-Server auf QNAP
Möchten Sie ein einfaches Klassifizierungsproblem lösen?
Wie baue ich meinen eigenen Linux-Server?
Erstellen Sie einfach einen DNS-Server mit Twisted
So erstellen Sie eine Sphinx-Übersetzungsumgebung
Ich habe versucht, einen Linebot zu erstellen (Vorbereitung)
Erstellen Sie einen einfachen WebDAV-Server unter Linux
Ich möchte eine Python-Umgebung erstellen
Erstellen Sie einen Samba-Server unter Arch Linux
[Django-Extensions] Anfänger in der Webentwicklung haben versucht, Django-Extensions zusammenzufassen
Ich habe versucht, das Webanwendungs-Framework zu vergleichen
Ich werde die Infrastruktur weiterhin meiden, weil es schwierig erscheint ... Der Programmierer hat sich bemüht, einen Server zu bauen, um sie zu überwinden. WebAP Server Edition
Ein Python-Anfänger hat versucht, bei einem IT-Unternehmen zu praktizieren [Tag 2 Chatbot-Umfrage]
Atcoder-Anfängerwettbewerb A, B Zusammenfassung der Eingabe, die tendenziell ein Problem für Python darstellt
Python-Anfänger versuchte, bei einem IT-Unternehmen zu praktizieren [Tag 1 Entwicklungsprozess]
Ein Programmieranfänger versuchte, die Ausführungszeit des Sortierens usw. zu überprüfen.
Quellkompilieren Sie Apache2.4 + PHP7.4 mit Raspberry Pi und erstellen Sie einen Webserver --2 PHP Einführung
Quellkompilieren Sie Apache2.4 + PHP7.4 mit Raspberry Pi und erstellen Sie einen Webserver. 1. Apache-Einführung
Quellkompilierung Apache2.4 (httpd 2.4.43) + PHP7.4 unter Linux zum Erstellen eines Webservers ―― 1. Einführung in Apache
Ein Anfänger des maschinellen Lernens versuchte an einem Tag, eine Sheltie-Urteils-KI zu erstellen
[Python] So erstellen Sie eine lokale Webserverumgebung mit SimpleHTTPServer und CGIHTTPServer
Quellkompilierung Apache2.4 (httpd 2.4.43) + PHP7.4 unter Linux zum Erstellen eines Webservers --2 PHP-Einführung
Senden Sie eine Nachricht von Slack an einen Python-Server
Erstellen Sie einen lokalen Server mit einem einzeiligen Befehl [Mac]
Ich habe Web Scraping versucht, um die Texte zu analysieren.
Berechnen wir das statistische Problem mit Python
So öffnen Sie einen Webbrowser über Python
Buch aktualisiert: Entwicklung zu einem "anständigen Webserver"