Trust Wallet Core 安全漏洞CVE-2025-66692
Trust Wallet Core是Trust Wallet公司的开源的、跨平台、以移动为中心的库,支撑钱包应用与 Web3 项目快速实现多链资产安全管理。
一、基本情况
Trust Wallet Core是Trust Wallet生态的核心底层库,提供私钥管理、地址生成、交易签名等低级别密码学功能,支持130 +主流区块链。
Trust Wallet Core专注于钱包底层核心能力,不包含 UI与上层业务逻辑,其主打跨平台、多链兼容的加密钱包基础能力,适配多链协议。

栋科技漏洞库关注到Trust Wallet Core受影响版本中存在缓冲区溢出漏洞,该漏洞现已被追踪为CVE-2025-66692,CVSS 3.X评分7.5。
二、漏洞分析
CVE-2025-66692漏洞是Trust Wallet Core 5668c67之前版本中的安全漏洞,该漏洞源于PublicKey::verify方法存在缓冲区过度读取。
该漏洞源于Trust Wallet Core的PublicKey::verify()方法中存在缓冲区溢出,攻击者可能会通过特制输入造成拒绝服务(DoS)。
由于PublicKey::verify()方法接受一个Data&类型的signature参数(std::vector<uint8_t>),在将其传递给加密函数之前未验证其大小:
1、文件:PublicKey.cpp
bool PublicKey::verify(const Data& signature, const Data& message) const {
switch (type) {
case TWPublicKeyTypeSECP256k1:
case TWPublicKeyTypeSECP256k1Extended:
return ecdsa_verify_digest(&secp256k1, bytes.data(),
signature.data(), // NO SIZE VALIDATION
message.data()) == 0;
预期行为与实际行为
预期:所有加密验证函数都预期恰好需要64个字节:
ECDSA(SECP256k1/NIST256p1):64字节(32字节R + 32字节S)
ED25519/Curve25519:64字节签名
实际:ecdsa_verify_digest 在读取签名字节时未进行边界检查:
2、文件:TrezorCrypto/ecdsa。
int ecdsa_verify_digest(..., const uint8_t *sig, ...) {
bn_read_be(sig, &r); // Reads bytes 0-31
bn_read_be(sig + 32, &s); // Reads bytes 32-63
// If sig has < 64 bytes -> BUFFER OVER-READ
}
如果signature.size()小于64,则在调用任何加密函数之前,就会导致立即发生越界访问。
三、POC概念验证
1、将此测试添加到tests/PublicKeyTests.cpp文件中:
管理员已设置登录后刷新可查看3、步骤:
将上述测试添加到 PublicKeyTests.cpp 中
构建:cmake --build build
运行:./build/tests/tests --gtest_filter="*VerifyShortSignatureCrash"
观察:分段错误
3、漏洞证据
证据1:PublicKey.cpp中缺少验证
// src/PublicKey.cpp - NO size check before crypto operations
bool PublicKey::verify(const Data& signature, const Data& message) const {
switch (type) {
case TWPublicKeyTypeSECP256k1:
case TWPublicKeyTypeSECP256k1Extended:
// signature.data() passed directly without size check
return ecdsa_verify_digest(&secp256k1, bytes.data(),
signature.data(), message.data()) == 0;
证据2:ecdsa_verify_digest需要64个字节
// TrezorCrypto/ecdsa.c
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest) {
// ...
bn_read_be(sig, &r); // Reads bytes 0-31 (32 bytes)
bn_read_be(sig + 32, &s); // Reads bytes 32-63 (32 bytes)
// Total: 64 bytes expected, NO length parameter
证据3:生产代码使用了此漏洞
// src/FIO/Signer.cpp
bool Signer::verify(const PublicKey& pubKey, const Data& data, const Data& signature) {
return pubKey.verify(TW::data(signature.data() + 1, signature.size() - 1), data);
// signature parameter comes from external input (network transactions)
// NO validation before creating Data and passing to verify()
}
证据4:其他代码验证通过,此代码未通过(不一致性)
// src/EOS/Transaction.cpp
Signature::Signature(const Data& sig, Type type) : data(sig), type(type) {
if (sig.size() != DataSize) { // SIZE VALIDATION PRESENT
throw std::invalid_argument("Invalid signature size!");
}
}
// But PublicKey::verify() has NO such check
// Inconsistency indicates oversight/bug
Evidence 5: CURVE25519 Direct Array Access
// src/PublicKey.cpp
case TWPublicKeyTypeCURVE25519: {
// ...
ed25519PublicKey[31] |= signature[63] & 0x80; // Access signature[63]
// ...
verifyBuffer[63] &= 127; // Access again
// If signature.size() < 64 -> Immediate out-of-bounds access
}
证据6:测试缺口表明遗漏了漏洞
// tests/PublicKeyTests.cpp - All tests use VALID signatures
TEST(PublicKeyTests, Verify) {
// ...
const auto signature = privateKey.sign(digest); // Valid 65-byte signature
EXPECT_TRUE(publicKey.verify(signature, digest)); // Never tests size < 64
}
// NO test case for signature.size() < 64
// Vulnerability went undetected due to insufficient test coverage
4、利用路径
(1)恶意/易受攻击的区块链创建带有短签名的交易
(2)交易通过区块链网络进行传播
(3)Trust Wallet同步和调用:
管理员已设置登录后刷新可查看(4)使用短签名(例如,10个字节)调用 PublicKey::verify()
(5)无大小验证 → 直接进入加密函数
(6)加密函数尝试从10字节的缓冲区中读取64个字节
(7)缓冲区溢出 → 分段错误 → 钱包崩溃
5、补救
在 PublicKey::verify() 方法的开头添加签名大小验证:
bool PublicKey::verify(const Data& signature, const Data& message) const {
// FIX: Validate signature size before any processing
const size_t expectedSigSize = 64; // All signature types use 64 bytes
if (signature.size() != expectedSigSize) {
return false; // Invalid signature size
}
switch (type) {
case TWPublicKeyTypeSECP256k1:
case TWPublicKeyTypeSECP256k1Extended:
return ecdsa_verify_digest(&secp256k1, bytes.data(),
signature.data(),
message.data()) == 0;
// ... rest of code unchanged
四、影响范围
Trust Wallet Core <= 5668c67
五、参考链接
Trust Wallet Core >= 5668c67
六、参考链接
管理员已设置登录后刷新可查看