aboutsummaryrefslogtreecommitdiff
path: root/AntivirusBypass
diff options
context:
space:
mode:
authorgarignack <garignack@gmail.com>2013-05-02 01:29:19 -0400
committergarignack <garignack@gmail.com>2013-05-02 01:29:19 -0400
commitacc46c71f758554ac4575283b7905a09cb437ba6 (patch)
tree9f8ea0c0a000a3391c3bbd4e702cf5d947dcc0f6 /AntivirusBypass
parent2224f4dca9d856f37a02a9fe4c1941d27c4e564f (diff)
downloadPowerSploit-acc46c71f758554ac4575283b7905a09cb437ba6.tar.gz
PowerSploit-acc46c71f758554ac4575283b7905a09cb437ba6.zip
Find-AVSignature Performance Improvements
Updated code to use [System.IO.FileStream] class with a buffer (64kb default) to greatly increase performance, especially when handling large files. Updated $EndBytes validation logic to change it to a valid value rather than throw an error.
Diffstat (limited to 'AntivirusBypass')
-rw-r--r--AntivirusBypass/Find-AVSignature.ps1309
1 files changed, 177 insertions, 132 deletions
diff --git a/AntivirusBypass/Find-AVSignature.ps1 b/AntivirusBypass/Find-AVSignature.ps1
index c373c5b..7a3f7c4 100644
--- a/AntivirusBypass/Find-AVSignature.ps1
+++ b/AntivirusBypass/Find-AVSignature.ps1
@@ -1,133 +1,178 @@
-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 Force
-
-Forces the script to continue without confirmation.
-
-.EXAMPLE
-
-PS C:\> Find-AVSignature -Startbyte 0 -Endbyte max -Interval 10000 -Path c:\test\exempt\nc.exe
-PS C:\> Find-AVSignature -StartByte 10000 -EndByte 20000 -Interval 1000 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run2 -Verbose
-PS C:\> Find-AVSignature -StartByte 16000 -EndByte 17000 -Interval 100 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run3 -Verbose
-PS C:\> Find-AVSignature -StartByte 16800 -EndByte 16900 -Interval 10 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run4 -Verbose
-PS C:\> 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
-#>
-
- [CmdletBinding()] Param(
- [Parameter(Mandatory = $True)]
- [Int32]
- $StartByte,
-
- [Parameter(Mandatory = $True)]
- [String]
- $EndByte,
-
- [Parameter(Mandatory = $True)]
- [Int32]
- $Interval,
-
- [String]
- $Path = ($pwd.path),
-
- [String]
- $OutPath = ($pwd),
-
- [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}
- if ($EndByte -gt $FileSize -or $EndByte -lt 0) {Throw "EndByte range must be between 0 and $Filesize"}
-
- #read in byte array
- [Byte[]] $FileByteArray = [System.IO.File]::ReadAllBytes($Path)
-
- #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)
-
- #write out the calculated number of binaries
- [Int32] $i = 0
- for ($i -eq 0; $i -lt $ResultNumber; $i++)
- {
- [Int32] $SplitByte = (($StartByte) + (($Interval) * ($i)))
- Write-Verbose "Byte 0 -> $($SplitByte)"
- [IO.File]::WriteAllBytes((Join-Path $OutPath "$($FileName)_$($SplitByte).bin"), $FileByteArray[0..($SplitByte)])
- }
-
- #Write out the final binary
- [IO.File]::WriteAllBytes((Join-Path $OutPath "$($FileName)_$($EndByte).bin"), $FileByteArray[0..($EndByte)])
- Write-Verbose "Byte 0 -> $($EndByte)"
- Write-Verbose "Files written to disk. Flushing memory."
-
- #During testing using large binaries, memory usage was excessive so lets fix that
- [System.GC]::Collect()
- Write-Verbose "Completed!"
+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 Force
+
+Forces the script to continue without confirmation.
+
+.EXAMPLE
+
+PS C:\> Find-AVSignature -Startbyte 0 -Endbyte max -Interval 10000 -Path c:\test\exempt\nc.exe
+PS C:\> Find-AVSignature -StartByte 10000 -EndByte 20000 -Interval 1000 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run2 -Verbose
+PS C:\> Find-AVSignature -StartByte 16000 -EndByte 17000 -Interval 100 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run3 -Verbose
+PS C:\> Find-AVSignature -StartByte 16800 -EndByte 16900 -Interval 10 -Path C:\test\exempt\nc.exe -OutPath c:\test\output\run4 -Verbose
+PS C:\> 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
+#>
+
+ [CmdletBinding()] Param(
+ [Parameter(Mandatory = $True)]
+ [Int32]
+ $StartByte,
+
+ [Parameter(Mandatory = $True)]
+ [String]
+ $EndByte,
+
+ [Parameter(Mandatory = $True)]
+ [Int32]
+ $Interval,
+
+ [String]
+ [ValidateScript({Test-Path $_ })]
+ $Path = ($pwd.path),
+
+ [String]
+ $OutPath = ($pwd),
+
+ [int]
+ $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)
+
+ #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!"
} \ No newline at end of file