fix env vars in runasuser fixes amidaware/tacticalrmm#1614

This commit is contained in:
wh1te909 2023-08-24 12:35:11 -07:00
parent 90d0bbf020
commit 4f91148753
2 changed files with 68 additions and 6 deletions

View File

@ -161,22 +161,37 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
defer cancel() defer cancel()
var timedOut = false var timedOut = false
var token *wintoken.Token
var envBlock *uint16
usingEnvVars := len(envVars) > 0
cmd := exec.Command(exe, cmdArgs...) cmd := exec.Command(exe, cmdArgs...)
if runasuser { if runasuser {
token, err := wintoken.GetInteractiveToken(wintoken.TokenImpersonation) token, err = wintoken.GetInteractiveToken(wintoken.TokenImpersonation)
if err == nil { if err == nil {
defer token.Close() defer token.Close()
cmd.SysProcAttr = &syscall.SysProcAttr{Token: syscall.Token(token.Token()), HideWindow: true} cmd.SysProcAttr = &syscall.SysProcAttr{Token: syscall.Token(token.Token()), HideWindow: true}
if usingEnvVars {
envBlock, err = CreateEnvironmentBlock(syscall.Token(token.Token()))
if err == nil {
defer DestroyEnvironmentBlock(envBlock)
userEnv := EnvironmentBlockToSlice(envBlock)
cmd.Env = userEnv
} else {
cmd.Env = os.Environ()
} }
} }
}
} else if usingEnvVars {
cmd.Env = os.Environ()
}
if usingEnvVars {
cmd.Env = append(cmd.Env, envVars...)
}
cmd.Stdout = &outb cmd.Stdout = &outb
cmd.Stderr = &errb cmd.Stderr = &errb
if len(envVars) > 0 {
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, envVars...)
}
if cmdErr := cmd.Start(); cmdErr != nil { if cmdErr := cmd.Start(); cmdErr != nil {
a.Logger.Debugln(cmdErr) a.Logger.Debugln(cmdErr)
return "", cmdErr.Error(), 65, cmdErr return "", cmdErr.Error(), 65, cmdErr

View File

@ -24,11 +24,14 @@ var _ unsafe.Pointer
var ( var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
userenv = windows.NewLazyDLL("userenv.dll")
procFormatMessageW = modkernel32.NewProc("FormatMessageW") procFormatMessageW = modkernel32.NewProc("FormatMessageW")
procGetOldestEventLogRecord = modadvapi32.NewProc("GetOldestEventLogRecord") procGetOldestEventLogRecord = modadvapi32.NewProc("GetOldestEventLogRecord")
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW") procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
procReadEventLogW = modadvapi32.NewProc("ReadEventLogW") procReadEventLogW = modadvapi32.NewProc("ReadEventLogW")
procCreateEnvironmentBlock = userenv.NewProc("CreateEnvironmentBlock")
procDestroyEnvironmentBlock = userenv.NewProc("DestroyEnvironmentBlock")
) )
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-eventlogrecord // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-eventlogrecord
@ -114,3 +117,47 @@ func ReadEventLog(eventLog w32.HANDLE, readFlags ReadFlag, recordOffset uint32,
} }
return return
} }
func CreateEnvironmentBlock(token syscall.Token) (*uint16, error) {
var envBlock *uint16
ret, _, err := procCreateEnvironmentBlock.Call(
uintptr(unsafe.Pointer(&envBlock)),
uintptr(token),
0,
)
if ret == 0 {
return nil, err
}
return envBlock, nil
}
func DestroyEnvironmentBlock(envBlock *uint16) error {
ret, _, err := procDestroyEnvironmentBlock.Call(uintptr(unsafe.Pointer(envBlock)))
if ret == 0 {
return err
}
return nil
}
func EnvironmentBlockToSlice(envBlock *uint16) []string {
var envs []string
for {
len := 0
for *(*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(envBlock)) + uintptr(len*2))) != 0 {
len++
}
if len == 0 {
break
}
env := syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(envBlock))[:len])
envs = append(envs, env)
envBlock = (*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(envBlock)) + uintptr((len+1)*2)))
}
return envs
}