mirror of https://github.com/n1nj4sec/pupy.git
security: add windows access function, works a bit strange
This commit is contained in:
parent
d8bbe4b6f6
commit
5c4e02baae
|
@ -19,6 +19,8 @@ import psutil
|
|||
import sys
|
||||
import os
|
||||
|
||||
from os import W_OK, X_OK, R_OK
|
||||
|
||||
ntdll = WinDLL('ntdll', use_last_error=True)
|
||||
advapi32 = WinDLL('advapi32', use_last_error=True)
|
||||
shell32 = WinDLL('shell32', use_last_error=True)
|
||||
|
@ -37,6 +39,9 @@ INVALID_HANDLE_VALUE = c_void_p(-1).value
|
|||
LONG = c_long
|
||||
WORD = c_uint16
|
||||
|
||||
INVALID_HANDLE_VALUE = c_void_p(-1).value
|
||||
SECURITY_INFORMATION = DWORD
|
||||
|
||||
PROCESS_QUERY_INFORMATION = 0x0400
|
||||
READ_CONTROL = 0x00020000L
|
||||
STANDARD_RIGHTS_READ = READ_CONTROL
|
||||
|
@ -62,6 +67,49 @@ SE_PRIVILEGE_ENABLED = (0x00000002)
|
|||
SE_PRIVILEGE_REMOVED = (0x00000004)
|
||||
SE_PRIVILEGE_USED_FOR_ACCESS = (0x80000000)
|
||||
|
||||
OWNER_SECURITY_INFORMATION = 0x00000001
|
||||
GROUP_SECURITY_INFORMATION = 0x00000002
|
||||
DACL_SECURITY_INFORMATION = 0x00000004
|
||||
SACL_SECURITY_INFORMATION = 0x00000008
|
||||
|
||||
INVALID_FILE_ATTRIBUTES = -1
|
||||
FILE_ATTRIBUTE_ARCHIVE = 0x20
|
||||
FILE_ATTRIBUTE_COMPRESSED = 0x800
|
||||
FILE_ATTRIBUTE_DEVICE = 0x40
|
||||
FILE_ATTRIBUTE_DIRECTORY = 0x10
|
||||
FILE_ATTRIBUTE_ENCRYPTED = 0x4000
|
||||
FILE_ATTRIBUTE_HIDDEN = 0x02
|
||||
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x8000
|
||||
FILE_ATTRIBUTE_NORMAL = 0x80
|
||||
FILE_ATTRIBUTE_READONLY = 0x1
|
||||
FILE_ATTRIBUTE_SYSTEM = 0x4
|
||||
|
||||
|
||||
FILE_EXECUTE = 0x20
|
||||
FILE_READ_DATA = 0x1
|
||||
FILE_WRITE_DATA = 0x2
|
||||
|
||||
FILE_ADD_FILE = 2
|
||||
FILE_ADD_SUBDIRECTORY = 4
|
||||
FILE_APPEND_DATA = 4
|
||||
FILE_CREATE_PIPE_INSTANCE = 4
|
||||
FILE_DELETE_CHILD = 0x40
|
||||
FILE_LIST_DIRECTORY = 1
|
||||
FILE_READ_ATTRIBUTES = 0x80
|
||||
FILE_READ_EA = 8
|
||||
FILE_TRAVERSE = 0x20
|
||||
FILE_WRITE_ATTRIBUTES = 0x100
|
||||
FILE_WRITE_EA = 0x10
|
||||
|
||||
FILE_ALL_ACCESS = FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | \
|
||||
FILE_APPEND_DATA | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | \
|
||||
FILE_READ_EA | FILE_WRITE_EA
|
||||
|
||||
SecurityAnonymous = 0
|
||||
SecurityIdentification = 1
|
||||
SecurityImpersonation = 2
|
||||
SecurityDelegation = 3
|
||||
|
||||
class TOKEN_INFORMATION_CLASS:
|
||||
#see http://msdn.microsoft.com/en-us/library/aa379626%28VS.85%29.aspx
|
||||
TokenUser = 1
|
||||
|
@ -92,6 +140,16 @@ class TOKEN_USER(Structure):
|
|||
_fields_ = [
|
||||
("User", SID_AND_ATTRIBUTES),]
|
||||
|
||||
ACCESS_MASK = DWORD
|
||||
|
||||
class GENERIC_MAPPING(Structure):
|
||||
_fields_ = [
|
||||
('GenericRead', ACCESS_MASK),
|
||||
('GenericWrite', ACCESS_MASK),
|
||||
('GenericExecute', ACCESS_MASK),
|
||||
('GenericAll', ACCESS_MASK),
|
||||
]
|
||||
|
||||
LookupPrivilegeName = advapi32.LookupPrivilegeNameW
|
||||
LookupPrivilegeName.argtypes = [LPWSTR, POINTER(LUID), LPWSTR, POINTER(DWORD)]
|
||||
LookupPrivilegeName.restype = BOOL
|
||||
|
@ -177,6 +235,26 @@ class STARTUPINFO(Structure):
|
|||
('hStdError', HANDLE),
|
||||
]
|
||||
|
||||
class ACL_HEADER(Structure):
|
||||
_fields_ = [
|
||||
('AclRevision', BYTE),
|
||||
('Sbz1', BYTE),
|
||||
('AclSize', WORD),
|
||||
('AceCount', WORD),
|
||||
('Sbz2', WORD)
|
||||
]
|
||||
|
||||
class SECURITY_DESCRIPTOR(Structure):
|
||||
_fields_ = [
|
||||
('Revision', BYTE),
|
||||
('Sbz1', BYTE),
|
||||
('Control', WORD),
|
||||
('Owner', PSID),
|
||||
('Group', PSID),
|
||||
('Sacl', POINTER(ACL_HEADER)),
|
||||
('Dacl', POINTER(ACL_HEADER)),
|
||||
]
|
||||
|
||||
class SECURITY_ATTRIBUTES(Structure):
|
||||
_fields_ = [
|
||||
("nLength", DWORD),
|
||||
|
@ -201,6 +279,12 @@ class OSVERSIONINFOEXW(Structure):
|
|||
]
|
||||
POSVERSIONINFOEXW = POINTER(OSVERSIONINFOEXW)
|
||||
|
||||
class PRIVILEGE_SET_HEADER(Structure):
|
||||
_fields_ = [
|
||||
('PrivilegeCount', DWORD),
|
||||
('Control', DWORD)
|
||||
]
|
||||
|
||||
# advapi32
|
||||
|
||||
AdjustTokenPrivileges = advapi32.AdjustTokenPrivileges
|
||||
|
@ -227,6 +311,10 @@ DuplicateTokenEx = advapi32.DuplicateTokenEx
|
|||
DuplicateTokenEx.restype = BOOL
|
||||
DuplicateTokenEx.argtypes = [HANDLE, DWORD, PSECURITY_ATTRIBUTES, DWORD, DWORD, POINTER(HANDLE)]
|
||||
|
||||
DuplicateToken = advapi32.DuplicateToken
|
||||
DuplicateToken.restype = BOOL
|
||||
DuplicateToken.argtypes = [HANDLE, DWORD, POINTER(HANDLE)]
|
||||
|
||||
GetTokenInformation = advapi32.GetTokenInformation
|
||||
GetTokenInformation.restype = BOOL
|
||||
GetTokenInformation.argtypes = [HANDLE, DWORD, LPVOID, DWORD, POINTER(DWORD)]
|
||||
|
@ -247,12 +335,41 @@ OpenProcessToken = advapi32.OpenProcessToken
|
|||
OpenProcessToken.restype = BOOL
|
||||
OpenProcessToken.argtypes = [HANDLE, DWORD, POINTER(HANDLE)]
|
||||
|
||||
OpenThreadToken = advapi32.OpenThreadToken
|
||||
OpenThreadToken.restype = BOOL
|
||||
OpenThreadToken.argtypes = [HANDLE, DWORD, BOOL, POINTER(HANDLE)]
|
||||
|
||||
RevertToSelf = advapi32.RevertToSelf
|
||||
RevertToSelf.restype = BOOL
|
||||
RevertToSelf.argtypes = []
|
||||
|
||||
ImpersonateSelf = advapi32.ImpersonateSelf
|
||||
ImpersonateSelf.restype = BOOL
|
||||
ImpersonateSelf.argtypes = [DWORD]
|
||||
|
||||
MapGenericMask = advapi32.MapGenericMask
|
||||
MapGenericMask.argtypes = [POINTER(DWORD), POINTER(GENERIC_MAPPING)]
|
||||
|
||||
GetFileSecurityW = advapi32.GetFileSecurityW
|
||||
GetFileSecurityW.argtypes = [LPWSTR, SECURITY_INFORMATION, c_void_p,
|
||||
DWORD, POINTER(DWORD)]
|
||||
GetFileSecurityW.restype = BOOL
|
||||
|
||||
IsValidSecurityDescriptor = advapi32.IsValidSecurityDescriptor
|
||||
IsValidSecurityDescriptor.argtypes = [c_void_p]
|
||||
GetFileSecurityW.restype = BOOL
|
||||
|
||||
AccessCheck = advapi32.AccessCheck
|
||||
AccessCheck.restype = BOOL
|
||||
AccessCheck.argtypes = [c_void_p, HANDLE, DWORD, POINTER(GENERIC_MAPPING),
|
||||
c_void_p, POINTER(DWORD), POINTER(DWORD), POINTER(BOOL)]
|
||||
|
||||
# kernel32
|
||||
|
||||
GetFileAttributesW = kernel32.GetFileAttributesW
|
||||
GetFileAttributesW.argtypes = [LPWSTR]
|
||||
GetFileAttributesW.restype = DWORD
|
||||
|
||||
CloseHandle = kernel32.CloseHandle
|
||||
CloseHandle.restype = BOOL
|
||||
CloseHandle.argtypes = [HANDLE]
|
||||
|
@ -261,6 +378,10 @@ GetCurrentProcess = kernel32.GetCurrentProcess
|
|||
GetCurrentProcess.restype = HANDLE
|
||||
GetCurrentProcess.argtypes = []
|
||||
|
||||
GetCurrentThread = kernel32.GetCurrentThread
|
||||
GetCurrentThread.restype = HANDLE
|
||||
GetCurrentThread.argtypes = []
|
||||
|
||||
GetCurrentProcessId = kernel32.GetCurrentProcessId
|
||||
GetCurrentProcessId.restype = DWORD
|
||||
GetCurrentProcessId.argtypes = []
|
||||
|
@ -288,12 +409,13 @@ IsUserAnAdmin = shell32.IsUserAnAdmin
|
|||
IsUserAnAdmin.restype = BOOL
|
||||
IsUserAnAdmin.argtypes = []
|
||||
|
||||
ERROR_INSUFFICIENT_BUFFER = 122
|
||||
|
||||
def GetUserName():
|
||||
nSize = DWORD(0)
|
||||
GetUserNameW(None, byref(nSize))
|
||||
error = GetLastError()
|
||||
|
||||
ERROR_INSUFFICIENT_BUFFER = 122
|
||||
if error and error != ERROR_INSUFFICIENT_BUFFER:
|
||||
raise WinError(error)
|
||||
|
||||
|
@ -663,3 +785,101 @@ def get_windows_version():
|
|||
'minor_version': os_version.dwMinorVersion.real,
|
||||
'build_number': os_version.dwBuildNumber.real
|
||||
}
|
||||
|
||||
def access(path, mode):
|
||||
requested_information = OWNER_SECURITY_INFORMATION | \
|
||||
GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
|
||||
|
||||
dwSize = DWORD(0)
|
||||
hToken = HANDLE()
|
||||
access_desired = 0
|
||||
|
||||
if type(path) == str:
|
||||
path = path.decode(sys.getfilesystemencoding())
|
||||
|
||||
attributes = GetFileAttributesW(path)
|
||||
|
||||
if attributes == INVALID_FILE_ATTRIBUTES:
|
||||
return False
|
||||
|
||||
if mode == os.F_OK:
|
||||
return True
|
||||
|
||||
if (mode & W_OK) and (attributes & FILE_ATTRIBUTE_READONLY) and \
|
||||
not (attributes & FILE_ATTRIBUTE_DIRECTORY):
|
||||
return False
|
||||
|
||||
success = GetFileSecurityW(path, requested_information,
|
||||
c_void_p(0), 0, byref(dwSize))
|
||||
|
||||
if not success and get_last_error() != ERROR_INSUFFICIENT_BUFFER:
|
||||
return False
|
||||
|
||||
pSDBuf = create_string_buffer(dwSize.value)
|
||||
can_read_access = GetFileSecurityW(
|
||||
path, requested_information, pSDBuf,
|
||||
dwSize, byref(dwSize))
|
||||
|
||||
if not can_read_access:
|
||||
return False
|
||||
|
||||
if not IsValidSecurityDescriptor(pSDBuf):
|
||||
return False
|
||||
|
||||
is_access_granted = False
|
||||
|
||||
if not OpenProcessToken(
|
||||
GetCurrentProcess(),
|
||||
TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ,
|
||||
byref(hToken)):
|
||||
|
||||
return False
|
||||
|
||||
hImpersonatedToken = HANDLE()
|
||||
if not DuplicateToken(hToken, SecurityImpersonation, byref(hImpersonatedToken)):
|
||||
CloseHandle(hToken)
|
||||
return False
|
||||
|
||||
access_desired = 0
|
||||
|
||||
mapping = GENERIC_MAPPING()
|
||||
|
||||
if (mode & X_OK):
|
||||
access_desired |= FILE_EXECUTE
|
||||
if (mode & R_OK):
|
||||
access_desired |= FILE_READ_DATA
|
||||
if (mode & W_OK):
|
||||
access_desired |= FILE_WRITE_DATA
|
||||
|
||||
mapping.GenericRead = FILE_READ_DATA
|
||||
mapping.GenericWrite = FILE_WRITE_DATA
|
||||
mapping.GenericExecute = FILE_EXECUTE
|
||||
mapping.GenericAll = FILE_ALL_ACCESS
|
||||
|
||||
access_desired = DWORD(access_desired)
|
||||
|
||||
MapGenericMask(byref(access_desired), byref(mapping))
|
||||
|
||||
ps = PRIVILEGE_SET_HEADER()
|
||||
pps = byref(ps)
|
||||
pps_size = DWORD(sizeof(ps))
|
||||
access_granted = DWORD(0)
|
||||
is_access_granted_bool = BOOL(False)
|
||||
|
||||
if not AccessCheck(
|
||||
pSDBuf, hImpersonatedToken, access_desired, byref(mapping), pps,
|
||||
byref(pps_size), byref(access_granted), byref(is_access_granted_bool)):
|
||||
|
||||
if get_last_error() == ERROR_INSUFFICIENT_BUFFER:
|
||||
pps = create_string_buffer(pps_size.value)
|
||||
|
||||
AccessCheck(
|
||||
pSDBuf, hImpersonatedToken, access_desired, byref(mapping), pps,
|
||||
byref(pps_size), byref(access_granted), byref(is_access_granted_bool))
|
||||
|
||||
is_access_granted = bool(is_access_granted_bool)
|
||||
|
||||
CloseHandle(hImpersonatedToken)
|
||||
CloseHandle(hToken)
|
||||
|
||||
return is_access_granted
|
||||
|
|
Loading…
Reference in New Issue