域控查看ldap端口命令_Windows内网协议学习LDAP篇之域用户和计算机用户介绍

86b9932adc6f3b7c0dbd917cec13f0d8.png

作者:daiker@360RedTeam

0x00 前言

这篇文章主要介绍AD里面的域用户,计算机用户。

0x01 域用户

1. 查询域用户

当我们拥有一个域用户的时候,想要枚举域内的所有用户,主要有两个方法。

(1) 通过SAMR 协议查询

samr 也不算是一种专门的协议,就是一个RPC接口(这里简单地提一下。后面在RPC篇里面详细介绍这个RPC接口)

我们平时使用的net user /domain就是使用samr 进行查询的。

fe862667b4a831f59cbc7f50a5becee1.png
875909a61b06f38519bacf3a58b5774a.png

在impacket 里面有一个脚本samrdump.py就是专门调用samr 去查询域用户的。

4de4c91632482c65ca957fc75c1fea2a.png

(2) 通过Ldap 语法查询

域用户存储于活动目录数据库里面,对其他用户可见。可以通过Ldap 去查询。

过滤语法如下

(&(objectCategory=person)(objectClass=user))
5d574073d74ed358d1804366d513ef8c.png
4cfff15515764a7506de89550801bd81.png

2. 域用户部分属性介绍

  • ● 相关的用户名
deaf34229e4b99a4fb241139deb11e97.png

这些属性在LDAP 里面都可以查看

(1)姓对应的属性就是sn

e33d38eaf04107c37158ea49509275a1.png

(2) 名对应的属性是giveName

69152ac77ed09349c1fd039e9c71fefe.png

(3)展示名,对应的属性是displayName。

4d0ced08a4f02c8c46c13ad524fc3114.png
c9ab4d5aca79eee72dd4001f62cabb73.png

值得注意的是,displayName不能用于登陆,虽然跟域用户名往往一样。但是这个不是直接用于登陆的我们登陆用的账号,在一些公司里面,displayName往往是中文,登陆的用户名是拼音。登陆的格式有以下两种格式。

ed6d0011d0c5b60f0c390a22c44778d5.png

(4)第一种格式是UserPrincipalName,我们简称为UPN,一般的格式是用户名@域名这样的格式。

比如这里就是lisi@test.local

61bee6a5736b9d4a30561dc7b171cc91.png
0e294d55e9c65236b94e008414131ad9.png

(5) 第二种格式是域名sAMAccountName这种格式

比如这里就是test.locallisi,这里的域名可以是netbios名,也可以是dns 名。

65a874d9c0cf5842c84b0cee7cba1618.png
fb25a8737951283b10a0fad4c48bf601.png
  • ● 用户相关的一些时间· whenCreated· pwdLastSet· Lastlogon看名字就可以大约猜出这些字段的含义了。账号创建时间,设置密码时间,上次登录时间,这些属性任意域用户都可以看的到。只是这个并不直观,adfind 提供了转化。这样更直观一点值得注意的是Lastlogon这个属性值在不同的域控制器上是不会同步的。所以要查询一个用户的最后登录时间,得指定不同的域控制器来查询。
  • ● userAccountControl

在上一篇,讲位操作的时候有简单提及到这个userAccountControl,其实这个属性至关重要。在整个系列文章里面反复提及。userAccountControl对应的位如下。

33212029005389b21b2eabd7551c0d05.png

我们可以利用ldap的位操作(关于Ldap的位操作见Windows内网协议学习LDAP篇之组和OU介绍)来一个个过滤。

比如,我们想查询查询密码永不过期的用户。

8680409b9df3d3ee8f060fd57d7be9bd.png
3d44cbe0df894ee3156c5f820d3c6d50.png

又比如,我们想查询设置了约束委派的用户。

d83b534cc37e9224cc23f4217b715357.png
b38d5d8f9e408c3e22dba8a7533deea2.png

又比如,我们想查询域内设置了对委派敏感的用户。

fbb81ae1c895893a70ad131a652689a5.png
87089ca953b3b6e880fee93e6f30ef27.png

等等等。大家可以查表,然后更改对应的十进制值来过滤。

0x02 机器用户

默认情况底下,加入域的机器默认在CN=Computer这个容器里面,域控默认在Domain Controllers这个OU里面。有些域内会通过redircmp进行修改

62cfb01d0226f23a4822cde2ad82f7ae.png

1. 机器用户跟system 用户的关系

考虑到这样一个场景,如果拿到一台域内机器,然后发现没有域内用户。 这个时候有很多人用mimikatz 抓一下,没抓到域用户,就束手无策了。

我们随便点开一台Domain Computer,这里以WIN7这台机子做为测试。

e8ce8493e5ae36cac23d45d6f0af342a.png

我们看他的对象类。

7ce67b77e56c5521cbadec3d43617243.png

发现他是computer 类的实例。

而computer 类的user 类的子类。域用户是user类的实例。之前我们说过类是属性的集合。子类继承了父类的所有属性,因此域用户该有的属性,计算用户都有,甚至我们可以说,机器用户就是一种域用户。

那回到之前的那个问题,如果拿到一台域内机器,然后发现没有域内用户的情况。我们上面说了,机器用户其实就是一个域用户,那我们怎么使用这个机器用户呢。其实本地用户SYSTEM就对应于域内的机器用户,在域内的用户名就是机器名+$,比如win7,他的机器名是WIN7,那他在域内的登录名就是win7$,关于sAMAccountName我们在上一小节已经讲了。

1cc8789dbc283720d61dfddf7c8dae66.png

所以我们可以将当前用户提到system(非管理员需要配合提权漏洞,管理员组的非administrators需要bypassuac,administrator提到system。这个网上有很多方法,psexec,mimikatz等等)。就可以在域内充当机器用户了。

34ac3f7c998ea8e77575e8db2471a96f.png

或者直接抓hash 也是一样的。

fc78a9c5fbcdcc30a346c21cbab0fae9.png

2. 查找域内的所有机器

可以通过objectclass=Computer或者objectcategory=Computer查找域内的所有机器

5f28c76115b98a9fd7635af71f72d832.png

adfind 对查询计算机,提供了一些快捷方式。

0f7f282a2dcae845428e504cb04d4dd9.png
c65ad40439ff9b105e0900ec5f92c3f7.png

域内的域控都在Domain Controller这个OU底下,可以通过查看这个OU里面的机器来找到域内的所有域控。

c065b8717f1301566d89776d22631107.png

adfind 对查询域控,也提供了一些快捷方式。

960b53aabece2e76daf3b24d47d75923.png
1e5f0a614ffdb438ece7c117faad5469.png
56d6ad360dd68790eb91330c3b46580a.png

0x03 域用户账户与机器用户的对应关系

1. 域用户默认能登录域内的任何一台普通机器

如果我们是自己搭建过域环境的话,应该会知道,默认情况底下,域用户是能够登录域内的任何一台机器用户的。我们在这里面探究一下原因。

在域成员机器的本地安全策略里面,默认情况底下,本地用户组允许本地登录。其中包括Users组。

e82705bf0fd97f1782d62c425e0b3a4d.png

其中Users组包括Domain Users。

872448721e008c6cd2d967bc20cd9172.png

而域内用户默认都在Domain Users组里面。

因为域用户默认都在Domain Users组里面,而Domain Users在Users组里面。默认情况底下Users组内的成员允许本地登录。所以域内成员默认都能登录域内任何一台机器。

对于这种情况,很多域内都没有解决这个问题。而有些域内运维意识到这个问题。一般会有这两种修改方案。

(1) 在域用户这边做限制

4d1a7fe37eb487ce303d0fb9c90a7a96.png

设置域用户只允许登录到某台机器。

(2) 在机器这边做限制

这个可以通过下发组策略实现。

因为一般都会把常登陆这台机器的域用户加入到Administrators组里面。不允许User组里面用户本地登录。把下图的Users删除掉。这样登陆这台机器的域用户,因为在Administrators组里面,也可以登录。而其他域用户也不能登录。

e82705bf0fd97f1782d62c425e0b3a4d.png

2. 查看域用户能够登录的主机

域用户默认能本地登录域内的任何一台主机。为了缓解这个问题。上一小节我们提出了两种解决方案。也会带来新的问题。我们可以根据这个找到域用户能够登录的主机。限制了域用户只能登录到某台主机之后,在LDAP里面,会设置一个字段,userWorkStation。这个字段保存了这个域用户只能登录到某台机器。而这个字段对于域内任何用户都是可读的,我们可以通过读域用户的userWorkStation来查看域用户限制登录到那一台机子。那个用户也就能够登录那台机子。

98d6db0818d1a36aa43ec1a11fa8cf4e.png

3. 查看域用户正在登陆的主机

当我们想寻找一个域用户正在登陆的主机的情况下,主要有以下几种方式

  1. 检查远程机器注册表项里HKEY_USERS来查询谁正在登陆机器比如我们远程登录SERVER12的注册表,看到HKEY_USERS底下的key有S-1-5-21-1909611416-240434215-3714836602-1113,将S-1-5-21-1909611416-240434215-3714836602-1113这个sid转化为用户名是TESTmaria,就可以看到用户TESTmaria当前正在SERVER12这台机器上登录。远程查看注册表项这个操作可以通过API实现,我们可以遍历域内所有机器,查询机器正在登陆的用户。值得注意的有:(1) 默认PC机器,是没有开启注册表远程连接的。Server 机器,默认开启远程连接。(2) 域内任何用户,即使配置了,不能本地登录域内机器A,但是只要域内机器A开启远程注册表连接,我们就可以连接上机器A的注册表,从而枚举正在登陆的用户
  2. 利用 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 为域控。
  3. 利用NetWkstaUserEnum列出当前登录到该机器的所有用户的信息同样的,这也是一个WIN32 API,关于这个API的细节可以看官方文档NetWkstaUserEnum functionNET_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

c633b1605b3003d3e657cd05238c280b.png

(2) netsess.exe

91d9ed75d9b5c3ccdb4ada81b201cb97.png

(3) PVEFindADUser.exe

6a5676e8097c1be741f18e7b1e65684b.png

(4) hunter.exe

eaaa8fff4c91abd36aa7b80712d0211f.png

4. 查看域用户登录过的主机

  1. 通过查看outlook的邮件头当用户a 在公司内部使用outlook 给你发一封邮件的时候,我们可以在改邮件的头部看到用户a的内网IP
  2. 导出DC日志。

这个要求我们有域控权限,比如说我们在拿到域控之后想找到域内某个用户的主机。

域内用户A在机器B正常登录的时候,由于本地没有域用户A的hash。机器B会去域控那边做验证,登录成功的话,在域控那边,会有个4624的日志,登录类型为3。

465188df9b7a29e29830fad8f5d9e018.png

值得注意的是,在域内可能存在多台域控,日志并不同步,请将每一台域控的日志都导出来。导出日志和查看日志有很多方式,这里提供一个实现。

导出日志,wevtutil是自带的

wevtutil epl Security C:甥敳獲AdministratorDesktop1.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 // 提取日志
3df861605133b8c966a5576f9c714de9.png

原文链接:https://www.anquanke.com/post/id/196510

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要通过Java使用LDAP获取AD用户和组织信息,需要使用Java的JNDI API。 以下是一个简单的Java程序,演示如何使用JNDI API连接到AD并获取用户和组织信息: ``` import java.util.*; import javax.naming.*; import javax.naming.directory.*; public class ADInfo { public static void main(String[] args) { String ldapURL = "ldap://AD服务器地址:389"; String ldapUser = "CN=LDAP查询用户,OU=xxx,DC=xxx,DC=xxx"; String ldapPassword = "LDAP查询用户密码"; String searchBase = "OU=xxx,DC=xxx,DC=xxx"; Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, ldapURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, ldapUser); env.put(Context.SECURITY_CREDENTIALS, ldapPassword); try { DirContext ctx = new InitialDirContext(env); SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(objectCategory=user)"; NamingEnumeration<SearchResult> results = ctx.search(searchBase, filter, searchControls); while (results.hasMore()) { SearchResult searchResult = results.next(); Attributes attributes = searchResult.getAttributes(); Attribute attribute = attributes.get("cn"); String cn = (String) attribute.get(); System.out.println(cn); } filter = "(objectCategory=organizationalUnit)"; results = ctx.search(searchBase, filter, searchControls); while (results.hasMore()) { SearchResult searchResult = results.next(); Attributes attributes = searchResult.getAttributes(); Attribute attribute = attributes.get("ou"); String ou = (String) attribute.get(); System.out.println(ou); } ctx.close(); } catch (NamingException e) { e.printStackTrace(); } } } ``` 在上面的代码中,替换以下变量: - ldapURL:AD服务器地址和端口号 - ldapUser:用于查询ADLDAP用户的DN - ldapPassword:用于查询ADLDAP用户的密码 - searchBase:要搜索的AD的基本DN 该程序连接到AD并搜索用户和组织。它使用过滤器来限制搜索结果,只搜索用户和组织单位对象。它还使用SearchControls对象来设置搜索范围。 对于每个搜索结果,程序从属性中提取cn或ou,并将其打印到控制台上。 请注意,此代码需要在Java应用程序中包含JNDI API类路径。如果您使用Maven或Gradle之类的构建工具,则可以将以下依赖项添加到项目中: ``` <dependency> <groupId>com.sun.jndi</groupId> <artifactId>ldap</artifactId> <version>1.2.1</version> </dependency> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值