wordpress   发布时间:2022-04-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了确定Windows进程是否具有创建符号链接的权限大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述@H_489_4@ 我想以编程方式确定当前用户(或进程)是否有权创建符号链接.在 Windows(Vista和更高版本)中,如果没有SeCreateSymbolicLinkPrivilege,则无法创建符号链接,默认情况下,此操作仅分配给管理员.如果尝试创建没有此权限的符号链接,则会发生Windows错误1314(客户端未保留所需的权限). 为了演示此限制,我创建了一个Windows的全新安装,以初始管理员帐户登录(
我想以编程方式确定当前用户(或进程)是否有权创建符号链接.在 Windows(Vista和更高版本)中,如果没有SeCreateSymbolicLinkPrivilege,则无法创建符号链接,认情况下,此操作仅分配给管理员.如果尝试创建没有此权限的符号链接,则会发生Windows错误1314(客户端未保留所需的权限).

为了演示此限制,我创建了一个Windows的全新安装,以初始管理员帐户登录(通过UAC限制),并且无法在主目录中创建符号链接.

管理员身份运行命令提示符或禁用UAC后,该命令将无错执行.

根据this article,“代表用户执行的每个进程都有[访问]令牌的副本”.

所以我创建了a Python script to query for the permissions.为了方便和后人,我在下面添加了一段摘录.

该脚本背后的想法是枚举所有特权并确定该进程是否具有所需的特权.不幸的是,我发现当前进程实际上并没有所需的权限,即使它可以创建符号链接.

我怀疑问题在于即使当前用户的权限没有明确包含该权限,他的组成员资格确实提供了该权限.

简而言之,我如何确定给定进程是否有权创建符号链接(而不尝试创建符号链接)?最好使用C或C或Python中的示例,但使用Windows API的任何内容都是合适的.

def get_process_token():
    token = wintypes.HANDLE()
    TOKEN_all_ACCESS = 0xf01ff
    res = OpenProcessToken(GetCurrentProcess(),TOKEN_all_ACCESS,token)
    if not res > 0: raise RuntimeError("Couldn't get process token")
    return token

def get_privilege_information():
    # first call with zero length to determine what size buffer we need

    return_length = wintypes.DWORD()
    params = [
        get_process_token(),TOKEN_INFORMATION_CLASs.TokenPrivileges,None,return_length,]

    res = GetTokenInformation(*params)

    # assume we Now have the necessary length in return_length

    buffer = ctypes.create_String_buffer(return_length.value)
    params[2] = buffer
    params[3] = return_length.value

    res = GetTokenInformation(*params)
    assert res > 0,"Error in second GetTokenInformation (%d)" % res

    privileges = ctypes.cast(buffer,ctypes.POINTER(TOKEN_PRIVILEGES)).contents
    return privileges

privileges = get_privilege_information()
print("found {0} privileges".format(privileges.count))
map(print,privileges)

解决方法

我找到了解决方案.以下Python代码是Python 2.6或3.1下的全功能脚本,演示了如何确定创建符号链接的权限.在管理员帐户下运行此响应成功,并在Guest帐户下运行它会响应失败.

请注意,脚本的前3/4主要是API定义.这部小说的工作始于get_process_token().

from __future__ import print_function
import ctypes
from ctypes import wintypes

GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess
GetCurrentProcess.restype = wintypes.HANDLE
OpenProcessToken = ctypes.windll.advapi32.openProcessToken
OpenProcessToken.argtypes = (wintypes.HANDLE,wintypes.DWORD,ctypes.POINTER(wintypes.HANDLE))
OpenProcessToken.restype = wintypes.bOOL

class LUID(ctypes.StructurE):
    _fields_ = [
        ('low_part',wintypes.DWORD),('high_part',wintypes.LONG),]

    def __eq__(self,other):
        return (
            self.high_part == other.high_part and
            self.low_part == other.low_part
            )

    def __ne__(self,other):
        return not (self==other)

LookupPrivilegeValue = ctypes.windll.advapi32.LookupPrivilegeValueW
LookupPrivilegeValue.argtypes = (
    wintypes.LPWSTR,# system name
    wintypes.LPWSTR,# name
    ctypes.POINTER(LUID),)
LookupPrivilegeValue.restype = wintypes.bOOL

class TOKEN_INFORMATION_CLASS:
    TokenUser = 1
    TokenGroups = 2
    TokenPrivileges = 3
    # ... see http://msdn.microsoft.com/en-us/library/aa379626%28Vs.85%29.aspx

SE_PRIVILEGE_ENABLED_BY_DEFAULT = (0x00000001)
SE_PRIVILEGE_ENABLED            = (0x00000002)
SE_PRIVILEGE_REMOVED            = (0x00000004)
SE_PRIVILEGE_USED_FOR_ACCESS    = (0x80000000)

class LUID_AND_ATTRIBUTES(ctypes.StructurE):
    _fields_ = [
        ('LUID',LUID),('attributes',]

    def is_enabled(self):
        return bool(self.attributes & SE_PRIVILEGE_ENABLED)

    def enable(self):
        self.attributes |= SE_PRIVILEGE_ENABLED

    def get_name(self):
        size = wintypes.DWORD(10240)
        buf = ctypes.create_unicode_buffer(size.value)
        res = LookupPrivilegename(None,self.LUID,buf,sizE)
        if res == 0: raise RuntimeError
        return buf[:size.value]

    def __str__(self):
        res = self.get_name()
        if self.is_enabled(): res += ' (enabled)'
        return res

LookupPrivilegename = ctypes.windll.advapi32.LookupPrivilegenameW
LookupPrivilegename.argtypes = (
    wintypes.LPWSTR,# lpSystemName
    ctypes.POINTER(LUID),# lpLuid
    wintypes.LPWSTR,# lpName
    ctypes.POINTER(wintypes.DWORD),#cchName
    )
LookupPrivilegename.restype = wintypes.bOOL

class TOKEN_PRIVILEGES(ctypes.StructurE):
    _fields_ = [
        ('count',('privileges',LUID_AND_ATTRIBUTES*0),]

    def get_array(self):
        array_type = LUID_AND_ATTRIBUTES*self.count
        privileges = ctypes.cast(self.privileges,ctypes.POINTER(array_typE)).contents
        return privileges

    def __iter__(self):
        return iter(self.get_array())

PTOKEN_PRIVILEGES = ctypes.POINTER(TOKEN_PRIVILEGES)

GetTokenInformation = ctypes.windll.advapi32.GetTokenInformation
GetTokenInformation.argtypes = [
    wintypes.HANDLE,# TokenHandle
    ctypes.c_uint,# TOKEN_INFORMATION_CLASS value
    ctypes.c_void_p,# TokenInformation
    wintypes.DWORD,# TokenInformationLength
    ctypes.POINTER(wintypes.DWORD),# ReturnLength
    ]
GetTokenInformation.restype = wintypes.bOOL

# http://msdn.microsoft.com/en-us/library/aa375202%28Vs.85%29.aspx
AdjustTokenPrivileges = ctypes.windll.advapi32.AdjustTokenPrivileges
AdjustTokenPrivileges.restype = wintypes.bOOL
AdjustTokenPrivileges.argtypes = [
    wintypes.HANDLE,# TokenHandle
    wintypes.bOOL,# DisableAllPrivileges
    PTOKEN_PRIVILEGES,# NewState (optional)
    wintypes.DWORD,# BufferLength of PrevIoUsState
    PTOKEN_PRIVILEGES,# PrevIoUsState (out,optional)
    ctypes.POINTER(wintypes.DWORD),# ReturnLength
    ]

def get_process_token():
    """
    Get the current process token
    """
    token = wintypes.HANDLE()
    TOKEN_all_ACCESS = 0xf01ff
    res = OpenProcessToken(GetCurrentProcess(),token)
    if not res > 0: raise RuntimeError("Couldn't get process token")
    return token

def get_symlink_luid():
    """
    Get the LUID for the SeCreateSymbolicLinkPrivilege
    """
    symlink_luid = LUID()
    res = LookupPrivilegeValue(None,"SeCreateSymbolicLinkPrivilege",symlink_luid)
    if not res > 0: raise RuntimeError("Couldn't lookup privilege value")
    return symlink_luid

def get_privilege_information():
    """
    Get all privileges associated with the current process.
    """
    # first call with zero length to determine what size buffer we need

    return_length = wintypes.DWORD()
    params = [
        get_process_token(),ctypes.POINTER(TOKEN_PRIVILEGES)).contents
    return privileges

def report_privilege_information():
    """
    Report all privilege information assigned to the current process.
    """
    privileges = get_privilege_information()
    print("found {0} privileges".format(privileges.count))
    tuple(map(print,privileges))

def enable_symlink_privilege():
    """
    Try to assign the symlink privilege to the current process token.
    Return True if the assignment is successful.
    """
    # create a space in memory for a TOKEN_PRIVILEGES structure
    #  with one element
    size = ctypes.sizeof(TOKEN_PRIVILEGES)
    size += ctypes.sizeof(LUID_AND_ATTRIBUTES)
    buffer = ctypes.create_String_buffer(sizE)
    tp = ctypes.cast(buffer,ctypes.POINTER(TOKEN_PRIVILEGES)).contents
    tp.count = 1
    tp.get_array()[0].enable()
    tp.get_array()[0].LUID = get_symlink_luid()
    token = get_process_token()
    res = AdjustTokenPrivileges(token,false,tp,NonE)
    if res == 0:
        raise RuntimeError("Error in AdjustTokenPrivileges")

    ERROR_NOT_all_ASSIGNED = 1300
    return ctypes.windll.kernel32.GetLastError() != ERROR_NOT_all_ASSIGNED

def main():
    assigned = enable_symlink_privilege()
    msg = ['failure','success'][assigned]

    print("Symlink privilege assignment completed with {0}".format(msg))

if __name__ == '__main__': main()

大佬总结

以上是大佬教程为你收集整理的确定Windows进程是否具有创建符号链接的权限全部内容,希望文章能够帮你解决确定Windows进程是否具有创建符号链接的权限所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。