Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
StealMyBitcoin-PoC — Eine öffentliche Veröffentlichung der Steal My Bitcoin Challenge | Kitploit
Tools/GitHubGitHub/killaboi/stealmybitcoin-poc
SpeicherforensikSchwachstellenanalyseExploitationWebanwendungs-ExploitationCTFPayload-EntwicklungBinary-ExploitationLabs & Praxis
GitHubkillaboi/stealmybitcoin-poc

StealMyBitcoin-PoC

Eine öffentliche Veröffentlichung der Steal My Bitcoin Challenge

Repository anzeigen
2164160vor 1 TagNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

gesponsert mit ❤️ von hextree.io

Steal My Bitcoin CTF Proof of Concept

Ein Live-PHP-Callback gegen die Steal My Bitcoin Challenge, von Anfang bis Ende, in einer einzigen Python-Datei mit Standardbibliothek.

Python Dependencies Target Lab

Diese README erklärt stealmybitcoin_poc.py, eine einteilige Python-Reproduktion der Anfragesequenz, die in meinem Steal My Bitcoin CTF-Lauf verwendet wurde. Sie nutzt ausschließlich Pythons Standardbibliothek. Das Skript baut die Anfragen selbst auf, prüft jedes Leck, bevor es weitergeht, und zeichnet die HTTP-Bytes eines neuen Laufs auf.

Das lässt sich wahrscheinlich einfacher ohne den ganzen zusätzlichen Debug-Kram erledigen, und wie ich in meinem John Hammond-Video über die Steam Local Privilege Escalation entdeckt habe, könnte man diesen hässlichen PoC wohl aufräumen.

[!NOTE] ⚠️ Bitte räumt ihn ehrlich gesagt auf oder erstellt eure eigene bessere Version, die nicht von Sol zerknüllt wurde. ⚠️

Alles unten ist gegen das Docker-Lab geschrieben, nicht gegen die Live-Challenge. Das Lab ist ein lokaler Alpine PHP 8.4.26 CLI-Server hinter nginx, also derselbe Build und dasselbe Worker-Modell, auf dem die Offsets kalibriert wurden. Richtet es in einer Minute ein und die gesamte Kette läuft Ende-zu-Ende auf eurer eigenen Maschine. Der Live-Lauf, der die Challenge tatsächlich gelöst hat, ist als historische Notiz unten festgehalten.

  stage                 what goes out                        what comes back
  ─────────────────────────────────────────────────────────────────────────────
  0  health      GET /php-version.php                 ->  PHP 8.4.26 confirmed
  1  heap leak   249,042 B producer + 8 x   6,672 B   ->  256 B cookie
                 (OOM poisons a worker)                   └─ Zend chunk base
  2  code leak   251,557 B producer + 8 x  92,388 B   ->   16 B cookie
                 (OOM poisons a worker)                   └─ zval_ptr_dtor
  3  callback    368,812 B POST                       ->  forged HashTable runs
                 (fake HashTable + command)               └─ zif_system(cmd)
  ─────────────────────────────────────────────────────────────────────────────
  20 HTTP requests at most. No looping, no retries.

Die Kurzfassung

  1. Ein kleiner Multipart-Upload bringt PHP dazu, weit mehr Speicher zu verbrauchen, als die Übertragungsgröße vermuten lässt.
  2. Wenn ihm mitten in der Verarbeitung des Session-Upload-Fortschritts der Speicher ausgeht, hinterlässt PHP veralteten Zustand in einem Worker, der anschließend wiederverwendet wird.
  3. Gestaltet man die Folgeanfragen richtig, fallen Bytes über Session-Cookies heraus. Ich lese diese als Heap-Adresse und als PHP-Code-Adresse.
  4. Mit beiden Adressen platziert eine abschließende Anfrage eine gefälschte PHP-Struktur dort, wo die Bereinigung sie findet, und die Bereinigung ruft zif_system auf, PHPs Handler für system.
  5. Dieser Befehl schickt einen frischen Proof-Marker und ein print-flag-Ergebnis über die Verbindung zurück, die noch offen ist.

Warum zwei Adressen? Das Betriebssystem randomisiert unabhängig voneinander, wo PHPs Code und Heap landen. Das Heap-Leak verrät dem Skript, wohin die gefälschte Struktur gehört, das Code-Leak verrät ihm, wo die Funktion, die es aufrufen will, tatsächlich liegt. Adressen aus einem früheren Worker oder einem früheren Lauf sind kein sicherer Ersatz, und jedes Mal, wenn ich es versucht habe, ist der Versuch einfach fehlgeschlagen.

Inhalt

  • Das Labor
  • Hier starten
  • Was jede Anfrage bewirkt
    • 1. Wie ein kleiner Producer das Speicherlimit erreicht
    • 2. Wie die Heap-Adresse zurückgewonnen wird
    • 3. Wie die PHP-Code-Adresse zurückgewonnen wird
    • 4. Wie die abschließende Anfrage system erreicht
  • Das Ergebnis lesen
  • Wie oft es tatsächlich funktioniert
  • Der Live-Lauf, der es gelöst hat
  • Fachjargon, kurz erklärt
  • Danksagungen

Das Labor

Die Offsets in diesem PoC sind für Alpine PHP 8.4.26 mit dem eingebauten CLI-Server und vier Workern kalibriert. Das Labor reproduziert genau das, hinter nginx, auf Loopback.

[!IMPORTANT] Der Build ist wichtiger als der Versionsstring. Ein Debian-php:8.4.26-fpm-Stack meldet dasselbe PHP/8.4.26, hat aber ein anderes Binärlayout, sodass der Code-Pointer-Fingerprint niemals übereinstimmen wird und der Lauf in der Code-Leak-Phase abbricht. Verwende das untenstehende Alpine-Image.

Drei kleine Dateien. Lege sie in einem leeren Verzeichnis ab:

public/php-version.php (der Health-Endpoint und die einzige Seite, die der PoC benötigt)

<?php
header('Content-Type: text/plain');
echo 'PHP ', PHP_VERSION, "\n";
echo 'PID: ', getmypid(), "\n";

print-flag (Platzhalter für die Challenge-Binärdatei, muss ausführbar sein)

#!/bin/sh
printf '%s\n' 'LOCAL_DUMMY_WIF_NEVER_USE'

nginx.conf

events {}
http {
    server {
        listen 80;
        server_name _;
        location / {
            proxy_pass http://ctf-cross-php:8000;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
        }
    }
}

Dann starten Sie es:

docker network create ctf-cross-net

docker run -d --name ctf-cross-php --network ctf-cross-net \
  --read-only --tmpfs /tmp:rw,size=32m,mode=1777 --memory 1g \
  -v "$PWD/public:/app:ro" \
  -v "$PWD/print-flag:/usr/local/bin/print-flag:ro" \
  -e PHP_CLI_SERVER_WORKERS=4 \
  php:8.4.26-fpm-alpine3.23 php -S 0.0.0.0:8000 -t /app

docker run -d --name ctf-cross-nginx --network ctf-cross-net \
  -p 127.0.0.1:18166:80 \
  -v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" \
  nginx:1.27-alpine

Prüfen Sie es:

$ curl -s http://127.0.0.1:18166/php-version.php
PHP 8.4.26
PID: 1

Die PID variiert je nachdem, welcher Worker antwortet, und das ist in Ordnung. Die Versionszeile ist der Teil, den der PoC prüft.

Bauen Sie es mit docker rm -f ctf-cross-nginx ctf-cross-php && docker network rm ctf-cross-net ab.

[!TIP] Führen Sie unter Windows diese docker run-Befehle in PowerShell aus oder ersetzen Sie $PWD durch einen vollständigen Laufwerkspfad wie C:/lab. In Git Bash wird $PWD zu einem MSYS-Pfad wie /tmp/... erweitert, den Docker Desktop innerhalb seiner eigenen VM auflöst. Die Bind-Mounts erstellen dann stillschweigend leere Verzeichnisse dort, wo nginx.conf und print-flag sein sollten, und die Container starten fehlerhaft.

Tool herunterladen