-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFind-AVSignature.ps1
186 lines (137 loc) · 6.59 KB
/
Find-AVSignature.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
function Find-AVSignature
{
<#
.SYNOPSIS
Locate tiny AV signatures.
PowerSploit Function: Find-AVSignature
Authors: Chris Campbell (@obscuresec) & Matt Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Locates single Byte AV signatures utilizing the same method as DSplit from "class101" on heapoverflow.com.
.PARAMETER Startbyte
Specifies the first byte to begin splitting on.
.PARAMETER Endbyte
Specifies the last byte to split on.
.PARAMETER Interval
Specifies the interval size to split with.
.PARAMETER Path
Specifies the path to the binary you want tested.
.PARAMETER OutPath
Optionally specifies the directory to write the binaries to.
.PARAMETER BufferLen
Specifies the length of the file read buffer . Defaults to 64KB.
.PARAMETER Force
Forces the script to continue without confirmation.
.EXAMPLE
Find-AVSignature -Startbyte 0 -Endbyte max -Interval 10000 -Path c:\test\exempt\nc.exe
Find-AVSignature -StartByte 10000 -EndByte 20000 -Interval 1000 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run2 -Verbose
Find-AVSignature -StartByte 16000 -EndByte 17000 -Interval 100 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run3 -Verbose
Find-AVSignature -StartByte 16800 -EndByte 16900 -Interval 10 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run4 -Verbose
Find-AVSignature -StartByte 16890 -EndByte 16900 -Interval 1 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run5 -Verbose
.NOTES
Several of the versions of "DSplit.exe" available on the internet contain malware.
.LINK
http://obscuresecurity.blogspot.com/2012/12/finding-simple-av-signatures-with.html
https://github.com/mattifestation/PowerSploit
http://www.exploit-monday.com/
http://heapoverflow.com/f0rums/project.php?issueid=34&filter=changes&page=2
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')]
[CmdletBinding()]
Param(
[Parameter(Mandatory = $True)]
[ValidateRange(0,4294967295)]
[UInt32]
$StartByte,
[Parameter(Mandatory = $True)]
[String]
$EndByte,
[Parameter(Mandatory = $True)]
[ValidateRange(0,4294967295)]
[UInt32]
$Interval,
[String]
[ValidateScript({Test-Path $_ })]
$Path = ($pwd.path),
[String]
$OutPath = ($pwd),
[ValidateRange(1,2097152)]
[UInt32]
$BufferLen = 65536,
[Switch] $Force
)
#test variables
if (!(Test-Path $Path)) {Throw "File path not found"}
$Response = $True
if (!(Test-Path $OutPath)) {
if ($Force -or ($Response = $psCmdlet.ShouldContinue("The `"$OutPath`" does not exist! Do you want to create the directory?",""))){new-item ($OutPath)-type directory}
}
if (!$Response) {Throw "Output path not found"}
if (!(Get-ChildItem $Path).Exists) {Throw "File not found"}
[Int32] $FileSize = (Get-ChildItem $Path).Length
if ($StartByte -gt ($FileSize - 1) -or $StartByte -lt 0) {Throw "StartByte range must be between 0 and $Filesize"}
[Int32] $MaximumByte = (($FileSize) - 1)
if ($EndByte -ceq "max") {$EndByte = $MaximumByte}
#Recast $Endbyte into an Integer so that it can be compared properly.
[Int32]$EndByte = $EndByte
#If $Endbyte is greater than the file Length, use $MaximumByte.
if ($EndByte -gt $FileSize) {$EndByte = $MaximumByte}
#If $Endbyte is less than the $StartByte, use 1 Interval past $StartByte.
if ($EndByte -lt $StartByte) {$EndByte = $StartByte + $Interval}
Write-Verbose "StartByte: $StartByte"
Write-Verbose "EndByte: $EndByte"
#find the filename for the output name
[String] $FileName = (Split-Path $Path -leaf).Split('.')[0]
#Calculate the number of binaries
[Int32] $ResultNumber = [Math]::Floor(($EndByte - $StartByte) / $Interval)
if (((($EndByte - $StartByte) % $Interval)) -gt 0) {$ResultNumber = ($ResultNumber + 1)}
#Prompt user to verify parameters to avoid writing binaries to the wrong directory
$Response = $True
if ( $Force -or ( $Response = $psCmdlet.ShouldContinue("This script will result in $ResultNumber binaries being written to `"$OutPath`"!",
"Do you want to continue?"))){}
if (!$Response) {Return}
Write-Verbose "This script will now write $ResultNumber binaries to `"$OutPath`"."
[Int32] $Number = [Math]::Floor($Endbyte/$Interval)
#Create a Read Buffer and Stream.
#Note: The Filestream class takes advantage of internal .NET Buffering. We set the default internal buffer to 64KB per http://research.microsoft.com/pubs/64538/tr-2004-136.doc.
[Byte[]] $ReadBuffer=New-Object byte[] $BufferLen
[System.IO.FileStream] $ReadStream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read, $BufferLen)
#write out the calculated number of binaries
[Int32] $i = 0
for ($i -eq 0; $i -lt $ResultNumber + 1 ; $i++)
{
# If this is the Final Binary, use $EndBytes, Otherwise calculate based on the Interval
if ($i -eq $ResultNumber) {[Int32]$SplitByte = $EndByte}
else {[Int32] $SplitByte = (($StartByte) + (($Interval) * ($i)))}
Write-Verbose "Byte 0 -> $($SplitByte)"
#Reset ReadStream to beginning of file
$ReadStream.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null
#Build a new FileStream for Writing
[String] $outfile = Join-Path $OutPath "$($FileName)_$($SplitByte).bin"
[System.IO.FileStream] $WriteStream = New-Object System.IO.FileStream($outfile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::None, $BufferLen)
[Int32] $BytesLeft = $SplitByte
Write-Verbose "$($WriteStream.name)"
#Write Buffer Length to the Writing Stream until the bytes left is smaller than the buffer
while ($BytesLeft -gt $BufferLen){
[Int32]$count = $ReadStream.Read($ReadBuffer, 0, $BufferLen)
$WriteStream.Write($ReadBuffer, 0, $count)
$BytesLeft = $BytesLeft - $count
}
#Write the remaining bytes to the file
do {
[Int32]$count = $ReadStream.Read($ReadBuffer, 0, $BytesLeft)
$WriteStream.Write($ReadBuffer, 0, $count)
$BytesLeft = $BytesLeft - $count
}
until ($BytesLeft -eq 0)
$WriteStream.Close()
$WriteStream.Dispose()
}
Write-Verbose "Files written to disk. Flushing memory."
$ReadStream.Dispose()
#During testing using large binaries, memory usage was excessive so lets fix that
[System.GC]::Collect()
Write-Verbose "Completed!"
}