# Python .pth Startup Files Abused for Persistence (UPSTYLE backdoor in GlobalProtect CVE-2024-3400 exploitation)

> Python path-configuration (.pth) files execute any line beginning with 'import' followed by a space or tab each time the interpreter starts, giving attackers a stealthy persistence and execution hook that default tooling rarely inspects. The technique was used in the wild by UTA0218 in the UPSTYLE Python backdoor (update.py writing system.pth) deployed after exploiting Palo Alto PAN-OS GlobalProtect CVE-2024-3400.

- **Published:** 2026-10-21T04:47:10Z
- **Last reviewed:** 2026-10-21T04:47:10Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-4011
- **ID:** TL-2026-4011
- **Severity:** MEDIUM
- **Category:** THREAT_INTEL
- **Status:** ACTIVE
- **Actor:** UTA0218
- **Detections:** 9 · **IOCs:** 13 (full data via the Threadlinqs MCP server — Purple tier)
- **CVEs:** CVE-2024-3400

## Description

Python's site module processes .pth files found in site-packages / dist-packages directories at interpreter start-up. Lines that begin with 'import' followed by a space or tab are passed to exec(), so a single line such as 'import os; os.system(...)' runs arbitrary code whenever any Python process starts or the site module is imported (behavior documented in the Python site module docs; executed lines are supported since Python 3.5 per dfir.ch). Files in a directory are processed in alphabetical order. Interpreter flag -S suppresses the site module and therefore .pth processing; -s disables only the user site-packages directory. Python 3.15 deprecates executing 'import' lines in .pth files (still executed, diagnostic only with -v), with removal planned in later releases; .start files are the documented migration path.

dfir.ch (2025-01-14) analyzes the technique and lists example locations: /usr/lib/python3.6/site-packages/, /usr/local/lib/python3.12/dist-packages/ and the per-user /root/.local/lib/python3.12/site-packages/. The article's researcher test artifact is /usr/local/lib/python3.12/dist-packages/malmoeb.pth. The article notes that default security tooling typically misses .pth persistence and recommends monitoring creation of new (and hidden) .pth files in site-packages directories, and Python -> Bash -> nc process chains. It also points to CPython issue #113659 and the SafeBreach talk 'I'm In Your $PYTHONPATH, Backdooring Your Python Programs' (Itzik Kotler) for the related $PYTHONPATH redirection technique.

Real-world precedent: Volexity (2024-04-12) documented UTA0218, assessed as likely state-backed, exploiting the unauthenticated OS command injection CVE-2024-3400 in Palo Alto Networks PAN-OS GlobalProtect (CVSS 10.0 per vendor/Volexity). Volexity tracked the Python backdoor as UPSTYLE: update.py (MD5 0c1554888ce9ed0da1583dbdf7b31651, SHA256 3de2a4392b8715bad070b2ae12243f166ead37830f7c6d24e778985927f9caac) is dropped and writes a system.pth (dfir.ch cites /usr/lib/python3.6/site-packages/system.pth) whose base64-encoded payload executes on Python module imports. UPSTYLE parses the nginx error log (sslvpn_ngx_error.log) for attacker-supplied command patterns, executes them, writes output to a bootstrap CSS file, and cleans up artifacts within about 15 seconds; a signal handler protects the component from deletion. Post-exploitation described by Volexity includes cron jobs fetching remote 'policy' files every 60 seconds, reverse shells, firewall configuration exfiltration, the GOST tunneling tool and reverse-SSH, a worldtimeapi.org connectivity beacon, lateral movement over SMB/RDP with compromised service accounts, and theft of Chrome/Edge browser data, NTDS.DIT and DPAPI keys. Volexity's observed timeline: 2024-03-26 reconnaissance (zero-byte file), 2024-04-07 failed backdoor deployment, 2024-04-10 successful exploitation, 2024-04-11 second compromise.

The CVE is referenced context rather than the subject of the dfir.ch article; the technique applies to any host with a Python interpreter and write access to a site directory. No CVSS is assigned to the technique itself.

## MITRE ATT&CK

- T1190 Exploit Public-Facing Application
- T1546.018 Python Startup Hooks
- T1546.018 Python Startup Hooks
- T1053.003 Cron
- T1059.006 Python
- T1059.004 Unix Shell
- T1027.010 Command Obfuscation
- T1070.004 File Deletion
- T1132.001 Standard Encoding
- T1572 Protocol Tunneling
- T1555.003 Credentials from Web Browsers
- T1003.003 NTDS
- T1021.004 SSH

## Sources

- [Analysis of Python's .pth files as a persistence mechanism (dfir.ch)](https://dfir.ch/posts/publish_python_pth_extension/)
- [Volexity: Zero-Day Exploitation of Unauthenticated RCE Vulnerability in GlobalProtect (CVE-2024-3400)](https://www.volexity.com/blog/2024/04/12/zero-day-exploitation-of-unauthenticated-remote-code-execution-vulnerability-in-globalprotect-cve-2024-3400/)
- [Palo Alto Networks Security Advisory CVE-2024-3400](https://security.paloaltonetworks.com/CVE-2024-3400)
- [NVD: CVE-2024-3400](https://nvd.nist.gov/vuln/detail/CVE-2024-3400)
- [CISA Known Exploited Vulnerabilities Catalog (CVE-2024-3400 added 2024-04-12)](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
- [Python docs: site - Site-specific configuration hook](https://docs.python.org/3/library/site.html)
- [CPython issue #113659](https://github.com/python/cpython/issues/113659)
- [Centre for Cybersecurity Belgium: CVE-2024-3400 GlobalProtect actively exploited](https://ccb.belgium.be/advisories/warning-cve-2024-3400-globalprotect-gateway-actively-exploited-patch-immediately)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-4011
