Python Startup Hooks (MITRE ATT&CK T1546.018) abuse the way Python initializes itself. It affects Linux, macOS and Windows, and it matters wherever Python runs automation or production workloads.
How attackers use it
MITRE names three mechanisms that Python processes at startup:
- Path configuration files with a
.pthextension. They are meant to extend Python's module search path. If one sits insite-packagesordist-packages, any line beginning withimportruns automatically when Python is invoked. sitecustomize.py, imported during interpreter startup if it is on the Python path.usercustomize.py, handled the same way.
Code in these files runs whenever Python is invoked, with no obvious trigger. An adversary who can write to those directories gets persistence on any system where Python is used often.
This ties to the software supply chain. A package that drops a .pth file or a customize module during install gets a hook that outlives the package's own code paths. It is a good reason to know exactly what your dependencies write to site-packages.
How to detect it
MITRE's strategy for Linux points to:
- Unauthorized creation or modification of
.pth,sitecustomize.pyorusercustomize.pyin site-packages, dist-packages or user paths. - A python process starting without user interaction after such a write, or showing changed behavior such as malicious imports.
- Outbound network connections from Python, and unusual child processes.
Link the write to an execve of the python process, and to anything odd that follows.
How to reduce the risk
MITRE lists no mitigations for this sub-technique. Sensible steps follow from the mechanism:
- Restrict write access to site-packages and dist-packages.
- Install dependencies from trusted sources only, pin versions and review new packages.
- Monitor the hook file names above with file integrity tools.
- Rebuild environments from locked inputs instead of patching in place.
To see what a project depends on, the free Safeguard Gold scan checks a dependency manifest in your browser, with no login, the file staying on your machine, up to 100 dependencies.
Check your own environment
Read-only commands on Linux or macOS:
python3 -c "import site; print(site.getsitepackages()); print(site.getusersitepackages())"
find /usr/lib/python3* /usr/local/lib/python3* ~/.local/lib -name '*.pth' 2>/dev/null
find / -name sitecustomize.py -o -name usercustomize.py 2>/dev/null
Some .pth files are legitimate, for example those installed by well known tooling. For each one, open it and check that any import line does what the owning package says it should.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Which lines in a .pth file execute code?
Lines that begin with import. Other lines only add paths to the module search path.
Name the two customize modules.
sitecustomize.py and usercustomize.py, imported automatically at interpreter startup when present on the Python path.