windows 访问控制模型(一)
来源:互联网 发布:windows vista32位下载 编辑:程序博客网 时间:2024/05/18 01:36
最近研究了下windows的访问控制模型,于是想写篇博客加深下印象。有些内容直接转子互联网(已标记)
下面内容转自:
***************************************************************************************************
标 题: 【原创】白话windows之 访问控制模型(Access Control Model)
作 者: ddlx
时 间: 2013-06-10,21:38:41
链 接: http://bbs.pediy.com/showthread.php?t=173381
***********************************************************************************
当一个线程使用Open*打开一个内核对象时,会发生什么?
有两种可能:
1. 打开成功,拿到句柄
2. 打开失败
这不是废话么?!为啥打开失败呢?有两种可能:
1. 当前线程不具有指定的特权
2. 权限不足(由dwDesiredAccess参数指定权限)
这个时候就引入了今天的主题:令牌(包含特权列表)和安全描述符(描述用户权限)。
Token
token是什么?对了,他就是一个令牌。就像原先钦差大臣手里面的上方宝剑一样,上可惩天子,下可斩贪官!所以千万不要小看它哦亲~。那Token中都有些神马东东呢?
先看一下他的数据结构:
代码:
lkd> dt nt!_token +0x000 TokenSource : _TOKEN_SOURCE +0x010 TokenId : _LUID +0x018 AuthenticationId : _LUID +0x020 ParentTokenId : _LUID +0x028 ExpirationTime : _LARGE_INTEGER +0x030 TokenLock : Ptr32 _ERESOURCE +0x038 AuditPolicy : _SEP_AUDIT_POLICY +0x040 ModifiedId : _LUID +0x048 SessionId : Uint4B +0x04c UserAndGroupCount : Uint4B +0x050 RestrictedSidCount : Uint4B +0x054 PrivilegeCount : Uint4B +0x058 VariableLength : Uint4B +0x05c DynamicCharged : Uint4B +0x060 DynamicAvailable : Uint4B +0x064 DefaultOwnerIndex : Uint4B +0x068 UserAndGroups : Ptr32 _SID_AND_ATTRIBUTES +0x06c RestrictedSids : Ptr32 _SID_AND_ATTRIBUTES +0x070 PrimaryGroup : Ptr32 Void +0x074 Privileges : Ptr32 _LUID_AND_ATTRIBUTES +0x078 DynamicPart : Ptr32 Uint4B +0x07c DefaultDacl : Ptr32 _ACL +0x080 TokenType : _TOKEN_TYPE +0x084 ImpersonationLevel : _SECURITY_IMPERSONATION_LEVEL +0x088 TokenFlags : Uint4B +0x08c TokenInUse : UChar +0x090 ProxyData : Ptr32 _SECURITY_TOKEN_PROXY_DATA +0x094 AuditData : Ptr32 _SECURITY_TOKEN_AUDIT_DATA +0x098 OriginatingLogonSession : _LUID +0x0a0 VariablePart : Uint4B
会话Id,用户和组列表这些告诉我们Token是属于哪个用户的。
特权列表,这个是表示该Token都可以干哪些坏事,拥有的权限越多越牛B哈哈
我们既然知道了Token是何方神圣了,那谁可以拥有Token呢?对了,只有进程和线程才能拥有!
每一个进程都拥有一个Token(这个是必须有的),该Token叫主令牌。可以从父进程处继承,也可以是后来设置的,使用NtSetInformationProcess,Class=ProcessAccessToken。
每个线程可以拥有一个ImpersonationToken(模仿令牌)。该令牌不是必须的,线程可以不拥有模仿令牌。
由此看来一个线程最多拥有2个令牌:主令牌和模仿令牌,最少拥有一个令牌:主令牌。
设置线程的模仿令牌的方法:NtSetInformationThread, calss=ThreadImpersonationToken。
既然有了主令牌,模仿令牌有什么用呢?
当一个线程要加载一个驱动,但发现主令牌没有加载驱动特权,它就可以模仿主令牌,然后在模仿令牌中加入加载驱动特权
当一个线程想要打开一个文件,但是该文件只有User2用户才能打开,主令牌却是属于User1用户。这时候可以模仿一个User2用户的令牌,这样就可以打开该文件了。
下面我们看一下都有哪些特权:
代码:
SeAssignPrimaryTokenPrivilegeSeAuditPrivilegeSeBackupPrivilegeSeChangeNotifyPrivilegeSeCreateGlobalPrivilegeSeCreatePagefilePrivilegeSeCreatePermanentPrivilegeSeCreateSymbolicLinkPrivilegeSeCreateTokenPrivilegeSeDebugPrivilegeSeEnableDelegationPrivilegeSeImpersonatePrivilegeSeIncreaseBasePriorityPrivilegeSeIncreaseQuotaPrivilegeSeIncreaseWorkingSetPrivilegeSeLoadDriverPrivilegeSeLockMemoryPrivilegeSeMachineAccountPrivilegeSeManageVolumePrivilegeSeProfileSingleProcessPrivilegeSeRelabelPrivilegeSeRemoteShutdownPrivilegeSeRestorePrivilegeSeSecurityPrivilegeSeShutdownPrivilegeSeSyncAgentPrivilegeSeSystemEnvironmentPrivilegeSeSystemProfilePrivilegeSeSystemtimePrivilegeSeTakeOwnershipPrivilegeSeTcbPrivilegeSeTimeZonePrivilegeSeTrustedCredManAccessPrivilegeSeUndockPrivilegeSeUnsolicitedInputPrivilege
简单说明一下常见的。其他的看MSDN吧:http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
SeCreateGlobalPrivilege
创建全局的特权。这个特权直接影响到你可不可以创建一个有名字的全局事件、互斥量、内存区等。
SeDebugPrivilege
调试特权。顾名思义,跟调试有关。该特权直接影响到你能否打开系统进程如system、winlogin.exe等,并调试他们。
SeLoadDriverPrivilege
加载驱动特权。想加载驱动?那就必须有改权限。
SeImpersonatePrivilege
模仿特权。要想设置线程的模仿令牌,就要有该权限
SeCreateTokenPrivilege
创建令牌特权。没有该特权,就无法创建一个新的令牌。
一个Token中的特权列表中,已经指明该Token可以拥有哪些特权。不过有些特权并不是置位有效的,如果要使用该特权,需要使用SetTokenInformation修改。但是,特权列表中没有的特权,是不能添加进去的(当然你非要添加的话还是有办法的)!
下面我们用windbg看一下windbg.exe的Token
代码:
lkd> !process 0 1 windbg.exePROCESS 89031da0 SessionId: 0 Cid: 0c68 Peb: 7ffdb000 ParentCid: 0530 DirBase: 09f602e0 ObjectTable: e1f25ba0 HandleCount: 86. Image: windbg.exe VadRoot 88c553c0 Vads 87 Clone 0 Private 2296. Modified 3959. Locked 1. DeviceMap e20447c8 Token e108d258 ElapsedTime 02:26:28.813 UserTime 00:00:01.171 KernelTime 00:00:06.078 QuotaPoolUsage[PagedPool] 92740 QuotaPoolUsage[NonPagedPool] 3600 Working Set Sizes (now,min,max) (1803, 50, 345) (7212KB, 200KB, 1380KB) PeakWorkingSetSize 3848 VirtualSize 60 Mb PeakVirtualSize 61 Mb PageFaultCount 7861 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 2704lkd> !token e108d258_TOKEN e108d258TS Session ID: 0User: S-1-5-21-2025429265-1682526488-1801674531-1005Groups: 00 S-1-5-21-2025429265-1682526488-1801674531-513 Attributes - Mandatory Default Enabled 01 S-1-1-0 Attributes - Mandatory Default Enabled 02 S-1-5-32-544 Attributes - Mandatory Default Enabled Owner 03 S-1-5-32-545 Attributes - Mandatory Default Enabled 04 S-1-5-4 Attributes - Mandatory Default Enabled 05 S-1-5-11 Attributes - Mandatory Default Enabled 06 S-1-5-5-0-5125624 Attributes - Mandatory Default Enabled LogonId 07 S-1-2-0 Attributes - Mandatory Default Enabled Primary Group: S-1-5-21-2025429265-1682526488-1801674531-513Privs: 00 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default 01 0x000000008 SeSecurityPrivilege Attributes - 02 0x000000011 SeBackupPrivilege Attributes - 03 0x000000012 SeRestorePrivilege Attributes - 04 0x00000000c SeSystemtimePrivilege Attributes - 05 0x000000013 SeShutdownPrivilege Attributes - 06 0x000000018 SeRemoteShutdownPrivilege Attributes - 07 0x000000009 SeTakeOwnershipPrivilege Attributes - 08 0x000000014 SeDebugPrivilege Attributes - Enabled 09 0x000000016 SeSystemEnvironmentPrivilege Attributes - 10 0x00000000b SeSystemProfilePrivilege Attributes - 11 0x00000000d SeProfileSingleProcessPrivilege Attributes - 12 0x00000000e SeIncreaseBasePriorityPrivilege Attributes - 13 0x00000000a SeLoadDriverPrivilege Attributes - Enabled 14 0x00000000f SeCreatePagefilePrivilege Attributes - 15 0x000000005 SeIncreaseQuotaPrivilege Attributes - 16 0x000000019 SeUndockPrivilege Attributes - Enabled 17 0x00000001c SeManageVolumePrivilege Attributes - 18 0x00000001d SeImpersonatePrivilege Attributes - Enabled Default 19 0x00000001e SeCreateGlobalPrivilege Attributes - Enabled Default Authentication ID: (0,4e3f87)Impersonation Level: AnonymousTokenType: PrimarySource: User32 TokenFlags: 0x89 ( Token in use )Token ID: 4f3891 ParentToken ID: 0Modified ID: (0, 4ffaa5)RestrictedSidCount: 0 RestrictedSids: 00000000
SecurityDescriptor
安全描述符(sd)是访问控制模型的灵魂。所有的内核对象都拥有安全描述符。包括Token内核对象。
先看一下安全描述符的结构:
代码:
lkd> dt nt!_Security_Descriptor +0x000 Revision : UChar +0x001 Sbz1 : UChar +0x002 Control : Uint2B +0x004 Owner : Ptr32 Void +0x008 Group : Ptr32 Void +0x00c Sacl : Ptr32 _ACL +0x010 Dacl : Ptr32 _ACL
代码:
lkd> dt nt!_Object_Header +0x000 PointerCount : Int4B +0x004 HandleCount : Int4B +0x004 NextToFree : Ptr32 Void +0x008 Type : Ptr32 _OBJECT_TYPE +0x00c NameInfoOffset : UChar +0x00d HandleInfoOffset : UChar +0x00e QuotaInfoOffset : UChar +0x00f Flags : UChar +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION +0x010 QuotaBlockCharged : Ptr32 Void +0x014 SecurityDescriptor : Ptr32 Void +0x018 Body : _QUAD //对象体(可知对象体地址 - 4 即为安全描述符的地址)
先简要介绍一下sd。 sd中描述了用户Sid,DACL、SACL。
SACL是系统访问控制列表,是用来做审计用的,一般不用关心。
DACL是自主访问控制列表,记录了哪些用户可以(/不可以)以何种方式访问该对象。
安全描述符查看方法:
1. 在对象上查看其属性。如文件,点击右键选择“属性”,找到“安全”选项卡,点击“高级”按钮。弹出的对话筐中,“权限”选项卡就是DACL,"审核"选项卡是SACL,“所有者”是Owner、Group。
2. 用windbg的!sd指令
代码:
lkd> !object \BaseNamedObjects\ShimSharedMemoryObject: e1acd3a8 Type: (896732b0) Section ObjectHeader: e1acd390 (old version) HandleCount: 15 PointerCount: 16 Directory Object: e15289d0 Name: ShimSharedMemorylkd> !sd poi(e1acd3a8-4)&ffffffff8 //这里低三位取0 不是很懂ReadVirtual: e1a94680 not properly sign extendedReadVirtual: e1a94680 not properly sign extendedReadVirtual: e1a94690 not properly sign extendedReadVirtual: e1a94690 not properly sign extendedReadVirtual: e1a94664 not properly sign extendedReadVirtual: e1a94664 not properly sign extended->Revision: 0x1->Sbz1 : 0x0->Control : 0x8004 SE_DACL_PRESENT SE_SELF_RELATIVE->Owner : S-1-5-32-544->Group : S-1-5-18->Dacl : ->Dacl : ->AclRevision: 0x2->Dacl : ->Sbz1 : 0x0->Dacl : ->AclSize : 0x1c->Dacl : ->AceCount : 0x1->Dacl : ->Sbz2 : 0x0->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[0]: ->AceFlags: 0x0->Dacl : ->Ace[0]: ->AceSize: 0x14->Dacl : ->Ace[0]: ->Mask : 0x0003001f->Dacl : ->Ace[0]: ->SID: S-1-1-0->Sacl : is NULL
1. 对象的DACL==Null,则线程拥有完全的访问权限。
2. 对象的DACL不为Null,但是AceCount ==0(ACE,访问控制项),则拒绝任何线程访问。
3. 遍历DACL,找到跟令牌中用户或组一致的Ace,如果该Ace指明没有拥有制定的访问权限,则直接退出安全检查函数,并拒绝该线程访问。
4. 遍历DACL,没找到跟令牌中用户或组一致的Ace,并拒绝该线程访问。
5. 遍历DACL,找到跟令牌中用户或组一致的Ace,如果该Ace指明拥有制定的访问权限,则直接退出安全检查函数,并允许该线程访问。
为了更好的理解sd,给大家举个例子:
代码:
#include <windows.h>#include <sddl.h>BOOL InitSecurityDescriptor( SECURITY_ATTRIBUTES& sa, TCHAR* pszSD ){ sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = FALSE; return ConvertStringSecurityDescriptorToSecurityDescriptor( pszSD, SDDL_REVISION_1, &(sa.lpSecurityDescriptor), NULL);}void ReleaseSecurityDescriptor( SECURITY_ATTRIBUTES& sa ){ LocalFree(sa.lpSecurityDescriptor);}int _tmain(int argc, _TCHAR* argv[]){ SECURITY_ATTRIBUTES sa; //创建一个局部名字事件(由于是局部的,多会话时,每个会话都创建一个同名的事件) //第一个参数SECURITY_ATTRIBUTES传NULL,则使用进程TOKEN的默认DACL。 //默认DACL有两个ACE //ACE1: 当前用户,拥有全部权限(读、写) //ACE2: system用户,拥有全部权限(读、写) HANDLE hEvent1 = CreateEvent( NULL, FALSE, FALSE, TEXT("Event1")); //创建一个局部名字事件,与上面是等价的 //"D:(D;;GR;;;WD)(A;;GW;;;WD)" 的意思是: DACL添加Everyone用户,拒绝读,允许写权限 InitSecurityDescriptor( sa, TEXT("D:(D;;GR;;;WD)(A;;GW;;;WD)") ); HANDLE hEvent2 = CreateEvent( &sa, FALSE, FALSE, TEXT("Local\\Event2")); ReleaseSecurityDescriptor(sa); HANDLE hEventX = OpenEvent(EVENT_MODIFY_STATE, FALSE, TEXT("Local\\Event2")); if( hEventX != NULL ) { printf( "进入这里,有权限\n" ); CloseHandle(hEventX); } hEventX = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("Local\\Event2")); if( hEventX == NULL ) { printf( "进入这里,无权限。gle:%d\n", GetLastError() ); } //创建一个全局名字事件 //由于其只给当前用户和system分配了权限,所以虽然是全局事件,但是其他会话也是无法访问的 HANDLE hEvent3 = CreateEvent( NULL, FALSE, FALSE, TEXT("Global\\Event3")); //手动创建一个SECURITY_ATTRIBUTES,使用SDDL语法 //D:(A;;GA;;;WD) 的意思是: DACL添加Everyone用户,并让其拥有全部权限 InitSecurityDescriptor( sa, TEXT("D:(A;;GA;;;WD)") ); //创建一个全局名字事件,可以被其他会话访问 HANDLE hEvent4 = CreateEvent( &sa, FALSE, FALSE, TEXT("Global\\Event4")); ReleaseSecurityDescriptor(sa); printf( "%p, %p, %p, %p\n", hEvent1, hEvent2, hEvent3, hEvent4 ); getchar(); CloseHandle(hEvent1); CloseHandle(hEvent2); CloseHandle(hEvent3); CloseHandle(hEvent4); return 0;}
代码:
lkd> !object \Sessions\1\BaseNamedObjects\Event1Object: 89584ac8 Type: (896762f8) Event ObjectHeader: 89584ab0 (old version) HandleCount: 1 PointerCount: 2 Directory Object: e19721e0 Name: Event1lkd> !sd poi(89584ac8-4)&fffffff8->Revision: 0x1->Sbz1 : 0x0->Control : 0x8004 SE_DACL_PRESENT SE_SELF_RELATIVE->Owner : S-1-5-21-2025429265-1682526488-1801674531-1006//当前用户Sid->Group : S-1-5-21-2025429265-1682526488-1801674531-513//管理员组Sid->Dacl : ->Dacl : ->AclRevision: 0x2->Dacl : ->Sbz1 : 0x0->Dacl : ->AclSize : 0x64->Dacl : ->AceCount : 0x3->Dacl : ->Sbz2 : 0x0->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE//允许->Dacl : ->Ace[0]: ->AceFlags: 0x0->Dacl : ->Ace[0]: ->AceSize: 0x14->Dacl : ->Ace[0]: ->Mask : 0x001f0003//完全控制权限->Dacl : ->Ace[0]: ->SID: S-1-5-18//system Sid->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[1]: ->AceFlags: 0x0->Dacl : ->Ace[1]: ->AceSize: 0x24->Dacl : ->Ace[1]: ->Mask : 0x001f0003->Dacl : ->Ace[1]: ->SID: S-1-5-21-2025429265-1682526488-1801674531-1006//会话1用户的Sid->Dacl : ->Ace[2]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[2]: ->AceFlags: 0x0->Dacl : ->Ace[2]: ->AceSize: 0x24->Dacl : ->Ace[2]: ->Mask : 0x001f0003->Dacl : ->Ace[2]: ->SID: S-1-5-21-2025429265-1682526488-1801674531-1006->Sacl : is NULLlkd> !object \Sessions\1\BaseNamedObjects\Event2Object: 893db418 Type: (896762f8) Event ObjectHeader: 893db400 (old version) HandleCount: 1 PointerCount: 2 Directory Object: e19721e0 Name: Event2lkd> !sd poi(893db418-4)&fffffff8->Revision: 0x1->Sbz1 : 0x0->Control : 0x8004 SE_DACL_PRESENT SE_SELF_RELATIVE->Owner : S-1-5-21-2025429265-1682526488-1801674531-1006->Group : S-1-5-21-2025429265-1682526488-1801674531-513->Dacl : ->Dacl : ->AclRevision: 0x2->Dacl : ->Sbz1 : 0x0->Dacl : ->AclSize : 0x30->Dacl : ->AceCount : 0x2->Dacl : ->Sbz2 : 0x0->Dacl : ->Ace[0]: ->AceType: ACCESS_DENIED_ACE_TYPE//拒绝->Dacl : ->Ace[0]: ->AceFlags: 0x0->Dacl : ->Ace[0]: ->AceSize: 0x14->Dacl : ->Ace[0]: ->Mask : 0x00020001//读权限->Dacl : ->Ace[0]: ->SID: S-1-1-0//Everyone SID->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[1]: ->AceFlags: 0x0->Dacl : ->Ace[1]: ->AceSize: 0x14->Dacl : ->Ace[1]: ->Mask : 0x00020002//写权限->Dacl : ->Ace[1]: ->SID: S-1-1-0->Sacl : is NULLlkd> !object \BaseNamedObjects\Event3Object: 8945d7d0 Type: (896762f8) Event ObjectHeader: 8945d7b8 (old version) HandleCount: 1 PointerCount: 2 Directory Object: e15289d0 Name: Event3lkd> !sd poi(8945d7d0-4)&fffffff8->Revision: 0x1->Sbz1 : 0x0->Control : 0x8004 SE_DACL_PRESENT SE_SELF_RELATIVE->Owner : S-1-5-21-2025429265-1682526488-1801674531-1006->Group : S-1-5-21-2025429265-1682526488-1801674531-513->Dacl : ->Dacl : ->AclRevision: 0x2->Dacl : ->Sbz1 : 0x0->Dacl : ->AclSize : 0x40->Dacl : ->AceCount : 0x2->Dacl : ->Sbz2 : 0x0->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[0]: ->AceFlags: 0x0->Dacl : ->Ace[0]: ->AceSize: 0x24->Dacl : ->Ace[0]: ->Mask : 0x001f0003->Dacl : ->Ace[0]: ->SID: S-1-5-21-2025429265-1682526488-1801674531-1006->Dacl : ->Ace[1]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[1]: ->AceFlags: 0x0->Dacl : ->Ace[1]: ->AceSize: 0x14->Dacl : ->Ace[1]: ->Mask : 0x001f0003->Dacl : ->Ace[1]: ->SID: S-1-5-18->Sacl : is NULLlkd> !object \BaseNamedObjects\Event4Object: 8912ca78 Type: (896762f8) Event ObjectHeader: 8912ca60 (old version) HandleCount: 1 PointerCount: 2 Directory Object: e15289d0 Name: Event4lkd> !sd poi(8912ca78-4)&fffffff8->Revision: 0x1->Sbz1 : 0x0->Control : 0x8004 SE_DACL_PRESENT SE_SELF_RELATIVE->Owner : S-1-5-21-2025429265-1682526488-1801674531-1006->Group : S-1-5-21-2025429265-1682526488-1801674531-513->Dacl : ->Dacl : ->AclRevision: 0x2->Dacl : ->Sbz1 : 0x0->Dacl : ->AclSize : 0x1c->Dacl : ->AceCount : 0x1->Dacl : ->Sbz2 : 0x0->Dacl : ->Ace[0]: ->AceType: ACCESS_ALLOWED_ACE_TYPE->Dacl : ->Ace[0]: ->AceFlags: 0x0->Dacl : ->Ace[0]: ->AceSize: 0x14->Dacl : ->Ace[0]: ->Mask : 0x001f0003->Dacl : ->Ace[0]: ->SID: S-1-1-0->Sacl : is NULL
0 0
- windows 访问控制模型(一)
- windows 访问控制模型(一)
- windows 访问控制模型
- Windows的访问控制模型
- windows之 访问控制模型
- Windows的访问控制模型
- windows 访问控制模型(二)之安全描述符
- 访问控制模型
- 访问控制模型综述
- 访问控制安全机制及相关模型(包括:强制访问控制和自主访问控制)
- windows访问控制笔记
- Linux安全访问控制模型
- 说说关于访问控制模型
- (一四〇)访问控制:protected
- 第三章 授权(一)访问控制
- SNMP学习 SNMPv3 VACM(视图访问控制模型)
- SNMP学习 SNMPv3 VACM(视图访问控制模型)
- SNMP学习 SNMPv3 VACM(视图访问控制模型)
- 很轻微的议案U树要低啊USD
- 深入探讨 Java 类加载器
- SVN架设
- IE11也不再支持document.createElement("<input type='file' name='upload'/>");
- javaScript权威指南第一章 1.1 javaScript语言核心
- windows 访问控制模型(一)
- 每日linux命令学习之diff
- hdu 2189 悼念512汶川大地震遇难同胞——来生一起走
- openwrt开源系统LUCI配置界面
- 【索引】Probability::Examples:: Beginner
- crontab执行脚本中文乱码,手动执行没有问题
- 【思考题】任意长度有理数乘法运算
- 黑马程序员_C#基础篇总结3
- 实现算法2.17的程序