Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有子进程的Golang的Windows服务模拟-拒绝访问_Windows_Service_Impersonation_Upn - Fatal编程技术网

具有子进程的Golang的Windows服务模拟-拒绝访问

具有子进程的Golang的Windows服务模拟-拒绝访问,windows,service,impersonation,upn,Windows,Service,Impersonation,Upn,我试图在作为服务运行时获取已登录用户的UPN。我能够以DOMAIN\Username格式获取登录用户的用户名,以及用户的SessionID和许多其他内容 为了获得UPN,我试图通过获取一个访问令牌并使用这个目标令牌运行whoami/UPN命令来模拟用户。当服务直接执行此操作时,它工作得很好,但当此服务的子进程执行此操作时,它不工作 下面是获取已登录用户的UPN的go示例。事实上,我不能简单地获取当前用户的UPN,因为应用程序是作为服务运行的 导入( “错误” “fmt” “操作系统” “os/e

我试图在作为服务运行时获取已登录用户的UPN。我能够以
DOMAIN\Username
格式获取登录用户的
用户名
,以及用户的
SessionID
和许多其他内容

为了获得UPN,我试图通过获取一个访问令牌并使用这个目标令牌运行
whoami/UPN
命令来模拟用户。当服务直接执行此操作时,它工作得很好,但当此服务的子进程执行此操作时,它不工作

下面是获取已登录用户的UPN的go示例。事实上,我不能简单地获取当前用户的UPN,因为应用程序是作为服务运行的

导入(
“错误”
“fmt”
“操作系统”
“os/exec”
“字符串”
“系统调用”
“不安全”
winapi“github.com/kumako/go-win64api”
“golang.org/x/sys/windows”
“qohash.com/qostodian代理/内部/日志”
)
变量(
modwtsapi32*windows.LazyDLL=windows.newlazystemdll(“wtsapi32.dll”)
modadvapi32*windows.LazyDLL=windows.newlazystemdll(“advapi32.dll”)
procWTSQueryUserToken*windows.LazyProc=modwtsapi32.NewProc(“WTSQueryUserToken”)
procDuplicateTokenEx*windows.LazyProc=modadvapi32.NewProc(“DuplicateTokenEx”)
)
func GetUserSessions()([]用户,错误){
var u[]用户
用户,错误:=winapi.ListLoggedInUsers()
如果错误!=零{
返回u,错误
}
对于_,用户:=范围用户{
var upn字符串
变量错误
//UPN翻译不起作用->尝试模拟会话并运行whoami命令
upn,err=getUpnForLoggedUser(user.SessionID)
如果错误!=零{
logging.Debugf(“无法获取用户%v的UPN:\n\t-第一次尝试:%v\n\t”,user.FullUser(),err)
}否则{
logging.Debugf(“用户UPN:%v”,UPN)
}
u=附加(u,用户{
用户名:user.Username,
域:user.Domain,
Upn:Upn,
})
}
返回u,零
}
func getUpnForLoggedUser(sessionID uint32)(字符串,错误){
userToken,err:=duplicateUserTokenFromSessionID(windows.Handle(sessionID))
如果错误!=零{
返回“”,fmt.Errorf(“获取当前用户会话的重复用户令牌:%s”,错误)
}
winPath,ok:=os.LookupEnv(“SystemRoot”)
如果!好的{
返回“”,错误。新建(“无法获取SystemRoot环境变量”)
}
cmd:=exec.Command(fmt.Sprintf(“%s\\system32\\whoami.exe”,winPath),“/upn”)
cmd.SysProcAttr=&syscall.SysProcAttr{
希德温多:没错,
令牌:userToken,
}
out,err:=cmd.CombinedOutput()
如果错误!=零{
返回“”,错误
}
userToken.Close()
返回strings.TrimSpace(string(out)),nil
}
func duplicateUserTokenFromSessionID(sessionId windows.Handle)(syscall.Token,错误){
变量(
impersonationToken windows.Handle=0
userToken syscall.Token=0
)
如果返回代码,则错误:=procWTSQueryUserToken.Call(uintpttr(sessionId)、uintpttr(unsafe.Pointer(&impersonationToken));返回代码==0{
返回0xFFFFFF,fmt.Errorf(“调用本机WTSQueryUserToken:%s”,错误)
}
如果返回代码,则错误:=procDuplicateTokenEx.Call(uintpttr(impersonationToken)、0、0、uintpttr(windows.SecurityImpersonation)、uintpttr(windows.TokenPrimary)、uintpttr(unsafe.Pointer(&userToken));返回代码==0{
返回0xFFFFFF,fmt.Errorf(“调用本机DuplicateTokenEx:%s”,err)
}
如果错误:=windows.CloseHandle(模拟令牌);错误!=nil{
返回0xFFFFFF,fmt.Errorf(“关闭用于令牌复制的windows句柄:%s”,错误)
}
返回userToken,nil
}
当我的主服务调用
GetUserSessions
时,它工作并返回已登录UPN的用户

如果此主服务生成子流程,则UPN始终为空。调用
whoami
时,应用程序将获得
fork/exec C:\WINDOWS\system32\whoami.exe:访问被拒绝

我的问题是:

  • 模拟用户是获取用户UPN的好方法吗?经过多次不同的测试,我没有发现其他方法可以做到这一点
  • 如果没有其他方法,我需要做什么才能使子进程拥有作为另一个服务运行
    whoami/upn
    命令的权限
  • 谢谢大家!