PoshCode Logo PowerShell Code Repository

Add-Type extends by Ernst Schlee 4 months ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/6654"></script>download | new post

Arise you ever a wish to call CPython code via Add-Type cmdlets? Now you have this ability! Note that you need “morphine” library (https://github.com/gregzakh/morphine/blob/master/lib/morphine.ps1) and Python stored into $env:path

  1. function Get-LogonSessions {
  2.   Set-Content function:Add-Type (Unlock-Python)
  3. Add-Type -Language Python -TypeDefinition @'
  4. from calendar import timegm
  5. from ctypes   import (
  6.   POINTER, Structure, byref, cast, c_long, c_ulong, c_longlong,
  7.   c_ushort, c_void_p, c_wchar_p, sizeof, windll
  8. )
  9. from datetime import datetime, timedelta
  10. from enum     import IntEnum
  11. from sys      import exit
  12.  
  13. SECURITY_LOGON_TYPE = IntEnum('SECURITY_LOGON_TYPE', ' \
  14.    Unknown Interactive Network Batch Service Proxy Unlock \
  15.    NetworkCleartext NewCredentials RemoteInteractive \
  16.    CachedInteractive CachedRemoteInteractive CachedUnlock \
  17. ')
  18.  
  19. class LUID(Structure):
  20.   _fields_ = [
  21.      ('LowPart',  c_ulong),
  22.      ('HighPart', c_long),
  23.   ]
  24.  
  25. class LSA_UNICODE_STRING(Structure):
  26.   _fields_ = [
  27.      ('Length',        c_ushort),
  28.      ('MaximumLength', c_ushort),
  29.      ('Buffer',        c_wchar_p),
  30.   ]
  31.  
  32. class LSA_LAST_INTER_LOGON_INFO(Structure):
  33.   _fields_ = [
  34.      ('LastSuccessfulLogon',                        c_longlong),
  35.      ('LastFailedLogon',                            c_longlong),
  36.      ('FailedAttemptCountSinceLastSuccessfulLogon', c_ulong),
  37.   ]
  38.  
  39. class SECURITY_LOGON_SESSION_DATA(Structure):
  40.   _fields_ = [
  41.      ('Size',                  c_ulong),
  42.      ('LogonId',               LUID),
  43.      ('UserName',              LSA_UNICODE_STRING),
  44.      ('LogonDomain',           LSA_UNICODE_STRING),
  45.      ('AuthenticationPackage', LSA_UNICODE_STRING),
  46.      ('_LogonType',            c_ulong),
  47.      ('Session',               c_ulong),
  48.      ('_Sid',                  c_void_p),
  49.      ('_LogonTime',            c_longlong),
  50.      ('LogonServer',           LSA_UNICODE_STRING),
  51.      ('DnsDomainName',         LSA_UNICODE_STRING),
  52.      ('Upn',                   LSA_UNICODE_STRING),
  53.      ('UserFlags',             c_ulong),
  54.      ('LastLogonInfo',         LSA_LAST_INTER_LOGON_INFO),
  55.      ('LogonScript',           LSA_UNICODE_STRING),
  56.      ('ProfilePath',           LSA_UNICODE_STRING),
  57.      ('HomeDirectory',         LSA_UNICODE_STRING),
  58.      ('HomeDirectoryDrive',    LSA_UNICODE_STRING),
  59.      ('LogoffTime',            c_longlong),
  60.      ('KickOffTime',           c_longlong),
  61.      ('PasswordLastSet',       c_longlong),
  62.      ('PasswordCanChange',     c_longlong),
  63.      ('PasswordMustChange',    c_longlong),
  64.   ]
  65.   @property
  66.   def LogonType(self):
  67.      return SECURITY_LOGON_TYPE(self._LogonType).name if self._LogonType else None
  68.   @property
  69.   def Sid(self):
  70.      ptr = c_wchar_p()
  71.      if windll.advapi32.ConvertSidToStringSidW(self._Sid, byref(ptr)):
  72.         sid = ptr.value
  73.         windll.kernel32.LocalFree(ptr)
  74.         return sid
  75.   @property
  76.   def LogonTime(self):
  77.      lt = datetime(1601, 1, 1) + timedelta(microseconds=self._LogonTime / 10)
  78.      return datetime.fromtimestamp(timegm(lt.timetuple()))
  79.  
  80. def printlsaerror(nts):
  81.   msg = c_void_p()
  82.   windll.kernel32.FormatMessageW(
  83.      0x00001100, None, windll.advapi32.LsaNtStatusToWinError(nts),
  84.      1024, byref(msg), 0, None
  85.   )
  86.   err = c_wchar_p(msg.value).value
  87.   windll.kernel32.LocalFree(msg)
  88.   print(err.strip() if err else 'Unknown error has been occured.')
  89.  
  90. if __name__ == '__main__':
  91.   cnt, lsl = c_ulong(), c_void_p()
  92.   nts = windll.secur32.LsaEnumerateLogonSessions(byref(cnt), byref(lsl))
  93.   if nts:
  94.      printlsaerror(nts)
  95.      exit(1)
  96.   itr = c_void_p(lsl.value)
  97.   for i in range(0, cnt.value):
  98.      lsd = c_void_p()
  99.      nts = windll.secur32.LsaGetLogonSessionData(itr, byref(lsd))
  100.      if nts:
  101.         printlsaerror(nts)
  102.         break
  103.      slsd = cast(lsd, POINTER(SECURITY_LOGON_SESSION_DATA)).contents
  104.      print('Logon type   : %s' % slsd.LogonType)
  105.      print('User name    : %s\\%s' % (slsd.LogonServer.Buffer, slsd.UserName.Buffer))
  106.      print('Auth package : %s' % slsd.AuthenticationPackage.Buffer)
  107.      print('Session      : %u' % slsd.Session)
  108.      print('Sid          : %s' % slsd.Sid)
  109.      print('Logon time   : %s\n' % slsd.LogonTime)
  110.      itr = c_void_p(itr.value + sizeof(LUID))
  111.      windll.secur32.LsaFreeReturnBuffer(lsd)
  112.   windll.secur32.LsaFreeReturnBuffer(lsl)
  113. '@
  114. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me