请点击上面
一键关注
作者:360灵腾安全实验室
daiker@360RedTeam
0x00 前言
这篇文章主要介绍AD里面的域用户,计算机用户。
0x01 域用户
1. 查询域用户
当我们拥有一个域用户的时候,想要枚举域内的所有用户,主要有两个方法。
(1) 通过SAMR 协议查询
samr 也不算是一种专门的协议,就是一个RPC接口(这里简单地提一下。
后面在RPC篇里面详细介绍这个RPC接口)
我们平时使用的net user /domain就是使用samr 进行查询的。
在impacket 里面有一个脚本samrdump.py就是专门调用samr 去查询域用户的。
(2) 通过Ldap 语法查询
域用户存储于活动目录数据库里面,对其他用户可见。
可以通过Ldap 去查询。
过滤语法如下
(&(objectCategory=person)(objectClass=user))
2. 域用户部分属性介绍
这些属性在LDAP 里面都可以查看
(1)姓对应的属性就是sn
(2) 名对应的属性是giveName
(3)展示名,对应的属性是displayName。
值得注意的是,displayName不能用于登陆,虽然跟域用户名往往一样。
但是这个不是直接用于登陆的我们登陆用的账号,在一些公司里面,displayName往往是中文,登陆的用户名是拼音。
登陆的格式有以下两种格式。
(4)第一种格式是UserPrincipalName,我们简称为UPN,一般的格式是用户名@域名这样的格式。
比如这里就是[email protected]
(5) 第二种格式是域名\sAMAccountName这种格式
比如这里就是test.local\lisi,这里的域名可以是netbios名,也可以是dns 名。
在上一篇,讲位操作的时候有简单提及到这个userAccountControl,其实这个属性至关重要。
在整个系列文章里面反复提及。
userAccountControl对应的位如下。
我们可以利用ldap的位操作(关于Ldap的位操作见Windows内网协议学习LDAP篇之组和OU介绍)来一个个过滤。
比如,我们想查询查询密码永不过期的用户。
又比如,我们想查询设置了约束委派的用户。
又比如,我们想查询域内设置了对委派敏感的用户。
等等等。
大家可以查表,然后更改对应的十进制值来过滤。
0x02 机器用户
默认情况底下,加入域的机器默认在CN=Computer这个容器里面,域控默认在Domain Controllers这个OU里面。
有些域内会通过redircmp进行修改
1. 机器用户跟system 用户的关系
考虑到这样一个场景,如果拿到一台域内机器,然后发现没有域内用户。
这个时候有很多人用mimikatz 抓一下,没抓到域用户,就束手无策了。
我们随便点开一台Domain Computer,这里以WIN7这台机子做为测试。
我们看他的对象类。
发现他是computer 类的实例。
而computer 类的user 类的子类。
域用户是user类的实例。
之前我们说过类是属性的集合。
子类继承了父类的所有属性,因此域用户该有的属性,计算用户都有,甚至我们可以说,机器用户就是一种域用户。
那回到之前的那个问题,如果拿到一台域内机器,然后发现没有域内用户的情况。
我们上面说了,机器用户其实就是一个域用户,那我们怎么使用这个机器用户呢。
其实本地用户SYSTEM就对应于域内的机器用户,在域内的用户名就是机器名+$,比如win7,他的机器名是WIN7,那他在域内的登录名就是win7$,关于sAMAccountName我们在上一小节已经讲了。
所以我们可以将当前用户提到system(非管理员需要配合提权漏洞,管理员组的非administrators需要bypassuac,administrator提到system。
这个网上有很多方法,psexec,mimikatz等等)。
就可以在域内充当机器用户了。
或者直接抓hash 也是一样的。
2. 查找域内的所有机器
可以通过objectclass=Computer或者objectcategory=Computer查找域内的所有机器
adfind 对查询计算机,提供了一些快捷方式。
域内的域控都在Domain Controller这个OU底下,可以通过查看这个OU里面的机器来找到域内的所有域控。
adfind 对查询域控,也提供了一些快捷方式。
0x03 域用户账户与机器用户的对应关系
1. 域用户默认能登录域内的任何一台普通机器
如果我们是自己搭建过域环境的话,应该会知道,默认情况底下,域用户是能够登录域内的任何一台机器用户的。
我们在这里面探究一下原因。
在域成员机器的本地安全策略里面,默认情况底下,本地用户组允许本地登录。
其中包括Users组。
其中Users组包括Domain Users。
而域内用户默认都在Domain Users组里面。
因为域用户默认都在Domain Users组里面,而Domain Users在Users组里面。
默认情况底下Users组内的成员允许本地登录。
所以域内成员默认都能登录域内任何一台机器。
对于这种情况,很多域内都没有解决这个问题。
而有些域内运维意识到这个问题。
一般会有这两种修改方案。
(1) 在域用户这边做限制
设置域用户只允许登录到某台机器。
(2) 在机器这边做限制
这个可以通过下发组策略实现。
因为一般都会把常登陆这台机器的域用户加入到Administrators组里面。
不允许User组里面用户本地登录。
把下图的Users删除掉。
这样登陆这台机器的域用户,因为在Administrators组里面,也可以登录。
而其他域用户也不能登录。
2. 查看域用户能够登录的主机
域用户默认能本地登录域内的任何一台主机。
为了缓解这个问题。
上一小节我们提出了两种解决方案。
也会带来新的问题。
我们可以根据这个找到域用户能够登录的主机。
限制了域用户只能登录到某台主机之后,在LDAP里面,会设置一个字段,userWorkStation。
这个字段保存了这个域用户只能登录到某台机器。
而这个字段对于域内任何用户都是可读的,我们可以通过读域用户的userWorkStation来查看域用户限制登录到那一台机子。
那个用户也就能够登录那台机子。
3. 查看域用户正在登陆的主机
当我们想寻找一个域用户正在登陆的主机的情况下,主要有以下几种方式
-
检查远程机器注册表项里HKEY_USERS来查询谁正在登陆机器比如我们远程登录SERVER12的注册表,看到HKEY_USERS底下的key有S-1-5-21-1909611416-240434215-3714836602-1113,将S-1-5-21-1909611416-240434215-3714836602-1113这个sid转化为用户名是TEST\maria,就可以看到用户TEST\maria当前正在SERVER12这台机器上登录。
远程查看注册表项这个操作可以通过API实现,我们可以遍历域内所有机器,查询机器正在登陆的用户。
值得注意的有:
利用 NetSessionEnum 来寻找登陆的网络会话。
一个win32 API,关于这个API的细节可以看官方文档NetSessionEnum function。
NET_API_STATUS NET_API_FUNCTION NetSessionEnum(
LMSTR servername,
LMSTR UncClientName,
LMSTR username,
DWORD level,
LPBYTE *bufptr,
DWORD prefmaxlen,
LPDWORD entriesread,
LPDWORD totalentries,
LPDWORD resume_handle
);
这个API 的第一个参数servername ,可以指定一个远程的机器A,会去调用远程机器A的RPC。
然后返回其他用户在访问机器A的网络资源(例如文件共享)时所创建的网络会话,可以看到这个用户来自何处。
比如我们访问DC2016,会看到kangkang和jane 正在连接DC2016,而kangkang来自172.16.103.131,jane来自172.16.103.128
值得注意的有:
(1) 我们指定了servername 为机器A,并不能查询谁谁登陆了机器A,但是可以看到访问机器A的网络资源(例如文件共享)时所创建的网络会话。
这个网络会话可以看到哪个域用户来自哪个IP,比如kangkang来自172.16.103.131,所以我们一般指定servername为域控或者文件共享服务器。
(2) 调用此函数的用户,指定了servername 为机器A,并不需要在机器A 上有管理员权限。
所以域内任何用户都可以调用此函数,指定了servername 为域控。
利用NetWkstaUserEnum列出当前登录到该机器的所有用户的信息同样的,这也是一个WIN32 API,关于这个API的细节可以看官方文档NetWkstaUserEnum function
NET_API_STATUS NET_API_FUNCTION NetWkstaUserEnum(
LMSTR servername,
IN DWORD level,
LPBYTE *bufptr,
IN DWORD prefmaxlen,
LPDWORD entriesread,
LPDWORD totalentries,
LPDWORD resumehandle
);
这个API 的第一个参数servername 可以指定一个远程的机器A,会去调用远程机器A的RPC。
然后返回当前登录到机器A的所有用户的信息.值得注意的是,调用该函数的用户需要具备机器A的本地管理员权限。
有一些现有的工具用来枚举正在登陆某台机子的用户(一般称为枚举会话),其实本质上还是利用我们上面说的方法。
这里举例几个
(1) psloggedon.exe
(2) netsess.exe
(3) PVEFindADUser.exe
(4) hunter.exe
4. 查看域用户登录过的主机
-
通过查看outlook的邮件头当用户a 在公司内部使用outlook 给你发一封邮件的时候,我们可以在改邮件的头部看到用户a的内网IP
-
导出DC日志。
这个要求我们有域控权限,比如说我们在拿到域控之后想找到域内某个用户的主机。
域内用户A在机器B正常登录的时候,由于本地没有域用户A的hash。
机器B会去域控那边做验证,登录成功的话,在域控那边,会有个4624的日志,登录类型为3。
值得注意的是,在域内可能存在多台域控,日志并不同步,请将每一台域控的日志都导出来。
导出日志和查看日志有很多方式,这里提供一个实现。
导出日志,wevtutil是自带的
wevtutil epl Security C:\Users\Administrator\Desktop\1.evtx /q:“*[System[(EventID=4624)] and EventData[Data[@Name=‘LogonType’]=‘3’]]” //导出日志
将日志拷贝到我们的电脑.使用LogParser开始提取日志
LogParser.exe -i:EVT -o:CSV "SELECT TO_UPPERCASE(EXTRACT_TOKEN(Strings,5,'|')) as USERNAME,TO_UPPERCASE(EXTRACT_TOKEN(Strings,18,'|')) as SOURCE_IP FROM 1.evtx" >log.csv // 提取日志
「天億网络安全」 知识星球
一个网络安全学习的星球!星球主要
分享、整理、原创编辑等网络安全相关学习资料,一个真实有料的网络安全学习平台,大家共同学习、共同进步!
知识星球定价:
199元/年,
(服
务时间为一年,自加入日期顺延一年)。
如何加入:扫描下方二维码,扫码付费即可加入。
加入知识星球的同学,请加我微信,拉您进VIP交流群!