随笔集中的所有内容为笔者在写作当时的所思所想,受于见识有限,学识有限,有些地方可能并不正确。如果有什么错误的地方,欢迎不吝指正。
- 背景:
- 最近遇到一个项目,需要对Windows上的文件权限以及注册表权限进行一些限制。于是就开始了一些毫无头绪的学习。
- 本篇中的虚拟机环境为64位 Windows 7,镜像可搜索MSDN进行下载。
- 文中的代码皆为 python2.7 版本的代码
0x0 目标
-
由于项目需求,我们需要限制文件夹的权限,从而限制对指定文件夹的权限,大概,就像下面这种的限制。
-
那么,众所周知,把文件夹属性设置为只读,或者修改成SetFileAttribute之类的函数,并不会达成这样的目的。反而会显得我们有点蠢。
-
于是稍微尝试修改一下我们的思路,像这样,找几个地方瞎点一点试试,发现成功了。
-
那么,现在就需要我们利用代码来执行一下刚才的步骤了。
0x1 代码实现 (一)
- 由于需要在原有的python代码上进行添加修改,尝试搜索一下windows相关的python库,可以找到一个名叫 pywin32 的模块,里面可以调用很多不同的 Windows 接口。
- 继续尝试搜索 “pywin32 修改文件夹权限” 等关键词,可以找到类似于下面这样的代码。
import win32security
import ntsecuritycon as con
FILENAME = "C:\\test" # 目标路径
userx, domain, type = win32security.LookupAccountName ("", "User X")
usery, domain, type = win32security.LookupAccountName ("", "User Y")
# 获取文件夹的 dacl 值
sd = win32security.GetFileSecurity(FILENAME, win32security.DACL_SECURITY_INFORMATION)
dacl = sd.GetSecurityDescriptorDacl()
# 设置新的权限为 dacl 可读可访问
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_GENERIC_READ, userx)
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_ALL_ACCESS, usery)
# 更新 dacl 权限
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(FILENAME, win32security.DACL_SECURITY_INFORMATION, sd)
- 把上面的代码放到我们的虚拟机里面测试一下,发现可以运行,但是和我们想象的还有一些差别。
- 【这里因为时间太久远已经忘记要写什么了,貌似是覆盖了原始 dacl 导致不容易恢复回修改前的状态所以又继续折腾了一下】
0x2 概念
首先,让我们来看一下什么是ACL和ACE,微软官方文档给出的定义是这样子的:
Access Control List (ACL)
: A list of security protections that applies to an object. (An object can be a file, process, event, or anything else having a security descriptor.) An entry in an access control list (ACL) is an access control entry (ACE). There are two types of access control list, discretionary and system.
Access Control Entry (ACE)
: An entry in an access control list (ACL). An ACE contains a set of access rights and a security identifier (SID) that identifies a trustee for whom the rights are allowed, denied, or audited.
- 简单来说,ACE(Access Control Entry) 就是Windows系统设置的一系列规则,决定了每个用户对于不同对象(文件,进程,实践,注册表等)的操作权限(访问,读,写,执行,等),ACL(Access Control List) 则是由多个 ACE 组成的链表(list)。
- ACL 又分为两种类型,
DACL(Discretionary Access Control List)
和SACL(System Access Control List)
,其中的DACL
用来表示安全对象的权限,而SACL
则是用来记录对安全对象访问的日志。
ACL的结构 |
---|
-
再简单来说,ACL就是一个用来限制用户权限的一套规则,在
域控
和渗透
方面的用处比较多。具体的使用方法可以参考下面两篇文章: -
由于我们的目标只是一些简单的权限控制,那么就只进一步稍微了解一下DACL和SACL,两者都是由一条条的ACE组成,在这里我们只关心DACL的ACE(因为SACL我也还没研究明白)。
-
众所周知,Windows中的权限限制,长这个样子:
- 对应我们在刚才了解到的概念,又可以将上图以这样的方式进行解读:
可以看到,整个 权限项目 中显示的就是我们的DACL,而其中的每一个子项就是一个ACE。 |
---|
0x3 代码实现(二)
## 根据 filename 为指定路径,禁用文件创建权限
def disable_dir(filename):
try:
userx, domain, type = win32security.LookupAccountName("", os.environ['USERNAME'])
sd = win32security.GetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION)
dacl = win32security.ACL()
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_GENERIC_READ, userx)
sd.SetSecurityDescriptorDacl(1, dacl, 0) # may not be necessary
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
except:
print "disable_dir failed"
## 根据 filename 为指定路径,恢复文件夹权限
def enable_dir(filename):
try:
userx, domain, type = win32security.LookupAccountName("", os.environ['USERNAME'])
sd = win32security.GetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION)
dacl = win32security.ACL()
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_GENERIC_READ | con.FILE_GENERIC_WRITE, userx)
sd.SetSecurityDescriptorDacl(1, dacl, 0) # may not be necessary
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
except:
print "enable_dir failed"