# CVE-2024-26230 — Windows Telephony Service `tapisrv.dll` Use-After-Free

---

## Summary

| **Product** | Microsoft Windows — `tapisrv.dll` (Windows Telephony Service) |
|---|---|
| **Vendor** | Microsoft Corporation |
| **Severity** | CVSS v3.1 **7.8 (High)** |
| **CVE Title** | Windows Telephony Service Elevation of Privilege Vulnerability |
| **CWE** | CWE-416 (Use After Free) |
| **Affected Versions** | Windows 10/11 and Server with Telephony Service enabled |
| **Impact** | Local EoP — low-privilege user triggers UAF on a GOLD dialog object → SYSTEM |
| **Exploited ITW** | No |
| **Patch Date** | April 2024 Patch Tuesday — KB5036892 |
| **Public analysis** | [78 Research Lab — UAF in Windows Telephony Service](https://blog.78researchlab.com/306db461-3e5b-807b-ad56-f461c5fb596c) |

---

## Root Cause

Windows Telephony Service exposes an RPC interface (`ncalrpc:[tapsrvlpc]`) that
manages telephone-line devices and dialog objects. A **GOLD (Global Object for
Line Device)** dialog object is created by `GetUIDllName` when a TAPI application
requests UI DLL information for a line device.

The lifecycle bug:

1. **`GetUIDllName`** creates a GOLD dialog object and stores its pointer in a
cross-context reference list (shared between the TAPI service context and the
UI DLL context).

2. **`FreeDialogInstance`** frees the GOLD object when the dialog instance is
destroyed, but **does not invalidate the pointer stored in the cross-context
reference list**.

3. **`TUISPIDLLCallback`** later traverses the reference list and calls a virtual
function on the stale GOLD pointer — **use-after-free on a heap allocation
containing a vtable**, leading to controlled code execution.

### The patch (verified in ghidriff diff, 3296 → 3447)

The diff confirms two key functions changed:

- **`TUISPIDLLCallback`** (95% match) — added `WaitForExclusiveClientAccess` and
  `LeaveCriticalSection` calls around the GOLD pointer dereference path. The
  callback now acquires exclusive access before traversing the reference list
  and calling the virtual function, preventing the race where `FreeDialogInstance`
  frees the object while `TUISPIDLLCallback` is still using it.

- **`FreeDialogInstance`** (82% match) — synchronized with the same locking
  primitive so the free and the callback cannot interleave.

Diff: `ghidriff/CVE-2024-26230/output/tapisrv-10.0.22621.3296.dll-tapisrv-10.0.22621.3447.dll.ghidriff.md`

---

## Reaching the bug — userspace call flow

Fully client-reachable from any low-privilege process that can open the TAPI
service RPC endpoint:

```
user process
    │
    ▼
RpcStringBindingCompose("ncalrpc:[tapsrvlpc]", ...)
RpcBindingFromStringBinding(...)
    │
    ▼
tapi32!lineGetUIDllName  ──►  tapsrv!GetUIDllName
    │                              GOLD object created + ptr stored in ref list
    ▼
tapi32!lineDrop  /  lineClose  ──►  tapsrv!FreeDialogInstance
    │                              GOLD object freed, but ref-list ptr stale
    ▼
tapi32!lineConfigDialogEdit  ──►  tapsrv!TUISPIDLLCallback
    │                              virtual call on freed GOLD → UAF
    ▼
    controlled EIP via vtable hijack
```

| Element | Value |
|---|---|
| RPC endpoint | `ncalrpc:[tapsrvlpc]` (local RPC, no network required) |
| Vulnerable functions | `tapisrv!GetUIDllName`, `tapisrv!FreeDialogInstance`, `tapisrv!TUISPIDLLCallback` |
| Object type | GOLD (Global Object for Line Device) dialog — heap-allocated with vtable |
| Privileges | none (standard local user) |
| Preconditions | Telephony Service (`TapiSrv`) must be running (default on Windows client) |

---

## Detection engineering

- **RPC telemetry**: ETW `Microsoft-Windows-RPC` events showing calls to the
  TAPI service interface (`{2F5F6521-CA47-1068-B319-00DD010662DB}`) from
  unexpected processes (non-telephony apps).
- **Behavioral tell**: Rapid sequence of `lineGetUIDllName` → `lineClose` →
  `lineConfigDialogEdit` from the same process is abnormal — legitimate TAPI
  apps rarely exercise this path.
- **Crash forensics**: Heap corruption or access-violation in `tapisrv!TUISPIDLLCallback`
  with a stale pointer in `rcx`/`this`; verifier may catch the UAF with
  `HEAP_CORRUPTION` or `HEAP_FREE_BLOCK_INVALID`.

## References

- [MSRC — CVE-2024-26230](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-26230)
- [78 Research Lab — UAF in Windows Telephony Service](https://blog.78researchlab.com/306db461-3e5b-807b-ad56-f461c5fb596c)
