Windows下访问控制管理
参考URL:
https://blog.csdn.net/u011801161/article/details/45567289
http://blog.nsfocus.net/analysis-windows-access-authority-inspection-mechanism/
https://blog.csdn.net/eggfly178/article/details/41773601
一 Windows访问控制概述:
Windows访问控制中最主要的部分:访问令牌(Access Token)和安全描述符(Security Descriptor),window通过查看访问者AT与被访问对象SD中的内容来确定访问者是否能访问对象。
Windows访问控制概念介绍:
① SID:Secure Identifier(安全标识符),每个用户和账户组都有一个唯一的SID(通常情况下唯一)。它是标识用户、用户组和计算机账户唯一的号码,由计算机名、当前时间、当前用户态线程的CPU耗费时间三个参数来确定。
② Access Token:与特定的windows账户关联,账户环境下启动的所有进程都会获得该令牌的副本,进程中的线程默认获得这个令牌。由关联账户的SID、当前登录账户所属组的SID列表、受限制的SID列表、当前登录账户与所属组的Privilege列表组成。
③ Security Descriptor:安全描述符,与被访问对象关联。由对象所有者的SID、属组SID、DACL、SACL组成。DACL(随机访问控制列表)是SD最重要的一部分,描述允许或拒绝特定用户或组的某些访问权限,它包含零个或多个访问控制实体(ACE,Access Control Entry)。
④ ACE:访问控制实体,用于指定特定用户/组的访问权限,由SID、SIZE、Type、Access Mask、Inheritance/Audit Flags组成。
Windows访问控制流程图:
当一个线程尝试去访问一个对象时,系统会检查线程持有的令牌以及被访问对象的安全描述符中的DACL。
如果安全描述符中不存在DACL,则系统会允许线程进行访问。如果存在DACL,系统会顺序遍历DACL中的每个ACE,检查ACE中的SID在线程的令牌中是否存在。以访问者中的User SID或Group SID作为关键字查询被访问对象中的DACL。顺序:先查询类型为DENY的ACE,若命中且权限符合则访问拒绝;未命中再在ALLOWED类型的ACE中查询,若命中且类型符合则可以访问;以上两步后还没命中那么访问拒绝。
此外, SACL是系统访问控制列表,是用来做审计用的,一般不用关心。
二 一个修改特定对象DACL
以下代码实现了以默认权限创建一个event内核对象(默认权限下Administrators组没有修改权限), 然后给该对象的Administrators组添加修改权限的功能. 注意: 以下代码必须在system权限下运行(就是服务进程里边), 只展示了核心代码部分, DACL的修改貌似只能以整个安全描述符为单位进行修改, 不知道是不是我孤陋寡闻的原因
#include <windows.h>
#include <aclapi.h>
#include <sddl.h>
bool MyCreateEvent()
{
HANDLE g_HEStop =NULL;
bool result = false;
DWORD ret = ;
PACL pDACL11 = NULL;
PSECURITY_DESCRIPTOR pSE = NULL;
PSID pAdminSID = NULL;
wchar_t *domainName = NULL;
do
{
//get sid
LogToFile(L"find administrators sid");
DWORD domainSize = ;
DWORD sidSize = ;
SID_NAME_USE sidType = SidTypeGroup;
ret = LookupAccountNameW(NULL, L"Administrators", NULL, &sidSize, NULL, &domainSize, &sidType);
if (!(ret == && GetLastError() ==ERROR_INSUFFICIENT_BUFFER))
{ LogErr(L"LookupAccountName err1", GetLastError());
break;
}
std::wstring str = std::to_wstring(sidSize);
str += L" ";
str += std::to_wstring(domainSize);
LogToFile(str.c_str()); pAdminSID = new char[sidSize];
domainName = new wchar_t[domainSize];
if (!pAdminSID || !domainName)
{
LogToFile(L"alloc buffer err");
break;
} ret = LookupAccountNameW(NULL, L"Administrators", pAdminSID, &sidSize, domainName, &domainSize, &sidType);
if (ret == )
{
LogErr(L"LookupAccountName err2", GetLastError());
break;
}
else
{
LogErr(L"sidType", sidType);
LPWSTR str = NULL;
if (ConvertSidToStringSidW(pAdminSID, &str))
{
LogToFile(str);
LocalFree(str);
str = NULL;
}
} // create event
LogToFile(L"create event");
g_HEStop = CreateEventW(NULL, TRUE, FALSE, STOP_EVENT_NAME);
if (!g_HEStop)
{
LogToFile(L"create event err");
break;
} // modify dacl
LogToFile(L"modify dacl");
ret = GetSecurityInfo(g_HEStop, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL11, NULL, &pSE);
if (ret != ERROR_SUCCESS)
{
LogErr(L"get Dacl err",ret);
break;
} ACL_SIZE_INFORMATION aclSInfo;
ret = GetAclInformation(pDACL11, &aclSInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
if (ret == )
{
LogErr(L"get acl info err", GetLastError());
break;
} LogToFile(L"enum ace"); PACE_HEADER aceHeader = NULL;
bool find = false;
PSID pSidInAce = NULL;
LPWSTR StringSid = NULL;
for (DWORD index = ; index < aclSInfo.AceCount; ++index)
{
ret = GetAce(pDACL11, index, (LPVOID*)&aceHeader);
if (ret)
{
// 目前来说各中ace的结构是一样的, 可以这么写, 将来可能会变
pSidInAce = (PSID)((DWORD)aceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
if (ConvertSidToStringSidW(pSidInAce, &StringSid))
{
LogToFile(StringSid);
LocalFree(StringSid);
StringSid = NULL;
}
else
LogErr(L"ConvertSidToStringSidW err: ", GetLastError()); if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
{
PACCESS_ALLOWED_ACE aceAl = (PACCESS_ALLOWED_ACE)aceHeader;
if (EqualSid(pSidInAce, pAdminSID))
{
aceAl->Mask |= GENERIC_WRITE;
find = true;
break;
}
}
}
}
if (find)
{
ret = SetSecurityInfo(g_HEStop, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pDACL11, NULL);
if (ret == ERROR_SUCCESS)
result = true;
else
LogErr(L"SetSecurityInfo err: ", ret);
}
else
LogToFile(L"not find allow ace");
} while (false);
if (pAdminSID)
delete[] pAdminSID;
if (domainName)
delete[] domainName;
if (pSE)
LocalFree(pSE); if (!result && IsStopEventValid())
CloseHandle(g_HEStop);
return result;
}
Windows下访问控制管理的更多相关文章
- windows下python管理右键菜单
实现很简单,不记得什么时候写的了,贴出来希望能有所价值 """ Windows中创建右键菜单 """ import os import sy ...
- 分享Nginx在Windows下的管理命令(bat文件)
话不多说,复制下面的内容,存成bat文件,放到nginx目录下. ====================================================@echo offrem 当前 ...
- windows下进程管理常用命令
1.查看当前正在运行的进程 tasklist 注: /im 后为映像名称参数:/f 为强行终止,可以通过 taskkill /? 查看更多帮助 2.强制杀死映像名称为imagename的进程,映像名 ...
- windows下运行的linux服务器批量管理工具(带UI界面)
产生背景: 由于做服务器运维方面的工作,需要一人对近千台LINUX服务器进行统一集中的管理,如同时批量对LINUX服务器执行相关的指令.同时批量对LINUX服务器upload程序包.同时批量对LINU ...
- Windows下安装Cygwin及包管理器apt-cyg(转)
本文为转载文章: http://www.2cto.com/os/201212/176551.html Cygwin可以在Windows下使用unix环境Bash和各种功能强大的工具,对于Linux管理 ...
- 【亲测可用,亦可配置同一平台的不同账号,例如阿里云的两个不同账号】Windows下Git多账号配置,同一电脑多个ssh-key的管理
Windows下Git多账号配置,同一电脑多个ssh-key的管理 这一篇文章是对上一篇文章<Git-TortoiseGit完整配置流程>的拓展,所以需要对上一篇文章有所了解,当然直接 ...
- windows 下node版管理
linux 下的node 多版本管理有nvm,windows 下同样有这样的工具gnvm 安装步骤(无node环境): 1.下载并解压缩 gnvm.exe 保存到任意文件夹,并将此文件夹加入到环境变量 ...
- windows下安装php依赖关系管理工具composer
1.安装Composer Composer是PHP的依赖管理工具之一,官方网站 http://getcomposer.org/ .它支持多种安装方式,对于在win下做开发的草来说,最便捷的方式就是下载 ...
- [源码管理] Windows下搭建SVN服务器
前文所述SVN客户端使用的时候,用的SVN服务器通常为外部,例如Google Code的服务器,不过,做为一个程序开发人员,就算自己一个人写程序,也应该有一个SVN版本控制系统,以便对开发代码进行有效 ...
随机推荐
- C# Ini、Json、Xml 封装类
1.Ini是什么?(我对它的理解,用于存储用户配置信息的文件,该文件放在用户电脑...) INI文件是一个无固定标准格式的配置文件.它以简单的文字与简单的结构组成,常常使用在Windows操作系统,或 ...
- js中 setTimeout延时0毫秒的作用
经常看到setTimeout延时0ms的javascript代码,感到很迷惑,难道延时0ms和不延时不是一个道理吗?后来通过查资料以及实验得出以下两个作用,可能还有作用我还不知道,希望得知的朋友在后面 ...
- 2018上C语言程序设计(高级)- 第2次作业成绩
作业地址 评分准则 第一次作业各项成绩包括三项: 完成PTA所有题目:9分 总结和附加题目:15分 博客记录:70分 博客记录包含三次PTA,共8道题,有正确流程图题目12分,没有的8分: 设计思路2 ...
- html基础js
HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...
- JVM垃圾收集器-Parallel Scavenge收集器
今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...
- springboot+mybatis-puls利用swagger构建api文档
项目开发常采用前后端分离的方式.前后端通过API进行交互,在Swagger UI中,前后端人员能够直观预览并且测试API,方便前后端人员同步开发. 在SpringBoot中集成swagger,步骤如下 ...
- Java中如何拆分字符串为字符数组
题目:输入一串字符,由(){}[]组成,判断是否所有的括号都是闭括号,是的返回TRUE,不是返回FALSE. /*输入字符串,拆解为字符数组 * 用函数s.charAt(i)来完成 * * */imp ...
- Linux 系统的总管 Systemd
目录 1. init的进化,全功能的Systemd 2 1.1 Linux系统中,init主要有3个版本 2 1.2 比较传统的init程序,Systemd的特点有: 2 1.3 Systemd Jo ...
- C# 枚举用法
public static class EnumExtensions { public static string GetDescription(this Enum value) { return v ...
- 学习笔记DL005:线性相关、生成子空间,范数,特殊类型矩阵、向量
线性相关.生成子空间. 逆矩阵A⁽-1⁾存在,Ax=b 每个向量b恰好存在一个解.方程组,向量b某些值,可能不存在解,或者存在无限多个解.x.y是方程组的解,z=αx+(1-α),α取任意实数. A列 ...