我试图使用带有ctypes的GetTokenInformation函数。 问题是它将始终打印无。
import winappdbg
from ctypes import *
LPVOID = c_void_p
PVOID = LPVOID
PSID = PVOID
DWORD = c_uint32
class SID_AND_ATTRIBUTES(Structure):
_fields_ = [
("Sid", PSID),
("Attributes", DWORD),
]
class TOKEN_USER(Structure):
_fields_ = [
("User", SID_AND_ATTRIBUTES),]
tokenprivs = (winappdbg.win32.TOKEN_QUERY | winappdbg.win32.TOKEN_READ | winappdbg.win32.TOKEN_IMPERSONATE | winappdbg.win32.TOKEN_QUERY_SOURCE | winappdbg.win32.TOKEN_DUPLICATE | winappdbg.win32.TOKEN_ASSIGN_PRIMARY)
hProcess = winappdbg.win32.OpenProcess(winappdbg.win32.PROCESS_QUERY_INFORMATION, False, winappdbg.win32.GetCurrentProcessId())
hToken = winappdbg.win32.OpenProcessToken(hProcess, DesiredAccess = tokenprivs)
tokeninformation = TOKEN_USER()
dwLength = DWORD(0)
windll.advapi32.GetTokenInformation(hToken, winappdbg.win32.TokenUser, byref(tokeninformation), sizeof(TOKEN_USER), byref(dwLength))
print tokeninformation.User.Sid
P.S。我知道win32security.GetTokenInformation存在。但是我想使用ctypes,因为真正的进程处理程序。
编辑:
工作代码:
import winappdbg
from ctypes import *
LPVOID = c_void_p
PVOID = LPVOID
PSID = PVOID
DWORD = c_uint32
class SID_AND_ATTRIBUTES(Structure):
_fields_ = [
("Sid", PSID),
("Attributes", DWORD),
]
class TOKEN_USER(Structure):
_fields_ = [
("User", SID_AND_ATTRIBUTES),]
tokenprivs = (winappdbg.win32.TOKEN_QUERY | winappdbg.win32.TOKEN_READ | winappdbg.win32.TOKEN_IMPERSONATE | winappdbg.win32.TOKEN_QUERY_SOURCE | winappdbg.win32.TOKEN_DUPLICATE | winappdbg.win32.TOKEN_ASSIGN_PRIMARY)
hProcess = winappdbg.win32.OpenProcess(winappdbg.win32.PROCESS_QUERY_INFORMATION, False, winappdbg.win32.GetCurrentProcessId())
hToken = winappdbg.win32.OpenProcessToken(hProcess, DesiredAccess = tokenprivs)
dwSize = DWORD(0)
pStringSid = winappdbg.win32.LPSTR()
windll.advapi32.GetTokenInformation(hToken, winappdbg.win32.TokenUser, None, 0, byref(dwSize))
address = windll.kernel32.LocalAlloc(0x0040, dwSize)
print "Address: " + str(address)
windll.advapi32.GetTokenInformation(hToken, winappdbg.win32.TokenUser, address, dwSize, byref(dwSize))
print FormatError(GetLastError())
pToken_User = cast(address, POINTER(TOKEN_USER))
windll.advapi32.ConvertSidToStringSidA(pToken_User.contents.User.Sid, byref(pStringSid))
print "SID: " + pStringSid.value
答案 0 :(得分:1)
虽然对令牌信息类TokenUser
的查询在目标缓冲区中存储了TOKEN_USER
结构,但它本身并不包含所有必需的信息。正如你在结构的文档中看到的那样,它只包含SID_AND_ATTRIBUTES
结构,而结构只包含一个指针到一个SID和一个带有标志的整数。
如果您添加了更多错误检查,您会看到对GetTokenInformation()
的调用失败,报告的错误代码为ERROR_INSUFFICIENT_BUFFER
(122)且dwLength
设置为某事像36(肯定超过sizeof(TOKEN_USER)
,只有8)。
显然,函数需要在目标缓冲区中有足够的空间来存储甚至SID本身,然后从记录的输出结构TOKEN_USER
指向那些额外的数据。
我不太了解Ctypes,但是您需要将输出缓冲区创建为真正的缓冲区/数组而不仅仅是结构,并对其执行一些转换以获取数据。你可以采取简单的方法,在第一次尝试时创建足够大的缓冲区,或者调用函数两次,首先获得所需的缓冲区长度,然后再填充它。