# CVE-2020-0638 — Windows Update Medic Service `waasmedicsvc.dll` Plugin-Library Trust Bypass → Local EoP to SYSTEM

---

## Summary

| | |
|---|---|
| **Product** | Windows — `waasmedicsvc.dll` (Windows Update Medic Service / "Update Notification Manager") |
| **CVE ID** | CVE-2020-0638 |
| **Impact** | Elevation of Privilege (local — to SYSTEM) |
| **MSRC severity** | Important |
| **CVSS** | 7.8 / 7.0 — `CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/E:P/RL:O/RC:C` |
| **CWE** | CWE-59: Improper Link Resolution Before File Access ("Link Following") — via improper library-identity validation |
| **Delivery** | Local — attacker already has code execution on the host and abuses the SYSTEM service's plugin load |
| **KB / Fixed build** | KB4528760 — `waasmedicsvc.dll` 10.0.18362.628 (Win10 1903/1909 x64) |
| **Patch Date** | January 14, 2020 (2020-Jan) |
| **Pre-patch binary** | `waasmedicsvc.dll` 10.0.18362.535 (KB4530684, Dec 2019) — SHA256 `1f1c9f46caf56e938758af6a13a39150ceb8ef9b0c8c06c4327107bf84a304f9` |
| **Post-patch binary** | `waasmedicsvc.dll` 10.0.18362.628 (KB4528760, Jan 2020) — SHA256 `4236c7c7d9827deb21b2d96073805f6b17924c1feb46a34a640f0dc6bb1b23ea` |
| **Feature flag** | none — pre-velocity 2020 build (the fix is not CFR-gated) |
| **Exploitability** | MSRC: Exploitation "Proof-of-Concept" (E:P), not publicly disclosed, MSRC "not exploited". **Listed in CISA KEV (added 2022-05-23).** |

> Provenance note: the POST build `10.0.18362.628` (SHA `4236c7c7…`) is winbindex-confirmed as the
> January-2020 fix (KB4528760, which supersedes the December-2019 KB4530684 = build `.535`). The PRE
> binary is confirmed **pre-fix by content** — it does not contain `ValidateOriginalFileName` — although
> ghidriff read its embedded PE version string as `10.0.18362.1034` rather than the expected `.535`
> (a symbol-server version-label ambiguity of the kind seen before). Both SHA-256 values are recorded
> above so the exact inputs can be verified.

---

## Product Description

`waasmedicsvc.dll` implements the **Windows Update Medic Service** (`WaaSMedicSvc`), which runs as
**SYSTEM** and repairs the Windows Update stack. To do this it loads **remediation plugin libraries**
(`CWaasRemediation::LoadPluginLibrary`) after checking that each candidate library is "trusted"
(`IsTrustedLibrary`). Because the service is SYSTEM, anything it can be persuaded to load runs as SYSTEM.

---

## Vulnerability Summary

Pre-patch, `IsTrustedLibrary` validated a candidate plugin **only by its Authenticode signature**
(`WTGetSignatureInfo`), and `LoadPluginLibrary` then loaded it with `LoadLibraryW(path)`. There was no
check that the file's **identity** matched the module the service intended to load. A local attacker who
can **redirect or substitute** the resolved plugin file — the classic link-following / file-substitution
primitive Microsoft classes as **CWE-59** — could make the SYSTEM service load a different library that
still satisfied the weak signature-only check, gaining code execution as SYSTEM. Microsoft rates it
**Important, 7.8**; CISA later added it to the Known Exploited Vulnerabilities catalog.

---

## Prerequisites and Constraints

- Local, low-privileged code execution on the host (`AV:L`, `AC:L`, `PR:L`, `UI:N`).
- The attacker can influence the file the Medic service resolves as its plugin (path
  redirection / substitution — link following).
- The substituted library must satisfy the *pre-patch* trust check (signature), which does not bind the
  loaded file's identity.

---

## Vulnerability Details

### Root Cause

The trust decision for a SYSTEM-loaded plugin relied on the file's signature alone and did not verify
that the loaded file was actually the intended module. Combined with the ordinary `LoadLibraryW` load,
a redirected/substituted-but-acceptable library was loaded into a SYSTEM process.

### The patch (confirmed — diff, .535 → .628)

The January 2020 build adds a **library-identity binding** and a **signed-target load flag**:

```c
// WaasMedic::IsTrustedLibrary (10.0.18362.628) — PATCHED (from the diff)
DVar1 = ValidateOriginalFileName(param_1, local_res8);   // *** NEW: identity check first ***
// ... Authenticode check retained:
DVar1 = WTGetSignatureInfo(param_1, hObject, 0x1803, &local_78, 0, 0);

// WaasMedic::ValidateOriginalFileName (NEW) — from the diff
VerQueryValueW(lpData, L"\\VarFileInfo\\Translation", &local_2e8, local_2f0);
swprintf_s(local_248, 0xfe, L"\\StringFileInfo\\%04x%04x\\OriginalFilename", /*lang, codepage*/);
VerQueryValueW(lpData, local_248, &local_2e0, local_2f0);
iVar6 = _wcsicmp(/* embedded OriginalFilename */, /* expected name */);
*local_2d8 = iVar6 == 0;                                 // trusted only if the name matches

// WaasMedic::CWaasRemediation::LoadPluginLibrary (.628) — PATCHED
if ((iVar3 < 0) || ((local_248 & 0x200000000) == 0))
    pHVar4 = LoadLibraryExW(local_238, (HANDLE)0x0, 0x80);  // 0x80 = LOAD_LIBRARY_REQUIRE_SIGNED_TARGET
else
    pHVar4 = LoadLibraryW(local_238);
```

`ValidateOriginalFileName` reads the candidate's **version-resource `OriginalFilename`** (via
`VerQueryValueW` on `\StringFileInfo\<lang><codepage>\OriginalFilename`, with the language/codepage taken
from `\VarFileInfo\Translation`) and requires a case-insensitive match against the expected module name.
A substituted or redirected library whose embedded `OriginalFilename` does not match is rejected before
it is trusted. The load itself is additionally hardened with `LOAD_LIBRARY_REQUIRE_SIGNED_TARGET`
(`0x80`). Together these close the substitution: the loaded file must now be both correctly named and
signed.

### Patch Completeness Assessment

**Not CFR-gated** (this is a 2020, pre-velocity build). The identity check and the signed-target load
flag ship unconditionally in `.628`. The fix binds the loaded library's *name identity* in addition to
its signature; it does not, by itself, remove the attacker's ability to *attempt* redirection — it
ensures a redirected target fails the trust check.

---

## Detection Guidance

**Behavioural.** Unexpected module loads by `svchost`/`WaaSMedicSvc` hosting `waasmedicsvc.dll`,
especially of DLLs from user-writable locations; failures/rejections in the plugin trust path on patched
builds; junctions/symlinks or file substitutions targeting paths the Medic service resolves.

**Config.** Ensure the January 2020 (or later) cumulative update is installed — for 1903/1909, build
`10.0.18362.628` (KB4528760) or newer. This CVE is in **CISA KEV**, so remediation is mandated for US
federal systems.

---

## References

- MSRC advisory — CVE-2020-0638 (Update Notification Manager Elevation of Privilege), released 2020-01-14, KB4528760 (and per-SKU KBs KB4534273 / KB4534293 / KB4534276).
- CISA KEV — "Microsoft Update Notification Manager Privilege Escalation Vulnerability", added 2022-05-23.
- Full binary diff: `/data/patch_diffs/waasmedicsvc_dll-cve-2020-0638-ghidriff.md`
