Skip to content

fix: restore compatibility with modern Windows Update clients#18

Open
5tuk0v wants to merge 1 commit intoGoSecure:masterfrom
5tuk0v:master
Open

fix: restore compatibility with modern Windows Update clients#18
5tuk0v wants to merge 1 commit intoGoSecure:masterfrom
5tuk0v:master

Conversation

@5tuk0v
Copy link

@5tuk0v 5tuk0v commented Feb 23, 2026

Hey there, a fellow hacker got me curious about #17 and I took a look at it in the lab for fun. The tool seems to be working consistently on various OS versions after applying these fixes (written by our friend Claude):

  • Remove hardcoded Prerequisites category UUID (0fa1201d) from sync-updates.xml — modern WU clients no longer satisfy this category, causing updates to be silently marked non-applicable
  • Populate <Properties> in get-config.xml with required protocol negotiation fields (ProtocolVersion, MaxExtendedUpdatesPerRequest, IsInventoryRequired, ClientReportingLevel) — absence causes 0x8024402a on current WU client versions
  • Catch ConnectionResetError/BrokenPipeError on EXE send in do_GET — suppresses noisy traceback from BITS range-request probe
  • Bump lxml to >=4.9.2 to fix build failure on Python 3.11+

Tested successfully on: Windows 10 22H2, Windows 11 24H2, Windows Server 2019, Windows Server 2022

Payload used during testing: python3 ./pywsus.py -H IP_ADDR -p 8530 -e PsExec64.exe -c '/accepteula /s cmd.exe /c "whoami > C:\pwned.txt"'

- Remove hardcoded Prerequisites category UUID (0fa1201d) from
  sync-updates.xml — modern WU clients no longer satisfy this category,
  causing updates to be silently marked non-applicable
- Populate <Properties> in get-config.xml with required protocol
  negotiation fields (ProtocolVersion, MaxExtendedUpdatesPerRequest,
  IsInventoryRequired, ClientReportingLevel) — absence causes 0x8024402a
  on current WU client versions
- Catch ConnectionResetError/BrokenPipeError on EXE send in do_GET —
  suppresses noisy traceback from BITS range-request probe
- Bump lxml to >=4.9.2 to fix build failure on Python 3.11+

Tested on: Windows 10 22H2, Windows 11 24H2, Windows Server 2019, Windows Server 2022
@NeffIsBack
Copy link

Hey, do you know when these changes were introduced on the Microsoft/Windows side of things? I encountered some weird situations a few times (one time on a pentest and also via github issues on wsuks) that updates were requested but got stuck at the GetCookie state (GetExtendedUpdateInfo was never requested).

My assumption was that this occurred due to an unclean state of the update fetching mechanism, because when trying to verify the issue, every time I set up a fresh machine, configured WSUS, and synced to the WSUS server, the exploit worked out of the box on both Win10 and Win11 machines. The last time I tried was December last year.

Remove hardcoded Prerequisites category UUID (0fa1201d) from sync-updates.xml — modern WU clients no longer satisfy this category, causing updates to be silently marked non-applicable

Do you have a source for that or a way I could verify that these changes fixes the issue? E.g. where could I see the "marked as non-applicable" labels of the updates?

@5tuk0v
Copy link
Author

5tuk0v commented Mar 18, 2026

Hey, do you know when these changes were introduced on the Microsoft/Windows side of things? I encountered some weird situations a few times (one time on a pentest and also via github issues on wsuks) that updates were requested but got stuck at the GetCookie state (GetExtendedUpdateInfo was never requested).

My assumption was that this occurred due to an unclean state of the update fetching mechanism, because when trying to verify the issue, every time I set up a fresh machine, configured WSUS, and synced to the WSUS server, the exploit worked out of the box on both Win10 and Win11 machines. The last time I tried was December last year.

Remove hardcoded Prerequisites category UUID (0fa1201d) from sync-updates.xml — modern WU clients no longer satisfy this category, causing updates to be silently marked non-applicable

Do you have a source for that or a way I could verify that these changes fixes the issue? E.g. where could I see the "marked as non-applicable" labels of the updates?

Hey there,
The changes in the code are pure Claude slop, not going to deny that. I did not reverse anything or do any deep analysis, in fact it's a shame compared to the original work of the authors here, but I was mainly looking for a quick fix here. I tried to keep a rigorous testing methodology though:

  • Deploy VM with Ludus, configure wsus server on the client to put any mitm out of the picture
  • Start malicious WSUS server and serve payload, always the same
  • Check for updates on the client, look into the client update logs for any errors
  • Go back to tweaking the code on the server until it seemed to work
  • Reversed the changes to retest and confirm the "problem" was back
  • etc ...

So what I know is that I couldn't reliably receive the malicious update on freshly deployed Ludus VMs running the OSes I've listed (fully updated or not didn't seem to matter), and with these changes applied, it worked reliably.

Is there an issue elsewhere that I couldn't identify and the changes in the code are coincidental?? 👀

Still possible, but I did many, many test runs in my lab and it was consistent in my testing environment.

Funnily enough, I also forked your great wsuks to add a --serve-only option to quickly serve updates without needing to mitm, but I experienced similar results which makes sense since the update logic is mostly the same iirc.

I'm happy to jump back into the lab and do some more testing to help figure out what is really happening here, but it does get time consuming quite quickly 😅

@5tuk0v
Copy link
Author

5tuk0v commented Mar 19, 2026

Interestingly, I deployed a new range, pointed a Windows 2022 server and Windows 11 24H2 workstation to a Windows 2022 WSUS server, then ran the full MITM flow from a kali VM with wsuks and both updates worked first try (command used -c '/accepteula /s cmd.exe /c "whoami > C:\pwned.txt"'

In my numerous previous tests, I never bothered with MITM because this was not what I was testing - I just pointed a GPO straight to my attack box where I ran the malicious WSUS server, and ran into similar issues as in #17 which led me here.

I don't see what would be different with or without MITM though? the update client still goes through its usual flow and doesn't know about it(?)

Will do more testing with and without MITM to see if I can reproduce again

@NeffIsBack
Copy link

NeffIsBack commented Mar 19, 2026

The changes in the code are pure Claude slop, not going to deny that. I did not reverse anything or do any deep analysis, in fact it's a shame compared to the original work of the authors here, but I was mainly looking for a quick fix here.

Oh okay, the LinkedIn post sounded like you guys ran into the same/similar situation and verified the fix. Do you know how to reproduce the state in where the client refuses to pull or install the updates? I will definitely try it out the next time I am stuck at the receiving updates step, but refrain from integrating into wsuks until I can verify the fix (or observe a different behavior).

So what I know is that I couldn't reliably receive the malicious update on freshly deployed Ludus VMs running the OSes I've listed (fully updated or not didn't seem to matter), and with these changes applied, it worked reliably.

Is there an issue elsewhere that I couldn't identify and the changes in the code are coincidental?? 👀

Still possible, but I did many, many test runs in my lab and it was consistent in my testing environment.

Okay okay, so you could observe different behavior between the original and your adapted XML files? Very interesting! My biggest problem to be honest is that I can't reproduce the "invalid" state where clients refused to pull the updates (although reported both on the issue and by my colleague). I am happy to jump back into the lab but honestly, each time i set up a Win Client it seemed to work so far.

Funnily enough, I also forked your great wsuks to add a --serve-only option to quickly serve updates without needing to mitm, but I experienced similar results which makes sense since the update logic is mostly the same iirc.

Very nice :D Actually let me implement that as well. I had a feature request before for that because honestly there are a lot of scenarios where you wouldn't need the ARP spoofing and routing setup (responder, DNS poisoning or control over DNS, etc.)


Interestingly, I deployed a new range, pointed a Windows 2022 server and Windows 11 24H2 workstation to a Windows 2022 WSUS server, then ran the full MITM flow from a kali VM with wsuks and both updates worked first try (command used -c '/accepteula /s cmd.exe /c "whoami > C:\pwned.txt"'

Yeah haha exactly that is my issue. I still struggle at observing a or reproducing the "failed" state of the VMs.

In my numerous previous tests, I never bothered with MITM because this was not what I was testing - I just pointed a GPO straight to my attack box where I ran the malicious WSUS server, and ran into similar issues as in #17 which led me here.

I don't see what would be different with or without MITM though? the update client still goes through its usual flow and doesn't know about it(?)

Will do more testing with and without MITM to see if I can reproduce again

Agreed, i don't think MITM has any effect. At least i wouldn't know what that could cause, redirecting the traffic works flawlessly (otherwise we wouldn't see anything in the HTTP server) and besides that, the HTTP server should receive pretty much the same network packages, when hidden behind the routing logic or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants