GoSecure / pywsus

Standalone implementation of a part of the WSUS spec. Built for offensive security purposes.
https://gosecure.net/blog/
MIT License
286 stars 44 forks source link

PoC Failure on Win10 - Not domain joined #10

Open fneur opened 3 years ago

fneur commented 3 years ago

Trying to replicate the PoC in a simple setting involving two Win10 boxes with a direct network connection (i.e., no MITM involved), the process gets stuck after the SyncUpdates phase.

Whenever 'check for updates' is performed on the client, pywsus receives a SyncUpdates SOAP HTTP request. However, unlike the PoC, a GetExtendedUpdateInfo request is never received by pywsus.

Setup

Client (Win10, 10.0.0.14 ) <----------> pywsus (Win10, 10.0.0.4, local firewall disabled)

Client

Betriebssystemname: Microsoft Windows 10 Pro Betriebssystemversion: 10.0.19043 Nicht zutreffend Build 19043 Betriebssystemhersteller: Microsoft Corporation Betriebssystemkonfiguration: Eigenständige Arbeitsstation Typ des Betriebssystembuilds: Multiprocessor Free Systemtyp: x64-based PC Prozessor(en): 1 Prozessor(en) installiert. 01: Intel64 Family 6 Model 23 Stepping 10 GenuineIntel ~3003 MHz Domain: WORKGROUP Hotfix(es): 11 Hotfix(e) installiert.

                                           [02]: KB4577266
                                           [03]: KB4577586
                                           [04]: KB4580325
                                           [05]: KB4586864
                                           [06]: KB4589212
                                           [07]: KB4593175
                                           [08]: KB4598481
                                           [09]: KB5000736
                                           [10]: KB5004237
                                           [11]: KB5003742

PYWSUS

Betriebssystemname: Microsoft Windows 10 Pro Betriebssystemversion: 10.0.19042 Nicht zutreffend Build 19042 Betriebssystemhersteller: Microsoft Corporation Betriebssystemkonfiguration: Eigenständige Arbeitsstation Typ des Betriebssystembuilds: Multiprocessor Free Systemtyp: x64-based PC Prozessor(en): 1 Prozessor(en) installiert. 01: Intel64 Family 6 Model 142 Stepping 12 GenuineIntel ~1803 MHz Domain: WORKGROUP Hotfix(es): 11 Hotfix(e) installiert.

                                           [02]: KB4562830
                                           [03]: KB4577266
                                           [04]: KB4577586
                                           [05]: KB4580325
                                           [06]: KB4586864
                                           [07]: KB4589212
                                           [08]: KB4593175
                                           [09]: KB4598481
                                           [10]: KB5004237
                                           [11]: KB5003742

Windows Update Client + WSUS Configuration

Client configuration via GPO

pywsus is run with simplified command line: python pywsus.py -v -H 10.0.0.4 -p 8530 -e PsExec64.exe -c "/accepteula"

Results + Output of tools

Whenever 'check for updates' is performed on the client, pywsus receives a SyncUpdates SOAP HTTP request and responds. However, a GetExtendedUpdateInfo request is never received by pywsus. After some time the client initiates a ReportEventBatch action, which is subsequently answered by pywsus.

nitbx commented 3 years ago

Hi @fneur and thank you for the detailed issue.

I would have time to redo the attack with your configuration in next weeks.

Probable issue that I could think on top of my head:

Thank you

fneur commented 3 years ago

@nitbx many thanks in advance for your support! I think I will try out different configurations meanwhile. Cheers, F.

nitbx commented 3 years ago

Hi @fneur

I just updated everything and it seem to work with a basic MiTM attack:

image image image

For the next step, I will try to do as you did.

simple setting involving two Win10 boxes with a direct network connection (i.e., no MITM involved)

Thank you.

fneur commented 3 years ago

HI @nitbx

thanks for the update. Recently, I also did some further testing, where I replaced the (pywsus) server machine (which was running Win10 in my original setup) with a (virtual) Linux machine. The client stayed the same and, unfortunately, the results stayed the same.

Whenever 'check for updates' is performed on the client, pywsus receives a SyncUpdates SOAP HTTP request. However, unlike the PoC, a GetExtendedUpdateInfo request is never received by pywsus.

Cheers, F.

fneur commented 3 years ago

Some more testing tonight with 2 AWS VMs (again with a direct network connection, same subnet):

nitbx commented 3 years ago

Hi @fneur,

Just did a test and it work on my side.

From the DC, I changed the GPO to put my kali as the WSUS server: image

After that I changed the network for the Kali and the Window10 workstation for host-only 192.168.78.0/24.

Kali: 192.168.78.133 image

Windows10 worksation: 192.168.78.130 image

Can you give us a Wireshark trace? I'm not sure why you have this behaviour.

Thank you !

fneur commented 3 years ago

Here's a Wireshark capture file (wrt my original setup):

capture_pywsus.zip

Many thanks in advance for taking the time!

nitbx commented 3 years ago

Well, I see no difference except ID, time and uid...

Here is the SyncUpdates SOAP call.

Yours:

POST /ClientWebService/client.asmx HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Accept-Encoding: xpress
User-Agent: Windows-Update-Agent/10.0.10011.16384 Client-Protocol/2.32
SOAPAction: "http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdates"
MS-CV: xs2YnzOO2ESTjlEL.0.1.0.0.2.2
Content-Length: 1495
Host: 10.0.0.4:8530

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SyncUpdates xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><cookie><Expiration>2021-08-15T09:09:57.539151Z</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></cookie><parameters><ExpressQuery>false</ExpressQuery><OtherCachedUpdateIDs><int>906959</int><int>907721</int><int>912032</int><int>912707</int><int>912798</int><int>913143</int><int>913431</int><int>913790</int><int>918003</int><int>918525</int><int>922259</int><int>926799</int><int>929423</int><int>929958</int><int>934826</int><int>942380</int><int>942745</int><int>943603</int><int>946052</int><int>947235</int><int>949830</int><int>949995</int><int>952866</int><int>954408</int><int>958306</int><int>958350</int><int>959017</int><int>960800</int><int>960842</int><int>962375</int><int>962417</int><int>962955</int><int>964220</int><int>967380</int><int>967686</int><int>968789</int><int>974644</int><int>974844</int><int>975850</int><int>977795</int><int>985358</int><int>985936</int><int>987159</int><int>988853</int><int>988967</int><int>993345</int><int>994150</int><int>996723</int><int>999125</int><int>999488</int></OtherCachedUpdateIDs><SkipSoftwareSync>false</SkipSoftwareSync><NeedTwoGroupOutOfScopeUpdates>false</NeedTwoGroupOutOfScopeUpdates><AlsoPerformRegularSync>true</AlsoPerformRegularSync><ComputerSpec/></parameters></SyncUpdates></s:Body></s:Envelope>HTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.9.5
Date: Sat, 14 Aug 2021 07:11:31 GMT
Cache-Control: private
Content-type: text/xml; chartset=utf-8
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w4.org/2001/XMLSchema-instance"><SyncUpdatesResponse xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><SyncUpdatesResult><NewUpdates><UpdateInfo><ID>948473</ID><Deployment><ID>83531</ID><Action>Install</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="5da52daa-4291-4d33-a793-126431242932" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" ExplicitlyDeployable="true" AutoSelectOnWebSites="true" /&gt;&lt;Relationships&gt;&lt;Prerequisites&gt;&lt;AtLeastOne IsCategory="true"&gt;&lt;UpdateIdentity UpdateID="0fa1201d-4330-4fa8-8ae9-b877473b6441" /&gt;&lt;/AtLeastOne&gt;&lt;/Prerequisites&gt;&lt;BundledUpdates&gt;&lt;UpdateIdentity UpdateID="ab3f2196-408f-4fd7-832f-5f6f3306f925" RevisionNumber="204" /&gt;&lt;/BundledUpdates&gt;&lt;/Relationships&gt;</Xml></UpdateInfo><UpdateInfo><ID>913837</ID><Deployment><ID>91622</ID><Action>Bundle</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="ab3f2196-408f-4fd7-832f-5f6f3306f925" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" /&gt;&lt;Relationships&gt;&lt;/Relationships&gt;&lt;ApplicabilityRules&gt;&lt;IsInstalled&gt;&lt;False /&gt;&lt;/IsInstalled&gt;&lt;IsInstallable&gt;&lt;True /&gt;&lt;/IsInstallable&gt;&lt;/ApplicabilityRules&gt;</Xml></UpdateInfo></NewUpdates><Truncated>false</Truncated><NewCookie><Expiration>2021-08-15T09:09:57.550178</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></NewCookie><DriverSyncNotNeeded>true</DriverSyncNotNeeded></SyncUpdatesResult></SyncUpdatesResponse></s:Body></s:Envelope>

Mine:

POST /ClientWebService/client.asmx HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Accept-Encoding: xpress
User-Agent: Windows-Update-Agent/10.0.10011.16384 Client-Protocol/2.32
SOAPAction: "http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdates"
MS-CV: VLerXppsd0igftUH.0.1.0.0.2.2
Content-Length: 21993
Host: 192.168.78.133:8530

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SyncUpdates xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><cookie><Expiration>2021-08-14T18:30:49.816834Z</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></cookie><parameters><ExpressQuery>false</ExpressQuery><InstalledNonLeafUpdateIDs><int>16</int><int>28</int><int>43</int><int>73[...]</OtherCachedUpdateIDs><SkipSoftwareSync>false</SkipSoftwareSync><NeedTwoGroupOutOfScopeUpdates>false</NeedTwoGroupOutOfScopeUpdates><AlsoPerformRegularSync>true</AlsoPerformRegularSync><ComputerSpec/></parameters></SyncUpdates></s:Body></s:Envelope>HTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.9.1+
Date: Fri, 13 Aug 2021 22:31:09 GMT
Cache-Control: private
Content-type: text/xml; chartset=utf-8
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w4.org/2001/XMLSchema-instance"><SyncUpdatesResponse xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><SyncUpdatesResult><NewUpdates><UpdateInfo><ID>964121</ID><Deployment><ID>99691</ID><Action>Install</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="104fafec-ec5d-499a-9efe-fb01b88d4bfc" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" ExplicitlyDeployable="true" AutoSelectOnWebSites="true" /&gt;&lt;Relationships&gt;&lt;Prerequisites&gt;&lt;AtLeastOne IsCategory="true"&gt;&lt;UpdateIdentity UpdateID="0fa1201d-4330-4fa8-8ae9-b877473b6441" /&gt;&lt;/AtLeastOne&gt;&lt;/Prerequisites&gt;&lt;BundledUpdates&gt;&lt;UpdateIdentity UpdateID="1a29a58c-f4a1-45f8-815e-b842ed07eba3" RevisionNumber="204" /&gt;&lt;/BundledUpdates&gt;&lt;/Relationships&gt;</Xml></UpdateInfo><UpdateInfo><ID>992302</ID><Deployment><ID>93435</ID><Action>Bundle</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="1a29a58c-f4a1-45f8-815e-b842ed07eba3" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" /&gt;&lt;Relationships&gt;&lt;/Relationships&gt;&lt;ApplicabilityRules&gt;&lt;IsInstalled&gt;&lt;False /&gt;&lt;/IsInstalled&gt;&lt;IsInstallable&gt;&lt;True /&gt;&lt;/IsInstallable&gt;&lt;/ApplicabilityRules&gt;</Xml></UpdateInfo></NewUpdates><Truncated>false</Truncated><NewCookie><Expiration>2021-08-14T18:30:49.816861</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></NewCookie><DriverSyncNotNeeded>true</DriverSyncNotNeeded></SyncUpdatesResult></SyncUpdatesResponse></s:Body></s:Envelope>

I guess I would need to try on AWS in order to have the exact same version as you. Thank you.

fneur commented 3 years ago

Hi @nitbx, can you provide your WindowsUpdate log file, please, so we can compare it with the one I linked above (in the first comment)? We might spot differences there.

(Note: The Get-WindowsUpdateLog cmdlet merges and converts Windows Update .etl files into a single readable WindowsUpdate.log file)

Thank you!

nitbx commented 3 years ago

Interesting command, didn't know about it.

WindowsUpdate.log (Lots of garbage in the logs from testing)

Thank you.

fneur commented 3 years ago

Hi @nitbx, just compared the WindowsUpdate.log you provided above with mine (recorded on a physical Windows 10 PRO machine):

image

image

Comments / Results

Questions

Thanks,

F.

fneur commented 3 years ago

Additional info to the previous post:

I also did a test after cleaning the Windows SoftwareDistribution folder (which is often recommended to troubleshoot Windows Update problems). The corresponding log file is depicted below (basically the same as in the previous post, but with an additional GetConfig call):

image

nitbx commented 3 years ago

Hi @fneur and thank you for the time you take to address this issue with us.

For now it does not ring any bell, but I will try with a non-domain join host.

After, can you show me your GPO in order to specify the WSUS. I'm not sure what you mean by:

Internal update server + intranet server for statistics: http://10.0.0.4:8530 no connection to MS Windows Update Servers allowed setting 3 enabled <---- ?

Mine:

image

nitbx commented 3 years ago

I got the same issue with a non-domain joined host.

POST /ClientWebService/client.asmx HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Accept-Encoding: xpress
User-Agent: Windows-Update-Agent/10.0.10011.16384 Client-Protocol/2.32
SOAPAction: "http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdates"
MS-CV: pB9M6b7RckGPpXqU.0.1.0.0.2.1
Content-Length: 815
Host: 192.168.178.143:8530

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SyncUpdates xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><cookie><Expiration>2021-08-23T12:08:57.325699Z</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></cookie><parameters><ExpressQuery>false</ExpressQuery><OtherCachedUpdateIDs><int>906239</int><int>910283</int><int>911970</int><int>943135</int><int>975153</int><int>976831</int><int>978234</int><int>982703</int><int>985672</int><int>992916</int></OtherCachedUpdateIDs><SkipSoftwareSync>false</SkipSoftwareSync><NeedTwoGroupOutOfScopeUpdates>false</NeedTwoGroupOutOfScopeUpdates><AlsoPerformRegularSync>true</AlsoPerformRegularSync><ComputerSpec/></parameters></SyncUpdates></s:Body></s:Envelope>HTTP/1.1 200 OK
Server: BaseHTTP/0.6 Python/3.9.1+
Date: Sun, 22 Aug 2021 16:09:15 GMT
Cache-Control: private
Content-type: text/xml; chartset=utf-8
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w4.org/2001/XMLSchema-instance"><SyncUpdatesResponse xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService"><SyncUpdatesResult><NewUpdates><UpdateInfo><ID>915262</ID><Deployment><ID>87339</ID><Action>Install</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="d0963579-594f-45c8-97e0-e363c3998b6e" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" ExplicitlyDeployable="true" AutoSelectOnWebSites="true" /&gt;&lt;Relationships&gt;&lt;Prerequisites&gt;&lt;AtLeastOne IsCategory="true"&gt;&lt;UpdateIdentity UpdateID="0fa1201d-4330-4fa8-8ae9-b877473b6441" /&gt;&lt;/AtLeastOne&gt;&lt;/Prerequisites&gt;&lt;BundledUpdates&gt;&lt;UpdateIdentity UpdateID="c0a8d539-ca9b-4644-81b8-57efe7c0c93f" RevisionNumber="204" /&gt;&lt;/BundledUpdates&gt;&lt;/Relationships&gt;</Xml></UpdateInfo><UpdateInfo><ID>977787</ID><Deployment><ID>83231</ID><Action>Bundle</Action><IsAssigned>true</IsAssigned><LastChangeTime>2020-02-29</LastChangeTime><AutoSelect>0</AutoSelect><AutoDownload>0</AutoDownload><SupersedenceBehavior>0</SupersedenceBehavior></Deployment><IsLeaf>true</IsLeaf><Xml>&lt;UpdateIdentity UpdateID="c0a8d539-ca9b-4644-81b8-57efe7c0c93f" RevisionNumber="204" /&gt;&lt;Properties UpdateType="Software" /&gt;&lt;Relationships&gt;&lt;/Relationships&gt;&lt;ApplicabilityRules&gt;&lt;IsInstalled&gt;&lt;False /&gt;&lt;/IsInstalled&gt;&lt;IsInstallable&gt;&lt;True /&gt;&lt;/IsInstallable&gt;&lt;/ApplicabilityRules&gt;</Xml></UpdateInfo></NewUpdates><Truncated>false</Truncated><NewCookie><Expiration>2021-08-23T12:09:13.871497</Expiration><EncryptedData>QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=</EncryptedData></NewCookie><DriverSyncNotNeeded>true</DriverSyncNotNeeded></SyncUpdatesResult></SyncUpdatesResponse></s:Body></s:Envelope>

I'm confident that if we find the right UpdateID we can make it work.

Still nice that we found the issue.

Thank you.

nitbx commented 3 years ago

I found something.

Fresh Windows 10 not domain joined but with latest update from MSFT

Fresh Windows 10 not domain joined with the latest update from MSFT. After registering with the real WSUS and performing one checks update. Then changing the local GPO for the PYWSUS server.

I will compare Wireshark traces and keep you updated.

Thank you

fneur commented 3 years ago

Hi @nitbx,

thanks for your effort. I appreciate it. Here are my GPO settings:

image

image

image

bananabr commented 2 years ago

Same situation here. I can never get past SyncUpdates. Any updates on this?

Thank you

fneur commented 2 years ago

No. Unfortunately, no positive updates on my part!

nitbx commented 2 years ago

Thanks for following up. I'm working on it when it possible.

The status is that I'm confident the attack could work on a non-domain join computer. Performing the attack, the other way around (with WSUSpendu). I'm able to inject a malicious update to a non-domain joined workstations.

Now it just a question of finding a needle in a PCAP.

NsByte commented 2 years ago

Has there been any update on this? I'm having the same issue on a fresh installed windows 10 pro. Out of the box the client wouldn't get passed the SyncUpdates. It did work after syncing with a legit WSUS server once and after that replace the WSUS server with the malicious one

fneur commented 2 years ago

Has there been any update on this? I'm having the same issue on a fresh installed windows 10 pro. Out of the box the client wouldn't get passed the SyncUpdates. It did work after syncing with a legit WSUS server once and after that replace the WSUS server with the malicious one

No

x13x13x commented 1 year ago

I am afraid I have the exacxt same problem and in a pentest the update never goes further than the syncupdate-request.... Probably the solution is to use another younger tool...

Anybody found a good working alternative?