版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章 以最小特权运行 以最小特权运行的原则,就是总是使用完成任务所需 的最小特权集来执行任务。以最小特权运行还意味着以尽可 能短的时间使用提升后的特权,这将减少利用该特权进行攻 击的时间段。在Windows中,你可以在使用某项特权前将其 激活,执行需要此特权的任务,然后取消此特权。 如果在很低的特权下运行那些会危及安全的软件,就 可以减少那些会导致安全问题的严重程序缺陷(比如缓冲区 溢出)所带来的危害。当用户意外或无意中执行了具有恶意 的代码,而这些代码在提高了用户权限的条件下运行,将会 导致安全问题的出现。 第七章 以最小特权运行 现实中的最小特权 如果你的应用程序不是在提升的特权下运行,
2、许多攻击都不 会成功。目前,在互联网上最普遍的两种攻击方式是病 毒/木马和破坏Web服务器,当用户只是以普通身份运行 程序时,许多攻击是不会成功的。 Back Orifice。 Back Orifice是一种工具,一旦安装在计算 机中,攻击者就可以对其进行远程控制,包括启动计算 机、执行由于程序、浏览文件内容,而且不为用户所知。 安装Back Orifice时,它试图向Windows的系统文件夹以 及一些注册表项中写入一些信息,这些操作只有管理员 才能进行,如果用户不是计算机管理员,Back Orifice将 会安装失败。 第七章 以最小特权运行 现实中的最小特权 SubSeven。 SubS
3、even能使未经授权的攻击者通过互联网 访问你的计算机,为了能够执行, SubSeven在Windows 系统文件夹中创建自身的一个拷贝,更新Win.ini和 System.ini,而且修改注册表中的注册服务码,这些只有 管理员才能执行。当用户不是管理员时, SubSeven也会 失败。 FunLove病毒。当这个病毒被运行之后,它通过修改被感 染计算机上的内核访问检测代码,从而允许用户访问所 有文件。它同样是向系统文件夹中写入一个文件,然后 插入到Windows内核Ntoskrnl.exe中,除非用户是管理员, 否则FunLove无法写入这些文件,从而导致失败。 第七章 以最小特权运行 现实
4、中的最小特权 ILoveYou病毒。它将自己写入系统文件夹中,并试图更 新注册表中的信息。同样只要用户不是管理员,病毒攻 击会失败。 破坏Web服务器。在微软的Windows 2000中包含的,并 通过IIS暴露出来的Internet打印协议(IPP)中,存在着缓冲 区溢出漏洞,非法的攻击者可以通过它来对IIS服务进行 攻击。真正的危险者是IIP的处理程序,它是作为一个 ISAPI扩展来实现的,并以SYSTEM账户运行。如果IPP不 是在本地系统账户下运行,那么很少会有网站会被攻击。 第七章 以最小特权运行 Windows中较强能力的特权及其能够带来 的安全性问题 Windows用户帐户都具有
5、一定的特权或权限。这些特权的例 子包括登陆到一台计算机、调试属于其他用户的程序、 改变系统时间等。特权是一台计算机的本地权限,但它 可以通过组策略(Group Policy)分布到域中的多台计算机 上。一个用户可能在一台计算机上有一组特权,在另一 台计算机上有另一组特权。用本地策略(Local Policy)选项 为你自己计算机上的用户帐户设置特权,不会对网络中 任何计算机上的特权策略产生影响。 第七章 以最小特权运行 Windows中较强能力的特权及其能够带来 的安全性问题 一些能力较强的Windows特权 显示的名称显示的名称内部名称内部名称#define(Winnt.h) 备份文件和目录
6、SeBackupPrivilege(16)SE_BACKUP_NAME 还原文件和目录SeRestorePrivilege(17)SE_RESTORE_NAME 作为操作系统的一部分SeTcbPrivilege(6)SE_TCB_NAME 调试程序SeDebugPrivilege(19)SE_DEBUG_NAME 替换进程级别的令牌SeAssignPrimaryTokenPrivilege(2)SE_ASSIGNPRIMARYTOKEN_NAME 装载和卸载设备驱动程序SeLoadDriverPrivilege(9)SE_LOAD_DRIVER_NAME 获取文件和其他对象的所 有权 SeTa
7、keOwnershipPrivilege(16)SE_TAKE_OWNERSHIP_NAME 第七章 以最小特权运行 Windows中较强能力的特权及其能够带来 的安全性问题 SeBackupPrivilege问题 实例:执行如下步骤: (1)以具有备份特权的身份登录,例如一个本地的管理员 (administrator)或一个备份操作员(backup operator)。 (2)创建一个小文件,取名为Test.txt,其中包含一些无用 的文本。 (3)使用ACL编辑工具,在文件中添加一个拒绝ACE来拒绝 你自己的账户对该文件的访问。假如你的账户名为Blake, 则添加一个Blake(全部拒绝)
8、ACE。 (4)编译并运行下面的代码。 第七章 以最小特权运行 Windows中较强能力的特权及其能够带来 的安全性问题 SeBackupPrivilege问题 一个具有备份文件和目录的特权账户能够读取那些在正常情 况下该账户所不能访问的文件。 如果一个叫Blake的用户要备份一个文件,正常情况下,该文 件的ACL将拒绝Blake的访问,而实际上,由于该账户具 有备份文件和目录的特权,正是这个特权使得他可以读 取该文件。一个备份程序可以在调用CreateFile时,通过 设置FILE_FLAG_BACKUP_SEMANTICS标志的值来对文件进 行读取。 第七章 以最小特权运行 /*WOWAc
9、cess.cpp*/ #include #include int EnablePriv(char *szPriv) HANDLE hToken=0; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, return -1; TOKEN_PRIVILEGES newPrivs; if(!LookupPrivilegeValue(NULL, szPriv, CloseHandle(hToken); return -1; BOOL OpenProcessToken( HANDLE ProcessHandle, DWOR
10、D DesiredAccess, PHANDLE TokenHandle ); 第一参数是要修改访问权限的进程句柄;第三个参数就是返回的访问令牌指针; 第二个参数指定你要进行的操作类型,如要修改令牌我们要指定第二个参数为 TOKEN_ADJUST_PRIVILEGES(其它一些参数可参考PlatformSDK)。 第一个参数为第一个参数为系统的名称,若为空,则在当前的sysytem查找。第二个参第二个参 数数指明了权限的名称,如“SeDebugPrivilege”。第三个参数第三个参数返回LUID的 指针。返回一个权限的局部唯一标识(Local Unique IDentifier) 。 第七章
11、 以最小特权运行 newPrivs.Privileges0.Attributes=SE_PRIVILEGE_ENABLE; newPrivs.PrivilegeCount=1; if(!AdjustTokenPrivileges(hToken, FALSE, CloseHandle(hToken); return -1; if(GetLastError()=ERROR_NOT_ALL_ASSIGNED) printf(“AdjustTokenPrivileges() succeeded, but not all privs setn”); CloseHandle(hToken); return
12、 0; 第一个参数是访问令牌的句柄;第二个参数决定是进行权 限修改还是禁止(Disable)所有权限;第三个参数指明要 修改的权限,是一个指向 TOKEN_PRIVILEGES结构的指针, 该结构包含一个数组,数据组的每个项指明了权限的类型 和要进行的操作; 第四个参数是结构PreviousState的长 度,如果PreviousState为空,该参数应为NULL;第五个参 数也是一个指向 TOKEN_PRIVILEGES结构的指针,存放修改 前的访问权限的信息,可空;最后一个参数为实际 PreviousState结构返回的大小。 第七章 以最小特权运行 void DoIT(char *szF
13、ileName, DWORD dwFlags) printf(“nnAttempting to read %s, with 0 x%x flagsn”, szFileName, dwFlags); HANDLE hFile=CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwFlags, NULL); if(hFile=INVALID_HANDLE_VALUE) printf(“CreateFile() failed -%d, GetLastError(); return; char buff
14、128; DWORD cbRead=0, cbBuff=sizeof buff; ZeroMemory(buff, sizeof buff); if(ReadFile(hFile, buff, cbBuff, else printf(“ReadFile() failed -%d, GetLastError(); CloseHandle(hFile); 第七章 以最小特权运行 void main(int argc, char *argv) if(argc2) printf(“Usage: %s ”, argv0); return; /Need to enable backup priv firs
15、t. if(EnablePriv(SE_BACKUP_NAME)=-1) return; /Try with no backup flag should get access denied. DoIt(argv1, FILE_ATTRIBUTE_NORMAL); /Try with backup flagshould work! DoIt(argv1, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS); 第七章 以最小特权运行 程序运行后会得到如下类似结果: Attempting to read Test.txt, with 0 x80 fla
16、gs CreateFile() failed -5 Attempting to read Test.txt, with 0 x2000080 flags Success, read 15 bytes Text is: Hello, Blake! 所以赋予这一用户权限将成为一个安全风险。既然无法确定 一个用户是在合法地备份数据,还是在偷窃数据,那么就只 向可信任的用户赋予这一用户权限。 第七章 以最小特权运行 SeRestorePrivilege问题 这项特权与备份特权正相反。利用这项特权,攻击者可以改写文件,包括一般情 况下不能访问的DLL和EXE!攻击者可以利用这项特权来改变对象的所有权,
17、而所有者具有对象的完全控制。 SeDebugPrivilege问题 一个具有调试特权的用户,能够依附于任何的进程并可以查看或调整其内存。因 此,如果一个应用程序中,有一些秘密需要保护,任何具有这个特权并且 完全知道如何访问的用户都能够通过使用调试器调试该进程来访问到秘密 数据。 调试程序特权同时也允许调用者通过调用TerminateProcess函数来结束计算机上的 任何进程。因此,具有该特权的非管理员也可以通过结束一个关键系统进 程,比如LSA(Local Security Authority, 本地安全授权)Lsass.exe,来关闭计 算机。 还有一种更为危险的可能性,一个具有调试特权的
18、攻击者能够使用 CreateRemoteThread函数在任何正在运行的进程中执行代码。例如,在 Lsass.exe中注入一个新线程来执行代码,读取已经经过LSA解密的私有数据, 从而查看存储在LSA中的秘密数据。 第七章 以最小特权运行 SeTcbPrivilege问题 如果一个账户的权限是作为操作系统的一部分,实质上他可以作为一个高可信的 系统组件进行工作。这个特权同时也被称作TCB(Trusted Computing Base, 可 信计算库)特权。TCB是最为可信的,因而也是Windows系统中最危险的特权。 因为这一点,具有该特权的唯一账户默认为SYSTEM(系统)。 SeLoadD
19、riverPrivilege问题 在内核中运行的可执行代码是高度可信任的,可以进行任何可能的任务。将代码 载入到内核中需要SeLoadDriverPrivilege特权。在默认情况下,只有管理员 才有此项特权。装载即插即用驱动程序并不需要这项特权,因为即插即用 服务装载的代码是以SYSTEM账户运行的。 SeRemoteShutdownPrivilege问题 这项特权允许关闭远程计算机。注意,与所有特权一样,用户账户的此项特权必 须在目标计算机上被激活。 SeTakeOwnershipPrivilege问题 所有者总是拥有对该账户所有的任何对象的完全控制。具有此项特权的账户就可 能从对象的原始
20、所有者那里取得所有权。其结果就是一个账户可能拥有对 系统中任何对象的全部控制。 第七章 以最小特权运行 令牌、特权、SID、ACL和进程之间的关系(*) 当用户登录运行Windows NT、2000、或XP的计算机时,同时这个 用户通过了身份认证,则操作系统会为用户创建一个称为令 牌(Token)的数据结构,这个令牌将用于所有由该用户激活 的进程和其中的每个线程。这个令牌包含该用户的SID、该用 户所属的每一个组的SID和用户所具有的特权列表等信息。 Windows NT、Windows 2000、Windows XP中的所有进程都以某一 个身份运行。也就是说,一个令牌与特定进程相关联。一般
21、来说,进程以启动该应用程序的用户的身份运行。然而,应 用程序也可以被一个具有适当特权的用户通过调用 CreateProcessAsUser函数来以其他用户的身份启动。典型情况 下,调用CreateProcessAsUser函数的进程必须具有 SeAssignPrimaryTokenPrivilege和SeIncreaseQuataPrivilege特权。 第七章 以最小特权运行 令牌、特权、SID、ACL和进程之间的关系 服务是另外一种类型的进程,它以服务控制管理器(SCM)中定 义的身份运行。许多服务默认以本地系统账户来运行,但是 也可以通过在SCM输入相应账户的用户名和密码来将其配置 为使
22、用其他账户运行。 因为进程与账户令牌相关联,因此,它具有其所属工作组的所有 资格和特权,它可以被认为是该账户的主体(principal),该账 户能够做的,该进程都能够做到。 一个令牌中包含有SID和特权。其中的SID用于根据资源中的ACL来 进行访问检查,而令牌中的特权则用于完成特定的在机器范 围内的任务。 第七章 以最小特权运行 应用程序要求提高特权的三个理由 非管理工具的应用程序为什么需要使用管理访问权,一般有三个原因: ACL问题。 特权问题。 使用LSA秘密。 ACL问题 假定NTFS分区中的一个文件夹,具有下列ACL: SYSTEM(完全控制)。 Administrators(完全
23、控制)。 Everyone(读取)。 除非你是管理员或SYSTEM账户,你对该文件夹所进行的操作只能是读取 文件。 第七章 以最小特权运行 应用程序要求提高特权的三个理由 ACL问题 有些应用程序要向文件系统中受保护的区域,或向操作系统 中其他部分如注册表中写入数据,这些应用程序必须在 管理员账户下执行,才能进行正确的操作。如许多游戏 向C:Program Files文件夹中写入最高分信息,这就意味 着玩这些游戏的用户必须是管理员。 特权问题 如果你的账户需要特定的特权来完成任务,比如备份文件, 那么你确实需要这项特权。但是,要谨慎地让管理员向 用户账户添加过多存在潜在危险的特权,或者让你的用
24、 户拥有过多不必要的特权。 第七章 以最小特权运行 应用程序要求提高特权的三个理由 使用LSA秘密 LSA可以为应用程序存储机密数据。操作LSA秘密的API包括 LsaStorePrivateData和LsaRetrievePrivateData。为了使用 LSA秘密,执行这些任务的进程必须是本地管理员组的成 员。 由于以上问题,普通用户常常要求提高特权。 第七章 以最小特权运行 解决提高特权的问题 解决ACL问题 以适当的访问权打开资源。即仅以所需的许可权来打开 资源。如果你要读取一个注册表项,就只请求只读访问 权即可。 将用户数据保存在用户能够写入的地方。要求不要将用 户数据写到操作系统受
25、保护的地方,如将用户文件写到 用户的profile目录。 放宽ACL。可以稍稍放宽ACL,因为将ACL降格的风险比 要求所有用户都成为管理员的风险会小一些。 解决特权问题 如果你需要一项完成任务的特权,那么就必须这么做,没有 简单的解决办法。 第七章 以最小特权运行 解决提高特权的问题 解决LSA问题 在Windows 2000及以后版本中,有一种可用的解决方案,称 为数据保护API或DPAPI。使用DPAPI,应用程序在访问秘 密数据时,不需要用户成为管理员,而是将数据使用一 个与用户关联的密钥进行保护,这样数据的所有者就可 以访问数据了。 第七章 以最小特权运行 确定适当特权的过程(*)
26、下面的过程可以帮助你根据应用程序的需要来确定 每个SID和特权是否应该包含在令牌中: 找出该应用程序所要使用的每个资源。 找出该应用程序所使用的有特权的API。 对应用程序运行时需要哪一个账户进行评估。 查明令牌中的SID和特权。 确定执行该应用程序任务所需要的所有SID和特 权。 对令牌进行调整以满足上一步的要求。 第七章 以最小特权运行 确定适当特权的过程 步骤1,找到应用程序使用的资源 第一步是列出应用程序用到的所有资源的列表,包括:文件、注册表项、 活动目录数据、命名管道、socket等等。同时也需要列出对于这些 资源需要使用哪种权限的访问。如下是一个假设的应用程序所使用 的资源列表:
27、 资源资源所需要的访问权限所需要的访问权限 配置数据由于管理员必须配置这个应用程序,所以需要完全的 控制。其他用户只需要对该数据具有读权限即可。 一个命名管道上的输 入数据 每个用户都需要使用这个管道来读写数据。 应用程序要将文件写 入的数据目录 每个用户都可以创建文件,并对属于他的数据进行任 何操作。每个用户都可以读取他人的文件。 应用程序所在的目录每个用户都可以读取并执行该应用程序,管理员可以 安装和更新。 第七章 以最小特权运行 步骤2,找到应用程序使用的特权API 分析应用程序中使用了哪些有特权的API。针对上述假设的例子,列出了所调用的有特权的 API。 函数名函数名所需要的权限或成
28、员关系所需要的权限或成员关系 使用FILE_FLAG_BACKUP_SEMANTICS选项的CreateFileSeBackupPrivilege LogonUserSeTcbPrivilege(Windows XP和Windows 2003不需要) SetTokenInformationSeTcbPrivilege ExitWindowsExSeShutdownPrivilege 使用安全事件日志的OpenEventLogSeSecurityPrivilege 面向所有桌面(BSM_ALLDESKTOPS)的BroadcastSystemMessageExSeTcbPrivilege Reg
29、isterLogonProcessSeTcbPrivilege InitiateSystemShutdownExSeShutdownPrivilege或SeRemoteShutdownPrivilege SetSystemPowerStateSeShutdownPrivilege GetFileSecuritySeSecurityPrivilege 当调试另一账户下运行的进程时调用的调试函数,包括 DebugActiveProcess和ReadProcessMemory SeDebugPrivilege CreateProcessAsUserSeIncreaseQuataPrivilege,
30、通常还有SeAssignPrimaryTokenPrivilege CreatePrivateObjectSecurityExSeSecurityPrivilege SetSystemTimeSeSystemtimePrivilege VirtualLock和AllocateUserPhysicalPagesSeLockMemoryPrivilege 网络API,例如NetUserAdd和NetLocalGroupDel对于许多调用,调用者必须是某些组的成员,如Administrators或Account Operators NetjoinDomainSeMachineAccountPrivi
31、lege 第七章 以最小特权运行 步骤3,哪一个账户是必需的 记下运行应用程序时所需要的账户。比如确定你的应用程 序是否需要以管理员的账户运行,或者你的服务是否需要本 地系统账户来运行。 步骤4,获取令牌的内容 查明上一步中确定的账户所对应的令牌中的SID和特权。 你既可以使用你想要测试的账户身份登录,来确定这些信息, 也可以使用RunAs命令来创建一个新的命令解释程序 (command shell)来实现。例如,如果你需要你的程序以管理 员的身份来运行,你可以输入下面的命令: RunAs /user:MyMachineAdministrator cmd.exe 第七章 以最小特权运行 下面的
32、代码将显示用户令牌中的各种重要的信息: /*MyToken*/ #define SECURITY_WIN32 #include “windows.h” #include “security.h” #include “strsafe.h” #define MAX_NAME 256 /This function determines memory required /and allocates it. The memory must be freed by caller. LPVOID AllocateTokenInfoBuffer(HANDLE hToken, TOKEN_INFORMATION
33、_CLASS InfoClass, DWORD *dwSize) *dwSize=0; GetTokenInformation(hToken, InfoClass, NULL, *dwSize, dwSize); return new BYTE*dwSize; /Get user name(s) Void GetUserNames() EXTENDED_NAME_FORMAT enf=NameDisplay, NameSamCompatible, NameUserPrincipal; for(int i=0; iGroupCount) printf(“tNone!n”); for(DWORD
34、i=0; iGroupCount; i+) SID_NAME_USE SidType; char lpNameMAX_NAME; char lpDomianMAX_NAME; DWORD dwNameSize=MAX_NAME; DWORD dwDomainSize=MAX_NAME; DWORD dwAttr=0; if(!LookupAccountSid(NULL, pSIDInfo-Groupsi.Sid, lpName, else printf(“LookupAccountSid Error %un”, GetLastError(); else dwAttr=pSIDInfo-Grou
35、psi.Attributes; printf(“%12s%-20st%sn”, lpDomain, lpName, (dwAttr delete (LPBYTE)pSIDInfo; 第七章 以最小特权运行 /Display privileges. void GetPrivis(HANDLE hToken) DWORD dwSize=0; TOKEN_PRIVILEGES *pPrivileges=(PTOKEN_PRIVILEGES)AllocateTokenInfoBuffer(hToken, TokenPrivileges, if(!pPrivileges) return; BOOL bR
36、es=GetTokenInformation(hToken, TokenPrivileges, pPrivileges, dwSize, if(FALSE=bRes) printf(“GetTokenInformation failedn”); for(DWORD i=0; iPrivilegeCount; i+) char szPrivilegeName128; DWORD dwPrivilegeNameLength=sizeof(szPrivilegeName); if(LookupPrivilegeName(NULL, else printf(“LookupPrivilegeName f
37、ailed - %lun”, GetLastError(); delete (LPBYTE)pPrivileges; 第七章 以最小特权运行 int main() if(!ImpersonateSelf(SecurityImpersonation) printf(“ImpersonateSelf Error %un”, GetLastError(); return -1; HANDLE hToken=NULL; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, return -1; printf(“nUser Namen”); Get
38、UserNames(); printf(“nSIDSn”); GetAllSIDs(hToken, TokenGroups); printf(“nRestricting SIDSn”); GetAllSIDs(hToken, TokenRestrictedSids); printf(“nPrivilegesn”); GetPrivs(hToken); RevertToSelf(); CloseHandle(hToken); return 0; 第七章 以最小特权运行 注:这段代码首先打开当前线程的令牌,并在 该令牌中查找该线程的用户名、SID、限定SID和 特权。函数GetUser、GetAl
39、lSIDs和GetPrivs能够 完成上面的主要工作。GetAllSIDs函数有两种形 式,一种是获得SID,另一种是获得限定SID。限 定SID是从一个可选的SID列表中添加到访问令牌 中的SID,用来对一个进程或线程的访问级别进 行限制,使得他们的访问级别比本来可以访问 的级别更低。 第七章 以最小特权运行 在上述例子中,应用程序需要以管理员的身份运行。通过MyToken.cpp,可以得到管理员令牌的默认内容: User NORTHWINDTRADERSblake SIDS NORTHWINDTRADERSDomain Users Everyone BUILTINAdministrator
40、s BUILTINUsers NT AUTHORITYINTERACTIVE NT AUTHORITYAuthenticated Users Restricting SIDS None Privileges SeChangeNotifyPrivilege (3) SeSecurityPrivilege (0) SeBackupPrivilege (0) SeRestorePrivilege (0) SeSystemtimePrivilege (0) SeShutdownPrivilege (0) SeRemoteShutdownPrivilege (0) SeTakeOwnershipPriv
41、ilege (0) SeDebugPrivilege (0) SeSystemEnvironmentPrivilege (0) SeSystemProfilePrivilege (0) SeProfileSingleProcessPrivilege (0) SeIncreaseBasePriorityPrivilege (0) SeLoadDriverPrivilege (2) SeCreatePagefilePrivilege (0) SeIncreaseQuataPrivilege (0) SeUndockPrivilege (2) SeManageVolumePrivilege (0)
42、第七章 以最小特权运行 步骤5,所有SID和特权是否都是必需的 让设计、开发和测试组的成员去分析令牌中每个SID和特 权,并确定哪一个是所需要的。执行这个任务要将第4步中 得到的令牌内容与资源列表以及在第1步和第2步中使用的API 函数进行比较。如果令牌中的SID和特权与需求不一致,则可 以考虑除去它们。 注意:许多SID是良性的,比如Users和Everyone,你不必 从令牌中删除它们。 第七章 以最小特权运行 步骤6,调整令牌 后一步是降低令牌的能力,这可以使用三种方法: 允许较低权限的用户来执行你的应用程序。 使用限定的令牌。 永久地除去不必要的特权 允许较低权限的用户来执行你的应用程
43、序 可以允许较低权限的用户来执行你的应用程序,但是却不 能允许他们执行某些功能,如不允许执行备份等这样的功能。 如一个基于Web的产品,不要因为需要管理员添加一个新的 用户账户,而要求该应用程序以SYSTEM的身份来运行。 第七章 以最小特权运行 上述例子可采用如下方法: 以预置好的具有较低特权的账户来运行系统,而取代以本 地系统账户来运行。 让程序要求管理员通过使用Windows身份验证来鉴别自己 的身份,从而执行高特权的操作,如添加一个新的账户。 让程序模仿用户账号并尝试执行用户账户的数据库操作, 如果操作系统拒绝访问,则这个账户不是管理员。 从安全的观点出发,以较低特权账户运行程序是不可
44、替代 的。如果一个进程以SYSTEM身份或其他较高权限的账户运行, 这个进程将模拟用户来降低该进程的能力,攻击者能够通过 注入代码来获得SYSTEM权限。比如通过缓冲区溢出,调用 RevertToSelf,在这一时刻,进程停止模拟。而转为该进程的 身份,即SYSTEM。 第七章 以最小特权运行 使用限定令牌 在Windows 2000及以后版本中添加了一个新的特性,即能 够获得用户令牌并降低或限定它的能力。一个限定的令牌是 原始或模仿的令牌在调用了CreateRestrictedToken函数之后产 生的。在限定令牌的安全环境下运行的进程或线程,被限制 了访问安全对象或执行特权操作的能力。可以
45、使用 CreateRestrictedToken函数对令牌执行下面三步操作来限制令 牌: 从令牌中删除一些特权。 指定一个限定SID的列表。 对SID应用“只拒绝(deny-only)”的属性。 第七章 以最小特权运行 删除权限。删除在令牌中你不想要的任何特权,而且它们在以 后也不会被添加进去。为了重新获得被删除的特权,该进程必须 被销毁并重新创建。 指定限定SID。通过给访问令牌添加限定SID,你可以决定在令 牌中允许哪些SID。当受限进程或线程试图去访问可用对象时,系 统会同时在可用的SID集和限定SID列表中进行访问验证。只有两者 检查都成功,才允许对指定对象的访问。 例如:一个文件的A
46、CL允许Everyone具有读权限,而 Administrators具有读、写以及删除的权限。而你的应用程序不 能删除该文件。比如一个Brian用户是管理员和市场部经理。代表 Brian的令牌应该具有下面的SID: Everyone Authenticated Users Administrators Marketing 应该选择一个仅由Everyone SID组成的限定SID。 第七章 以最小特权运行 给SID应用“只拒绝”的属性。“只拒绝”的SID改变了令牌中的 一个SID,以致使该令牌只能用来拒绝相应账户对安全资源的 访问,不能使用该SID来允许对一个资源的访问。比如,一个 资源可能具有
47、与之相关联的“Marketing”(拒绝所有的访问) ACE,则该用户组被拒绝访问。然而,如果一个资源包含 “Marketing”(允许读)ACE, “只拒绝”属性Marketing SID处于 用户访问的令牌中,那么只有这个用户被拒绝对该资源进行 读操作。 简单地从令牌中删除一个SID将会导致安全问题,而这也 是为什么SID能够被标记为“只拒绝”的原因。可以想象一个资 源上的ACL拒绝Marketing对该资源的访问。如果你的代码将 Marketing SID从用户令牌中删除,用户反而可以使用该资源。 因此,该SID应该标记为“只拒绝”,而不是将其从令牌中删除。 第七章 以最小特权运行 何时
48、使用限定令牌 如果你知道你的程序不需要某一层次的访问,你可以将其 标记为“只拒绝”。 如果你知道这样一类用户或组,他们不需要对程序所用到 的资源进行访问,那么请使用限定SID。 如果你的应用程序装载任意的代码,你应该考虑使用限定 令牌。如果对任意的文件调用ShellExecute或CreateProcess, 你可能考虑使用限定的令牌。 第七章 以最小特权运行 限定令牌的代码实例 限定令牌可以传递给CreateProcessAsUser以创建一个进程, 这个进程具有受限的权限和特权。这些令牌同样可以在调用 ImpersonateLoggedOnUser或SetThreadToken时使用,从而
49、能 够让调用线程模拟一个已登录用户的安全上下文,该用户由 一个限定令牌的句柄表示。 下面的示例代码显示了如何根据目前进程的令牌来创建一 个新的限定令牌。这个令牌除了具有SeChangeNotifyPrivilege 特权,其他特权都被删除了。 第七章 以最小特权运行 /*Restrict.cpp*/ /Create a SID for the BUILTINAdministrators Group. BYTE sidBuffer256; PSID pAdminSID=(PSID)sidBuffer; SID_IDENTIFIER_AUTHORITY SIDAuth=SECURITY_NT_AU
50、THORITY; if(!AllocateAndInitializeSid( return -1; /Change the local administrators SID to a deny-only SID. SID_AND_ATTRIBUTES SidToDisable1; SidToDisable0.Sid=pAdminSID; SidToDisable0.Attributes=0; /Get the current process token. HANDLE hOldToken=NULL; i f ( ! O p e n P r o c e s s T o k e n ( G e t
51、 C u r r e n t P r o c e s s ( ) , TOKEN_ASSIGN_PRIMARY|TOKEN_DUPLICATE|TOKEN_QUERY|TOKEN_ADJUST_DEFAULT, return -1; 第七章 以最小特权运行 /Create restricted token from the process token. HANDLE hNewToken=NULL; if(!CreateRestrictedToken(hOldToken, DISABLE_MAX_PRIVILEGE, 1, SidToDisable, 0, NULL, 0, NULL, retu
52、rn -1; if(pAdminSID) free(pAdminSID); /The following code creates a new process with the restricted token. PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory( si.cb=sizeof(STARTUPINFO); si.lpDesktop=NULL; /Build the path to cmd.exe to make sure were not running a Trojaned cmd.exe. char szSysDirMAX_P
53、ATH+1; if(GetSystemDirectory(szSysDir, MAX_PATH) char szCmdMAX_PATH+1; if(StringCchCopy(szCmd, MAX_PATH, szSysDir)=S_OK CloseHandle(hOldToken); CloseHandle(hNewToken); return 0; 第七章 以最小特权运行 下面的代码显示了如何在多线程应用程序中使用限定令牌。该线程调用函数ThreadFunc,删除了线程令牌中的所有特权,然后该线 程调用了DoThreadwork函数。 #include DWORD WINAPI Threa
54、dFunc(LPVOID lpParam) DWORD dwErr=0; try if(!ImpersonateSelf(SecurityImpersonation) throw GetLastError(); HANDLE hToken=NULL; HANDLE hThread=GetCurrentThread(); if(!OpenThreadToken(hThread, TOKEN_ASSIGN_PRIMARY|TOKEN_DUPLICATE|TOKEN_QUERY|TOKEN_IMPERSONATE, TRUE, HANDLE hNewToken=NULL; if(!CreateRes
55、trictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, NULL, 0, NULL, 0, NULL, if(!SetThreadToken( /DoThreadWork operates in restricted context. DoThreadWork(hNewToken); catch (DWORD d) dwErr=d; if(dwErr=0) RevertToSelf(); return dwErr; void main() HANDLE h=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thre
56、adFunc, NULL, CREATE_SUSPENDED, NULL); if(h) ResumeThread(h); 第七章 以最小特权运行 Windows XP的软件限制策略 Windows XP包括一个新的功能,叫做“软件限制策 略”(Software Restriction Policy,也叫做SAFER),它使限定令牌 在程序中更容易被使用和部署。 SAFER也包括一些函数,它们在Winsafer.h中声明,它能够 更加容易地与降低了权限的令牌配合使用。其中一个函数是 SafeComputeTokenFromLevel。这个函数能够接收发送来的令 牌并对其进行改变,以匹配预先定义
57、的降低了的功能级别。 下面的代码展示了如何创建一个以一般用户(NormalUser) 身份运行的新进程,这种身份就是非管理员和非高级用户 (PowerUser)账户。 第七章 以最小特权运行 /*SAFER.cpp*/ #include #include #include #include #include void main() SAFER_LEVEL_HANDLE hAuthzLevel; /Valid programmatic SAFER levels: /SAFER_LEVELID_FULLYTRUSTED /SAFER_LEVELID_NORMALUSER /SAFER_LEVELI
58、D_CONSTRAINED /SAFER_LEVELID_UNTRUSTED /SAFER_LEVELID_DISALLOWED /Create a normal user level. if(SaferCreateLevel(SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, 0, if(SaferComputeTokenFromLevel( hAuthzLevel,/Safer Level handle NULL,/NULL is current thread token. if(GetSystemDirectory(szSysDir, sizeof
59、(szSysDir) StringCbPrintf(szPath, sizeof(szPath), “%scmd.exe”, szSysDir); STARTUPINFO si; ZeroMemory( si.cb=sizeof(STARTUPINFO); si.lpDesktop=NULL; PROCESS_INFOMATION pi; if(!CreateProcessAsUser( hToken, szPath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, SaferCloseLevel(hAuthzLevel); 第
60、七章 以最小特权运行 永久地除去不必要的特权 Windows Server 2003种添加了一项新特性,可以从运行的应用程序中除去特权,而不 是从复制的线程中除去。其特点是这些特权将永远不会被应用程序使用,无论代 码是在正常运行还是正受到攻击。 一般来讲,除去特权的代码将在应用程序启动时调用,下面的代码是从进程令牌中移 去两个特权的实例。 /RemPriv #ifndef SE_PRIVILEGE_REMOVED #define SE_PRIVILEGE_REMOVED (0 x00000004) #endif DWORD RemovePrivs(LPCTSTR szPrivs, DWORD
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 氧化铝基负载型金属催化剂邻位氢中心构筑及加氢性能研究
- 秸秆回收加工厂项目可行性研究报告
- 2025版物业管理区域绿化安全管理服务合同3篇
- 基于相似理论的船用耐压设备缩比模型设计方法研究
- 2025版高校食堂营养膳食承包合作协议2篇
- 异地办公与远程工作管理
- 二零二五年度仓储物流用地买卖合同样本3篇
- 2025版选矿厂承包合同附设备更新改造计划书3篇
- 营销行业助理职责概述
- 热情温暖的社区活动中心三篇
- 城市道路智慧路灯项目 投标方案(技术标)
- 水泥采购投标方案(技术标)
- 初中英语-Unit2 My dream job(writing)教学设计学情分析教材分析课后反思
- 广州市劳动仲裁申请书
- 【公司利润质量研究国内外文献综述3400字】
- 工行全国地区码
- 新疆2022年中考物理试卷及答案
- 地暖工程监理实施细则
- 顶部板式吊耳计算HGT-20574-2018
- 《内证观察笔记》
- JJF 1191-2019测听室声学特性校准规范
评论
0/150
提交评论