Windows NT Session 概念的原理与应用浅析 [1] 遍历并获取信息

2023-11-06

转载自: http://www.cnblogs.com/flier/archive/2004/07/19/25709.html

 

我在上一篇文章《DACL, NULL or not NULL》中曾简要地介绍了 Windows 系统中 Session 的概念,并且通过一个自己编写的小工具 KeSession 列出当前系统 Session 信息。本文中我将就遍历并获取当前系统 Session 信息的方法进行详细分析,并借此机会让大家能够从 Session 的角度对 WinNT 底层帐号和权限管理机制有更深入的了解。因为文章是以随笔方式写的,可能在内容上有所遗漏,希望大家补充和指正。
    虽然 Session 的概念非常重要,但因为其过于底层,除了处理用户登陆和安全相关事务的程序员,它对高层开发基本上是透明的。故而这方面的介绍文章和工具实在不多。
    而要学习研究 Session,必要的文章和工具肯定是必不可少的,首推就是 www.sysinternals.com 提供的LoggonSessions。这个小工具能够将当前系统所有正在使用的 Session 以及相关信息列举出来,加上 -p 参数还可以进一步列出 Session 包括的进程列表。大概因为www.sysinternals.com 的牛人认为程序太简单,就没有给出源码,呵呵,待会我们来看看如何自己实现一个功能完全相同的 KeSession 工具。
    此外 Keith Brown 的 Handle Logons in Windows NT and Windows 2000 with Your Own Logon Session Broker 一文,以及文章所附源码工具 cmdasuser 也是必不可少的。此工具能够以指定用户身份,建立新的 Session,并载入用户配置和环境,创建一个完整的 Session 试验环境
    最后就是 Jeffrey Richter 和 Jason Clark 在 Programming Server-Side Applications for Microsoft Windows 一书的第11章 User Context 中,提供的非常强大的令牌管理工具,Token Master,可以查看当前系统任意进程、线程的令牌 (Token)。
    LoggonSessions 程序的功能实际上很容易实现,通过调用本机安全授权服务 (LSASS) 提供的 LsaEnumerateLogonSessions 函数枚举当前登陆会话,对每个会话调用 LsaGetLogonSessionData函数获取进一步的会话信息。

NTSTATUS NTAPI LsaEnumerateLogonSessions(
  PULONG LogonSessionCount,
  PLUID* LogonSessionList
);

NTSTATUS LsaFreeReturnBuffer(
  PVOID Buffer
);


LsaEnumerateLogonSessions 函数使用非常简单,直接返回会话数量和保存每个会话ID的数组。此数组每个元素是一个 LUID 类型,实际上就是一个 64bit 整数,使用完后通过 LSAFreeReturnBuffer 函数释放缓冲区。

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

对每个会话的 LUID,可以调用 LsaGetLogonSessionData 函数获取进一步的信息。此函数将返回一个保存会话信息的结构,使用完后通过 LSAFreeReturnBuffer 函数释放缓冲区。

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;

SECURITY_LOGON_SESSION_DATA 结构保存的会话数据包括:

    Size 保存此结构的大小,为兼容以后大小变化提供的可变数据模式

    LogonId 保存此 Session 的 LUID 内部编号,用户全局定位,如计算机登陆的 SYSTEM帐号的 LogonId 999(0x3e7)

    UserName 和 LogonDomain 保存此 Session 的登陆帐号和域,以 LogonDomain\UserName 组合后就是完整帐号名,如 SKY\FLIER$ 或 FLIER\Administrator

    AuthenticationPackage 保存此 Session 的认证方式。一般来说本机都是 NTLM,网络会话是 Negotiate

    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.

} SECURITY_LOGON_TYPE, *PSECURITY_LOGON_TYPE;

 


更为完整的登陆类型列表在 LogonUserEx 函数的参数介绍中可以看到。

    交互式(Interactive)登陆就是用户通过计算机控制台以物理方式登陆到系统的会话;
    网络(Network)登陆则是通过网络邻居等方式远程访问此计算机时的会话;
    批处理(Batch)登陆一般在使用批处理队列时使用,如 COM SCM
    服务(Service)登陆则适用于后台服务以系统帐号运行,如 System SCM

    以上四种登陆类型是最为常见的,而附加的登陆类型适用于特殊情况

    代理(Proxy)登陆基本上很少被用到,MSDN里面干脆说此类型不被支持
    解锁(Unlock)登陆是当用户锁屏后,GINALogonUser函数配合进行解锁时用到
    网络明文(NetworkCleartext)登陆允许用户在通过 LogonUserEx 登陆到系统后,用户名和密码被保存以再次登陆到其他服务器
    新凭证(NewCredentials)登陆允许用户对本地访问使用克隆的当前令牌,当对外部网络连接使用单独的凭证
    远程交互(RemoteInteractive)登陆是终端服务连接到服务器时使用的登陆方式,允许与交互登陆类似的桌面操作,当无需在本地进行
    缓存交互(CachedInteractive)登陆则对用户的凭证进行缓存,避免冗余网络验证等等

    登陆类型直接决定了此会话的能力以及所受限制,后面有机会再分别解析。

    Session 字段保存了一个显式会话编号。此编号一般是用户终端服务器,本地会话和交互登陆会话此编号都为 0,而远程交互登陆则能够获取新的编号。系统通过此编号,在对象管理器中,将 \BaseNamedObjects 映射到 \Sessions\1\ 等等名字空间中,有兴趣的朋友可以进一步参考 NT 对象管理器相关文章。

    Sid 字段保存了此会话登陆帐号的 Sid,与前面的登陆名对应;

    LogonTime 则是一个非本地时区的 FILETIME 格式的时间,表示会话开始时间

    最后的 LogonServer、DnsDomainName 和 Upn 则一般在使用活动目录时,提供帐号的进一步信息。

    在了解这些信息后,很容易就能写出一个遍历登陆会话信息的程序来,MSDN 中也提供了遍历和信息获取的两个例子。例如:

void __fastcall TSessionManager::Refresh(void)

{

  LsaData<PLUID> sessions;

  ULONG count = 0;

 

  m_sessions.clear();

 

  Win32Check(STATUS_SUCCESS == LsaEnumerateLogonSessions(&count, &sessions));

 

  for(int i=0; i<(int)count; i++)

  {

    LsaData<PSECURITY_LOGON_SESSION_DATA> data;

 

    Win32Check(STATUS_SUCCESS == LsaGetLogonSessionData(&sessions[i], &data));

 

    if(data) m_sessions.push_front(TKernelSession(data));

  }

}

值得注意的是如何将进程和 Session关联起来。这需要使用 NTDLL::ZwQuerySystemInformation 或 PSAPI::EnumProcesses 遍历系统进程,对每个进程获取其令牌,并使用GetTokenInformation 函数从令牌中获取统计信息 TokenStatistics,其中TOKEN_STATISTICS::AuthenticationId 就是此令牌所在 Session ID

const LUID __fastcall TSystemProcess::GetLogonID(void) const

{

  if(FID == 0 || FID == 4) return LUID();

 

  TSystemHandle hProc = ::OpenProcess(MAXIMUM_ALLOWED, FALSE, FID);

 

  if(!hProc.valid()) return LUID();

 

  TSystemHandle hToken;

 

  if(!::OpenProcessToken(hProc, TOKEN_QUERY, &hToken)) return LUID();

 

  TOKEN_STATISTICS stat;

  DWORD dwSize = 0;

 

  Win32Check(::GetTokenInformation(hToken, TokenStatistics, &stat, sizeof(stat), &dwSize));

 

  return stat.AuthenticationId;

}

另外一个值得注意的是如何获取 Session 的 SID。每个 Session 在启动时,系统会自动为其注册一个 SID,便于对 WinStation 等对象进行权限控制。因为一个 WinStation是可以由多个 Session公用的,但又存在一个相同帐号的多个 Session可能对此 WinStation访问权限不同的情况。所以系统为每个 Session建立一个全局唯一的 SID,以使 WinStation等用户对象的控制粒度,能够细到针对每个 Session,哪怕这些 Session使用相同的登陆帐号
    使用 www.sysinternals.com 提供的Process Explorer 工具,查看 winlogon.exe 进程打开的 WinStation 对象,可以发现除了普通的 Administrator 和 SYSTEM 等帐号外,还会有一个 S-1-5-5-xxx-yyy 的 ACE。这个 S-1-5-5 开头的就是 Session 的 SID,而 xxx-yyy 一般是 Session 的编号。
    此 SID 可以通过在此 Session 中的任意进程令牌获取。每个令牌可以有多个组 SID,而其中会有一个 Group SID 的类型属性包括 SE_GROUP_LOGON_ID 标志,这个就是此令牌所属 Session 的 SID,通过此 SID 可以将对权限的控制在 Session 这个粒度进行。可以通过 TokenMaster 工具查看令牌的此 Group SID。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows NT Session 概念的原理与应用浅析 [1] 遍历并获取信息 的相关文章

  • 在 Jenkins 中执行批处理文件

    我有一个简单的批处理文件 我想要从 Jenkins 调用 运行 执行该文件 Jenkins 中有同样的插件吗 如何从 Jenkins 执行批处理文件 如果有相同的教程或文档 无需为此添加新插件 在Jenkins 选择您的工作名称并转到配置部
  • 为什么我的文件路径中出现 Unicode 转义的语法错误? [复制]

    这个问题在这里已经有答案了 我想要访问的文件夹名为 python 位于我的桌面上 当我尝试访问它时出现以下错误 gt gt gt os chdir C Users expoperialed Desktop Python SyntaxErro
  • 如何通过 DOS 批处理命令发送电子邮件?

    我在 DOS 中有一个批处理文件 可以进行一些检查 完成后我需要发送一封电子邮件 我在 interwebz 上找到了一些解决方案 但大多数都是第三方的 或者只是在 Outlook 中打开新邮件 我需要命令来发送完整的电子邮件 而无需任何人工
  • Python 可执行文件:py2exe 还是 PyInstaller?

    要创建可执行文件 Windows 我假设我们应该使用其中之一 Py2exe 或 PyInstaller 它们之间有什么区别 Py2exe 和 PyInstaller 都是包装器 但我注意到以下几点差异 Py2exe 与 python2 4
  • Rails 渲染 JSON - 会话丢失?

    我正在尝试对控制器进行一些 Ajax 调用 该控制器以 JSON 进行响应 if session user render json gt Some Data else render json gt You are not logged in
  • 场次抽奖

    有人能解释一下什么是会话扫彩票吗 我已附加 Laravel 框架的默认会话配置文件 问题 1 它说某些会话驱动程序必须manually扫荡他们的 存储位置 有人可以描述这个过程以及为什么会这样吗 必要的 哪些会话驱动程序需要此操作 2 为什
  • 如何让 git 和 copSSH 在正确的目录中查找密钥?

    我刚刚安装了 Windows 版 copSSH 当我启动它时 我得到一个目录C copSSH home Nick ssh其中有我的酒吧和私钥 当我通过 Cygwin bash 窗口访问此目录时 使用 ssh 用户 主机 我很高兴地登录了 但
  • 批处理文件 FOR /f 标记

    任何人都可以逐行准确解释以下代码是如何工作的 我真的迷路了 我一直在尝试学习如何使用 FOR 命令 但我不明白这一点 echo off for f tokens delims f in myfile do set line f call p
  • 如何更改选项卡控件的名称

    我在 C WinForms 应用程序中使用选项卡控件 我想更改选项卡的标题 默认情况下它们是 tabPage1 tabPage2 等 一种无需代码即可实现的懒惰方法 选择选项卡控件 Go to properties use F4 to do
  • Django 的登录会话

    我正在尝试在我的网络应用程序中设置登录会话 但无法使其正常工作 我是 django 新手 阅读了会话文档 但没有连接到我的网络应用程序 我现在想要的只是检查用户是否已登录 如果没有则重定向到登录页面 这是我尝试合并登录会话的代码 设置 py
  • Windows 上的 Openssl 错误 0x02001005 和 0x2006D002?

    我正在尝试使用 openssl 将 cer 证书转换为 p12 证书 这是我正在使用的命令 C OpenSSL Win32 bin gt openssl x509 inform der in developer identity cer o
  • python+win32:检测窗口拖动

    有没有办法检测何时使用 python pywin32 在窗口中拖动不属于我的应用程序的窗口 我想对其进行设置 以便当我拖动标题与桌面边缘附近的图案匹配的窗口时 当松开鼠标时它会捕捉到边缘 我可以编写代码 以便在释放鼠标时将所有具有该标题的窗
  • 在 servlet 会话和 java.io.NotSerializedException 中保存对象

    SEVERE IOException while loading persisted sessions java io WriteAbortedException writing aborted java io NotSerializabl
  • Qt(在 Windows 上)将权限级别设置为“requireAdministrator”

    我正在使用 Qt Creator 并努力制作 exe文件默认以管理员身份运行 在线阅读所有解决方案我试图将这一行放入我的 pro file QMAKE LFLAGS MANIFESTUAC level requireAdministrato
  • 以编程方式从 java 代码中查找 java.exe 的绝对路径

    如果我有一个由用户启动的 java jar 或类文件 假设在环境变量中设置了 java 路径 那么我如何从代码中找出 java exe javaw exe 的绝对路径文件正在启动 就像在 ubuntu 上一样 我们可以运行 which ja
  • 如何在Windows上模拟socket.socketpair

    标准Python函数套接字 套接字对 https docs python org 3 library socket html socket socketpair不幸的是 它在 Windows 上不可用 从 Python 3 4 1 开始 我
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • 将 CrashDumps 转储到应用程序运行所在的同一文件夹中

    我编写了一个应用程序 我希望对其进行一定程度的自动调试 我想使用 Windows 错误报告将故障转储输出到应用程序运行所在的同一文件夹中 我的想法是 我可以让我的应用程序在它自己的文件夹中查找任何 dmp 文件 然后根据需要上传它们进行分析
  • 使用会话 php 创建 cookie?

    我使用会话来登录我网站中的用户 问题是 我想让用户remember密码 因此关闭 打开浏览器后他们不需要再次登录 我需要使用 cookie 和 session 来实现它吗 my code user POST user pass POST p
  • teracopy 如何替换默认的 Windows 副本

    我问了这个问题Windows 文件复制内部结构 动态加密 https stackoverflow com questions 24220382 windows file copy internals on the fly encryptio

随机推荐

  • python 计算置信区间,计算置信区间(示例代码)

    proc freq data datain by group tables var missprint nowarn binomial level 1 cl exact alpha 0 05 weight n zero 对发生的做置信区间
  • C语言数据结构之链表的增删改查

    C语言数据结构之链表的增删改查 tips 昨天学习了c语言结构体 今天来看看c语言数据结构之链表 单链表 的增删改查操作 首先我们创建一个简单的学生信息结构体 作为后面增删改查的主体 student结构体包含 数据域 学号 分数 指针域 一
  • jupyter报错

    1 打开anaconda jupyter notebook时报错 Traceback most recent call last File E python anaconda Scripts jupyter notebook script
  • 分页存储管理,分段存储管理,段页式存储管理

    概括的挺详细的 然后我加上了纯分页系统和请求式分页系统的基本概念 也对有些部分稍作修改 一 分页存储管理 1 基本概念 页面和物理块 将一个进程的逻辑地址空间划分成若干大小相等的部分 每一部分称为页或页面 页面的大小通常是2的次幂 大约在5
  • 区块链:Solidity值类型(地址Address)

    地址Address 以太坊钱包地址位数验证 以太坊中的地址的长度为20字节 一字节等于8位 一共160位 所以address其实亦可以用uint160来声明 我的以太坊钱包地址为0xDF12793CA392ff748adF013D146f8
  • 可变个数的参数

    1 用数组的方式来 例如 pulic void print String args for int i 0 i
  • Apache POI 4.1.0 发布,Office 文档的 Java API

    Apache POI 4 1 0 发布了 Apache POI 是用 Java 编写的开源跨平台的 Java API 提供 API 给 Java 程式对 Microsoft Office 格式档案读和写的功能 简而言之 你可以使用 Java
  • CSDN高校俱乐部第三届研讨会

    CSDN高校俱乐部第三届研讨会 于2013年6月6日在国家会议中心成功举办 感谢大家从全国各地远道而来参加 本次研讨会邀请了来自全国32所高校俱乐部的指导老师 同学以及优秀巡讲讲师和微软Imagine Cup 2013大赛负责人 会议开始先
  • 【MySQL高级篇笔记-数据库的设计规范(中) 】

    此笔记为尚硅谷MySQL高级篇部分内容 目录 一 为什么要数据库设计 二 范式 1 范式简介 2 范式都包括哪些 3 键和相关属性的概念 4 第一范式 1st NF 5 第二范式 2nd NF 6 第三范式 3rd NF 7 小结 三 反范
  • Flutter内存优化总结

    Flutter内存优化是一个非常复杂的问题 其中涉及多个方面的优化策略 下面将从以下几个方面对Flutter的内存优化进行具体实现的总结 一 减少Widget的创建和销毁 Widget的创建和销毁是Flutter中内存占用最大和最频繁的操作
  • C++学习笔记黑马程序员(有一些自己的思考)

    学习目标 掌握 C 入门知识 C 核心编程 掌握 STL 洛谷算法训练题 学习内容 C 入门知识 一 基本介绍 C 不同于C语言 这是一门面向对象的高级程序设计语言 二 面向对象与面向过程 什么是面向对象 对象又是什么 对象是对客观事物的抽
  • Flink_04_Watermark(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 时间语义 EventTime 在1 12版本中被设置成了默认 是事件
  • 求平方根问题 (C++ 实现)

    下面是用二分法和牛顿迭代法求一个正数的平方根 二分法 这里的题目稍微宽了一点点 包含了整数和小数的情况 这里二分法就不用多说了 如果中间值的平方与目标值在误差范围内 则返回 否则根据大小情况改变左 右区间的端点 include
  • 每日一题:选数

    选数 题目 Daimayuan Online Judge 原本我的思路是 大致题意就是从n个数中选取若干数 使得它们的和mod n等于0 任意选取 无关顺序 是可以跳着选的 也就是对于每一个数 有两种选择 选与不选 于是我想用01背包 但是
  • linux屏保默认图片,分享

    Ubuntu 4 10 Warty Warthog Ubuntu 5 04 Hoary Hedgehog Ubuntu 5 10 Breezy Badger Ubuntu 6 06 Dapper Drake Ubuntu 6 10 Edgy
  • 多个chatgpt模型

    GPT4All 简介 GPT4AllNomic AI Team 从 Alpaca 获得灵感 使用 GPT 3 5 Turbo OpenAI API 收集了大约 800 000 个提示 响应对 创建了 430 000 个助手式提示和生成训练对
  • SQL中in和not in遇到NULL值的查询情况

    首先 大家可以先试着做这道练习题 题目 给定一个表 T id 是树节点的编号 pid 是它父节点的 id 树中每个节点属于以下三种类型之一 叶子 如果这个节点没有任何孩子节点 根 如果这个节点是整棵树的根 即没有父节点 内部节点 如果这个节
  • 最简单的引入Vue看板娘教程

    最简单的引入Vue看板娘教程 一 项目引入 这里使用的是来自Evgo老哥的 vue live2d 使用简单 直接引入就好 具体的可以看老哥的文档 二 简单实现 在你的项目引入 npm install vue live2d 接着在想要引入看板
  • Unity3D关于iTween知识详解和接口总结

    目录 1 简介 2 物体移动方法 3 物体的颜色变化 4 摄像机淡入淡出 5 音频方法 6 Look类方法 7 旋转方法 8 物体大小缩放 9 晃动效果方法 10 值方法 11 外部工具方法 12 iTweenPath 1 简介 iTwee
  • Windows NT Session 概念的原理与应用浅析 [1] 遍历并获取信息

    转载自 http www cnblogs com flier archive 2004 07 19 25709 html 我在上一篇文章 DACL NULL or not NULL 中曾简要地介绍了 Windows 系统中 Session