Telephony tapsrv Arbitrary DWORD Write to RCE (TAPI Server Mode)
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
When the Windows Telephony service (TapiSrv, tapisrv.dll) is configured as a TAPI server, it exposes the tapsrv MSRPC interface over the \pipe\tapsrv named pipe to authenticated SMB clients. A design bug in the asynchronous event delivery for remote clients lets an attacker turn a mailslot handle into a controlled 4-byte write to any pre-existing file writable by NETWORK SERVICE. That primitive can be chained to overwrite the Telephony admin list and abuse an admin-only arbitrary DLL load to execute code as NETWORK SERVICE.
Attack Surface
- Remote exposure only when enabled:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Telephony\Server\DisableSharingmust allow sharing (or configured viaTapiMgmt.msc/tcmsetup /c <server>). By defaulttapsrvis local-only. - Interface: MS-TRP (
tapsrv) over SMB named pipe, so the attacker needs valid SMB auth. - Service account:
NETWORK SERVICE(manual start, on-demand).
Primitive: Mailslot Path Confusion → Arbitrary DWORD Write
ClientAttach(pszDomainUser, pszMachine, ...)initializes async event delivery. In pull mode, the service does:
CreateFileW(pszDomainUser, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
without validating that pszDomainUser is a mailslot path (\\*\MAILSLOT\...). Any existing filesystem path writable by NETWORK SERVICE is accepted.
- Every async event write stores a single
DWORD=InitContext(attacker-controlled in the subsequentInitializerequest) to the opened handle, yielding write-what/write-where (4 bytes).
Wymuszanie deterministycznych zapisów
- Otwórz plik docelowy:
ClientAttachwithpszDomainUser = <existing writable path>(e.g.,C:\Windows\TAPI\tsec.ini). - For each
DWORDto write, execute this RPC sequence againstClientRequest:
Initialize(Req_Func 47): ustawInitContext = <4-byte value>orazpszModuleName = DIALER.EXE(lub inny wpis najwyższego priorytetu w per-user priority list).LRegisterRequestRecipient(Req_Func 61):dwRequestMode = LINEREQUESTMODE_MAKECALL,bEnable = 1(rejestruje aplikację linii, przelicza odbiorcę o najwyższym priorytecie).TRequestMakeCall(Req_Func 121): wymuszaNotifyHighestPriorityRequestRecipient, generując zdarzenie asynchroniczne.GetAsyncEvents(Req_Func 0): zdejmuje z kolejki/kończy zapis.LRegisterRequestRecipientponownie zbEnable = 0(wyrejestrowuje).Shutdown(Req_Func 86) aby zakończyć aplikację linii.- Kontrola priorytetu: „odbiorca o najwyższym priorytecie” jest wybierany przez porównanie
pszModuleNamezHKCU\Software\Microsoft\Windows\CurrentVersion\Telephony\HandoffPriorities\RequestMakeCall(odczytywane podczas impersonacji klienta). W razie potrzeby wstaw swoją nazwę modułu za pomocąLSetAppPriority(Req_Func 69). - Plik musi już istnieć, ponieważ używane jest
OPEN_EXISTING. Typowe kandydaty zapisywalne przezNETWORK SERVICE:C:\Windows\System32\catroot2\dberr.txt,C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp\MpCmdRun.log,...\MpSigStub.log.
From DWORD Write to RCE inside TapiSrv
- Grant yourself Telephony “admin”: target
C:\Windows\TAPI\tsec.iniand append[TapiAdministrators]\r\n<DOMAIN\\user>=1using the 4-byte writes above. Start a new session (ClientAttach) so the service re-reads the INI and setsptClient->dwFlags |= 9for your account. - Admin-only DLL load: send
GetUIDllNamewithdwObjectType = TUISPIDLL_OBJECT_PROVIDERIDand supply a path viadwProviderFilenameOffset. For admins, the service doesLoadLibrary(path)then calls the exportTSPI_providerUIIdentify:
- Works with UNC paths to a real Windows SMB share; some attacker SMB servers fail with
ERROR_SMB_GUEST_LOGON_BLOCKED. - Alternative: slowly drop a local DLL using the same 4-byte write primitive, then load it.
- Payload: the export executes under
NETWORK SERVICE. A minimal DLL can runcmd.exe /c whoami /all > C:\Windows\Temp\poc.txtand return a non-zero value (e.g.,0x1337) so the service unloads the DLL, confirming execution.
Zalecenia dotyczące zabezpieczeń i wykrywania
- Wyłącz TAPI server mode, jeśli nie jest wymagany; zablokuj zdalny dostęp do
\pipe\tapsrv. - Wymuszaj walidację przestrzeni nazw mailslot (
\\*\MAILSLOT\) przed otwarciem ścieżek dostarczonych przez klienta. - Zablokuj ACL dla
C:\Windows\TAPI\tsec.inii monitoruj zmiany; generuj alerty przy wywołaniachGetUIDllNameładujących nietypowe ścieżki.
References
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


