Telephony tapsrv Arbitrary DWORD Write to RCE (TAPI Server Mode)
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
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).
Forcing Deterministic Writes
- Open target file:
ClientAttachwithpszDomainUser = <existing writable path>(e.g.,C:\Windows\TAPI\tsec.ini). - For each
DWORDto write, execute this RPC sequence againstClientRequest:
Initialize(Req_Func 47): setInitContext = <4-byte value>andpszModuleName = DIALER.EXE(or another top entry in the per-user priority list).LRegisterRequestRecipient(Req_Func 61):dwRequestMode = LINEREQUESTMODE_MAKECALL,bEnable = 1(registers the line app, recalculates highest priority recipient).TRequestMakeCall(Req_Func 121): forcesNotifyHighestPriorityRequestRecipient, generating the async event.GetAsyncEvents(Req_Func 0): dequeue/completes the write.LRegisterRequestRecipientagain withbEnable = 0(unregister).Shutdown(Req_Func 86) to tear down the line app.- Priority control: the “highest priority” recipient is chosen by comparing
pszModuleNameagainstHKCU\Software\Microsoft\Windows\CurrentVersion\Telephony\HandoffPriorities\RequestMakeCall(read while impersonating the client). If needed, insert your module name viaLSetAppPriority(Req_Func 69). - The file must already exist because
OPEN_EXISTINGis used. CommonNETWORK SERVICE-writable candidates: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.
Hardening / Detection Notes
- Disable TAPI server mode unless required; block remote access to
\pipe\tapsrv. - Enforce mailslot namespace validation (
\\*\MAILSLOT\) before opening client-supplied paths. - Lock down
C:\Windows\TAPI\tsec.iniACLs and monitor changes; alert onGetUIDllNamecalls loading non-default paths.
References
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


