windows下获取logon session信息

 
古城
@ 2009.03.19
分类:技术笔记
点击:1934  评论:0
 
 
 
    什么是LSA?什么是session?MSDN中的描述如下:

Local Security Authority

    (LSA) A protected subsystem that authenticates and logs users onto the local system. LSA also maintains information about all aspects of local security on a system, collectively known as the Local Security Policy of the system.

logon session

    A logon session begins whenever a user logs on to a computer. All processes in a logon session have the same primary access token. The access token contains information about the security context of the logon session, including the user's SID, the logon identifier, and the logon SID.

    当用户登陆计算机时,一个对应的logon session就开始了。一个logon session可以拥有多个进程,计算机上运行着的所有进程都属于一个唯一的session。怎么获取这些session和进程的相关信息呢?

    LsaEnumerateLogonSessions函数可以获取已经存在的logon session identifiers (LUIDs) 和session的总数。

  NTSTATUS NTAPI LsaEnumerateLogonSessions(
      PULONG LogonSessionCount,
      PLUID* LogonSessionList

  );

    当LogonSessionList不再需要时,需要调用LSAFreeReturnBuffer函数来释放所占用的内存。

    看看刚才获取的LogonSessionList,数据类型为LUID。

  typedef struct _LUID {
      DWORD LowPart;
      LONG HighPart;
  } LUID, *PLUID;

    为了通过LUID来获取详细的logon session信息,需要调用函数LsaGetLogonSessionData,调用者必须是拥有该session或者是本地的系统管理员。

  NTSTATUS NTAPI LsaGetLogonSessionData(
      PLUID LogonId,
      PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData
  );

      LsaGetLogonSessionData函数返回一个PSECURITY_LOGON_SESSION_DATA结构体。

  typedef struct _SECURITY_LOGON_SESSION_DATA {
      ULONG Size;
      LUID LogonId;
      LSA_UNICODE_STRING  UserName;
      LSA_UNICODE_STRING  LogonDomain;
      LSA_UNICODE_STRING  AuthenticationPackage;
      ULONG LogonType;
      ULONG Session;
      PSID Sid;
      LARGE_INTEGER LogonTime;
      LSA_UNICODE_STRING  LogonServer;
      LSA_UNICODE_STRING  DnsDomainName;
      LSA_UNICODE_STRING Upn;
  } SECURITY_LOGON_SESSION_DATA, *PSECURITY_LOGON_SESSION_DATA;

    其中包含了登陆标识(LogonId)、登陆的账号(UserName)、域(LogonDomain)、认证方式(AuthenticationPackage)、登陆类型(LogonType)、会话ID(Session)、用户的Sid(Sid)、用户登陆时间(LogonTime)等信息。

    登陆类型(LogonType)是个枚举类型。

  typedef enum _SECURITY_LOGON_TYPE {
      Interactive = 2,    // Interactively logged on (locally or remotely)
      Network,            // Accessing system via network
      Batch,              // Started via a batch queue
      Service,            // Service started by service  controller
      Proxy,              // Proxy logon
      Unlock,             // Unlock workstation
      NetworkCleartext,   // Network logon with cleartext credentials
      NewCredentials,     // Clone caller, new default credentials
      RemoteInteractive,  // Remote, yet interactive. Terminal server
      CachedInteractive,  // Try cached credentials without hitting the  net.
      CachedRemoteInteractive, // Same as RemoteInteractive, this is used internally for auditing purpose
      CachedUnlock        // Cached Unlock workstation
  } SECURITY_LOGON_TYPE, *PSECURITY_LOGON_TYPE;

    用户的Sid(Sid)可以用ConvertSidToStringSid来转换成常见的SID格式字符串。

  BOOL ConvertSidToStringSid(
      PSID Sid,
      LPTSTR* StringSid
  );

    这样,所有logon session的信息就获取到了。

    更进一步的,用EnumProcesses函数枚举进程ID,OpenProcess获取每一个进程的句柄。在分别通过OpenProcessToken和GetTokenInformation打开并获取进程的访问令牌信息。

  BOOL OpenProcessToken(
      HANDLE ProcessHandle,
      DWORD DesiredAccess,
      PHANDLE TokenHandle

  );

  BOOL GetTokenInformation(
      HANDLE TokenHandle,
      TOKEN_INFORMATION_CLASS  TokenInformationClass,
      LPVOID TokenInformation,
      DWORD  TokenInformationLength,
      PDWORD ReturnLength
  );

    TokenInformationClass是个枚举类型,用来指明要获取的信息类型,这里用TokenStatistics即可。获取的信息在TokenInformation中,数据类型为TOKEN_STATISTICS的结构体。

  typedef struct _TOKEN_STATISTICS {
      LUID TokenId;
      LUID AuthenticationId;
      LARGE_INTEGER  ExpirationTime;
      TOKEN_TYPE TokenType;
      SECURITY_IMPERSONATION_LEVEL  ImpersonationLevel;
      DWORD DynamicCharged;
      DWORD DynamicAvailable;
      DWORD GroupCount;
      DWORD PrivilegeCount;
      LUID ModifiedId;
  } TOKEN_STATISTICS, *PTOKEN_STATISTICS;

    其中LUID AuthenticationId如果和前面logon session的LUID一致,说明该进程的拥有者是相应的logon session。

    通过类似的方法,能获取很多有用的信息。下面的程序是用这些API写的一个windows下获取logon session信息,并列举属于该session的进程。

    下载地址:
    http://www.thatsky.cn/upfile/SessionViewer.rar

    > 点这里下载 <
 
 
 
 
 

本文评论

 
 

发表评论

你的评论
← 填你的昵称
以下内容非必填,可根据需要填写
← 可以展示在你的评论上方
← 不会在页面展示
← 不会在页面展示
← 只给我看?勾选上
这是一个别人称之为角落的世界
幸而,它的确是我的世界