Skip to content

Instantly share code, notes, and snippets.

@cr0nx
Created May 23, 2025 11:21
Show Gist options
  • Select an option

  • Save cr0nx/588d910144549e5f7a5136b7fd662466 to your computer and use it in GitHub Desktop.

Select an option

Save cr0nx/588d910144549e5f7a5136b7fd662466 to your computer and use it in GitHub Desktop.
memfd_create blocker using Python+bpftrace -> Kill the ppid of memfd_create call
import subprocess
import os
import signal
import re
# bpftrace script (embedded)
BPFTRACE_SCRIPT = """
#include <linux/sched.h>
#include <linux/cred.h>
tracepoint:raw_syscalls:sys_enter
/args->id == 319/ { // 319 is the syscall number for memfd_create
$name = str(args->args[0], 128);
$flags = args->args[1];
$parent_pid = ((struct task_struct *)curtask)->parent->pid;
$parent_uid = ((struct task_struct *)curtask)->parent->cred->uid.val;
printf("PID %d (%s) called memfd_create(name=%s, flags=%d), parent PID %d, parent UID %d\\n",
pid, comm, $name, $flags, $parent_pid, $parent_uid);
}
"""
def main():
# Write bpftrace script to a temporary file
with open("/tmp/memfd_trace_ppid_uid.bt", "w") as f:
f.write(BPFTRACE_SCRIPT)
try:
# Run bpftrace as a subprocess
process = subprocess.Popen(
["sudo", "bpftrace", "/tmp/memfd_trace_ppid_uid.bt"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
# Regex to parse bpftrace output
pattern = re.compile(r"PID (\d+) \((.*?)\) called memfd_create\(name=(.*?), flags=(\d+)\), parent PID (\d+), parent UID (\d+)")
print("Monitoring memfd_create calls and sending SIGKILL to parent PIDs (UID 1000-2000)... Ctrl-C to exit")
# Read bpftrace output
for line in process.stdout:
print(f"Raw output: {line.strip()}") # Debug: print raw line
match = pattern.search(line.strip())
if match:
pid = int(match.group(1))
comm = match.group(2)
name = match.group(3)
flags = int(match.group(4))
parent_pid = int(match.group(5))
parent_uid = int(match.group(6))
print(f"Parsed: PID {pid} ({comm}), name={name}, flags={flags}, parent PID {parent_pid}, parent UID {parent_uid}")
# Check UID range (1000-2000)
if 1000 <= parent_uid <= 2000:
try:
if os.path.exists(f"/proc/{parent_pid}"):
os.kill(parent_pid, signal.SIGKILL)
print(f"Sent SIGKILL to parent PID {parent_pid} (UID {parent_uid})")
else:
print(f"Parent PID {parent_pid} does not exist")
except OSError as e:
print(f"Failed to send SIGKILL to parent PID {parent_pid}: {e}")
else:
print(f"Parent UID {parent_uid} outside range 1000-2000, skipping SIGKILL")
else:
print(f"Failed to parse line: {line.strip()}")
# Print stderr (for bpftrace errors)
for line in process.stderr:
print(f"bpftrace error: {line.strip()}")
except KeyboardInterrupt:
print("\nStopping bpftrace...")
process.terminate()
process.wait()
except Exception as e:
print(f"Error: {e}")
finally:
if os.path.exists("/tmp/memfd_trace_ppid_uid.bt"):
os.remove("/tmp/memfd_trace_ppid_uid.bt")
if __name__ == "__main__":
main()
@cr0nx
Copy link
Author

cr0nx commented Jun 4, 2025

Find more interesting stuff here: https://edu.defensive-security.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment