forked from mubix/PowerWorm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGet-ExcelMacro.ps1
157 lines (116 loc) · 4.58 KB
/
Get-ExcelMacro.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
function Get-ExcelMacro
{
<#
.SYNOPSIS
Outputs the contents on an Excel macro if it is present in an Excel spreadsheet.
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
.DESCRIPTION
Get-ExcelMacro outputs the contents of an Excel macro if it is present and
optionally removes it if the '-Remove' switch is provided.
.PARAMETER Remove
Remove all macros from an Excel spreadsheet if they are present.
.PARAMETER Force
Suppress the confirmation prompt when the '-Remove' switch is used.
.EXAMPLE
Get-ChildItem C:\* -Recurse -Include "*.xls","*.xlsx" | Get-ExcelMacro
.EXAMPLE
Get-ExcelMacro -Path evil.xls -Remove
.NOTES
Get-ExcelMacro relies on the Excel COM object which requires that Excel be
installed. When the '-Remove' switch is provided to Get-ExcelMacro, all macros
are removed from the Excel spreadsheet. Be mindful of this fact if your
organization relies upon macros for legitimate purposes.
.LINK
http://www.exploit-monday.com/2014/04/powerworm-analysis.html
#>
[CmdletBinding(SupportsShouldProcess = $True , ConfirmImpact = 'Medium')]
Param (
[Parameter(Position = 0, ValueFromPipeline = $True)]
[ValidateScript({Test-Path $_})]
[String[]]
$Path,
[Parameter(ParameterSetName = 'Remove')]
[Switch]
$Remove,
[Parameter(ParameterSetName = 'Remove')]
[Switch]
$Force
)
BEGIN
{
try
{
$Excel = New-Object -ComObject Excel.Application
}
catch
{
throw 'Excel is not installed. Get-ExcelMacro requires that Excel be installed.'
}
# EXTREMELY IMPORTANT!!!
# Disable automatic execution of macros
$Excel.AutomationSecurity = 'msoAutomationSecurityForceDisable'
# Disable save dialogs
$Excel.DisplayAlerts = $False
# Macro security settings need to be briefly disabled in order to view and remove macros.
# They will be restored at the end of the script
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name AccessVBOM -Type DWORD -Value 1
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name VBAWarnings -Type DWORD -Value 1
}
PROCESS
{
foreach ($File In $Path)
{
$FullPath = Resolve-Path $File
$Workbooks = $Excel.Workbooks.Open($FullPath.Path)
$CodeModule = $Workbooks.VBProject.VBComponents.Item(1).CodeModule
$CurrentLine = 1
if ($CodeModule)
{
do
{
$FunctionName = $CodeModule.ProcOfLine($CurrentLine, [ref] 0)
if ($FunctionName -ne $null)
{
$StartLine = $CurrentLine
$EndingLine = $CodeModule.ProcCountLines($FunctionName, 0) - 1
$Result = @{
ExcelDocument = $FullPath
FunctionName = $FunctionName
MacroContents = $CodeModule.Lines($StartLine, $EndingLine)
}
$MacroObject = New-Object PSObject -Property $Result
$MacroObject
$CurrentLine += $EndingLine
}
} while ($CurrentLine -lt $CodeModule.CountOfLines)
if ($Remove)
{
if ($Force -or ($Response = $PSCmdlet.ShouldContinue('Do you want to proceed?',
"Removing macro from $FullPath"))) { }
if ($CodeModule.CountOfLines -gt 0)
{
$CodeModule.DeleteLines(1, $CodeModule.CountOfLines)
}
# http://msdn.microsoft.com/en-us/library/ff198017(v=office.14).aspx
$xlWorkbookDefault = 51
$Workbooks.SaveAs($FullPath.Path, $xlWorkbookDefault)
if ($MacroObject)
{
Write-Verbose "Removed macro from $FullPath."
}
}
}
$Workbooks.Close($False)
}
}
END
{
# Re-enable macro security settings
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name AccessVBOM -Type DWORD -Value 0
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name VBAWarnings -Type DWORD -Value 0
$Excel.Quit()
# Kill orphaned Excel process
Get-Process excel | ? { $_.MainWindowHandle -eq 0 } | Stop-Process
}
}