Skip to content

Commit fac71a2

Browse files
authored
Merge pull request #1919 from HackTricks-wiki/update_Notepad___Plugins__Plug_and_Payload_20260219_184934
Notepad++ Plugins Plug and Payload
2 parents c5e2707 + 5a62621 commit fac71a2

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@
255255
- [Abusing Auto Updaters And Ipc](windows-hardening/windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md)
256256
- [Arbitrary Kernel Rw Token Theft](windows-hardening/windows-local-privilege-escalation/arbitrary-kernel-rw-token-theft.md)
257257
- [Kernel Race Condition Object Manager Slowdown](windows-hardening/windows-local-privilege-escalation/kernel-race-condition-object-manager-slowdown.md)
258+
- [Notepad Plus Plus Plugin Autoload Persistence](windows-hardening/windows-local-privilege-escalation/notepad-plus-plus-plugin-autoload-persistence.md)
258259
- [Abusing Tokens](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens.md)
259260
- [Access Tokens](windows-hardening/windows-local-privilege-escalation/access-tokens.md)
260261
- [ACLs - DACLs/SACLs/ACEs](windows-hardening/windows-local-privilege-escalation/acls-dacls-sacls-aces.md)

src/windows-hardening/windows-local-privilege-escalation/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,14 @@ Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Ac
749749
Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match 'BUILTIN\Users'} } catch {}}
750750
```
751751
752+
### Notepad++ plugin autoload persistence/execution
753+
754+
Notepad++ autoloads any plugin DLL under its `plugins` subfolders. If a writable portable/copy install is present, dropping a malicious plugin gives automatic code execution inside `notepad++.exe` on every launch (including from `DllMain` and plugin callbacks).
755+
756+
{{#ref}}
757+
notepad-plus-plus-plugin-autoload-persistence.md
758+
{{#endref}}
759+
752760
### Run at startup
753761
754762
**Check if you can overwrite some registry or binary that is going to be executed by a different user.**\
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Notepad++ Plugin Autoload Persistence & Execution
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
Notepad++ will **autoload every plugin DLL found under its `plugins` subfolders** on launch. Dropping a malicious plugin into any **writable Notepad++ installation** gives code execution inside `notepad++.exe` every time the editor starts, which can be abused for **persistence**, stealthy **initial execution**, or as an **in-process loader** if the editor is launched elevated.
6+
7+
## Writable plugin locations
8+
- Standard install: `C:\Program Files\Notepad++\plugins\<PluginName>\<PluginName>.dll` (usually requires admin to write).
9+
- Writable options for low-privileged operators:
10+
- Use the **portable Notepad++ build** in a user-writable folder.
11+
- Copy `C:\Program Files\Notepad++` to a user-controlled path (e.g., `%LOCALAPPDATA%\npp\`) and run `notepad++.exe` from there.
12+
- Each plugin gets its own subfolder under `plugins` and is loaded automatically at startup; menu entries appear under **Plugins**.
13+
14+
## Plugin load points (execution primitives)
15+
Notepad++ expects specific **exported functions**. These are all called during initialization, giving multiple execution surfaces:
16+
- **`DllMain`** — runs immediately on DLL load (first execution point).
17+
- **`setInfo(NppData)`** — called once on load to provide Notepad++ handles; typical place to register menu items.
18+
- **`getName()`** — returns the plugin name shown in the menu.
19+
- **`getFuncsArray(int *nbF)`** — returns menu commands; even if empty, it is called during startup.
20+
- **`beNotified(SCNotification*)`** — receives editor events (file open/change, UI events) for ongoing triggers.
21+
- **`messageProc(UINT, WPARAM, LPARAM)`** — message handler, useful for larger data exchanges.
22+
- **`isUnicode()`** — compatibility flag checked at load.
23+
24+
Most exports can be implemented as **stubs**; execution can occur from `DllMain` or any callback above during autoload.
25+
26+
## Minimal malicious plugin skeleton
27+
Compile a DLL with the expected exports and place it in `plugins\\MyNewPlugin\\MyNewPlugin.dll` under a writable Notepad++ folder:
28+
29+
```c
30+
BOOL APIENTRY DllMain(HMODULE h, DWORD r, LPVOID) { if (r == DLL_PROCESS_ATTACH) MessageBox(NULL, TEXT("Hello from Notepad++"), TEXT("MyNewPlugin"), MB_OK); return TRUE; }
31+
extern "C" __declspec(dllexport) void setInfo(NppData) {}
32+
extern "C" __declspec(dllexport) const TCHAR *getName() { return TEXT("MyNewPlugin"); }
33+
extern "C" __declspec(dllexport) FuncItem *getFuncsArray(int *nbF) { *nbF = 0; return NULL; }
34+
extern "C" __declspec(dllexport) void beNotified(SCNotification *) {}
35+
extern "C" __declspec(dllexport) LRESULT messageProc(UINT, WPARAM, LPARAM) { return TRUE; }
36+
extern "C" __declspec(dllexport) BOOL isUnicode() { return TRUE; }
37+
```
38+
39+
1. Build the DLL (Visual Studio/MinGW).
40+
2. Create the plugin subfolder under `plugins` and drop the DLL inside.
41+
3. Restart Notepad++; the DLL is loaded automatically, executing `DllMain` and subsequent callbacks.
42+
43+
## Reflective loader plugin pattern
44+
A weaponized plugin can turn Notepad++ into a **reflective DLL loader**:
45+
- Present a minimal UI/menu entry (e.g., "LoadDLL").
46+
- Accept a **file path** or **URL** to fetch a payload DLL.
47+
- Reflectively map the DLL into the current process and invoke an exported entry point (e.g., a loader function inside the fetched DLL).
48+
- Benefit: reuse a benign-looking GUI process instead of spawning a new loader; payload inherits the integrity of `notepad++.exe` (including elevated contexts).
49+
- Trade-offs: dropping an **unsigned plugin DLL** to disk is noisy; consider piggybacking on existing trusted plugins if present.
50+
51+
## Detection and hardening notes
52+
- Block or monitor **writes to Notepad++ plugin directories** (including portable copies in user profiles); enable controlled folder access or application allowlisting.
53+
- Alert on **new unsigned DLLs** under `plugins` and unusual **child processes/network activity** from `notepad++.exe`.
54+
- Enforce plugin installation via **Plugins Admin** only, and restrict execution of portable copies from untrusted paths.
55+
56+
## References
57+
- [Notepad++ Plugins: Plug and Payload](https://trustedsec.com/blog/notepad-plugins-plug-and-payload)
58+
- [MyNewPlugin PoC snippet](https://gitlab.com/-/snippets/4930986)
59+
- [LoadDLL reflective loader plugin](https://gitlab.com/KevinJClark/ops-scripts/-/tree/main/notepad_plus_plus_plugin_LoadDLL)
60+
61+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)