0x00 前言
我们有时候可能会遇到这样的环境:通过钓鱼或其他手段进入目标的内网,所处机器权限为工作组环境。通过内网存活探测,发现存在域环境,但当前没有用户凭证,域内个人机清一色 Win 10+,后续成功定位到域控及 ADCS。但是,针对域控无凭证利用的 ZeroLogin 漏洞已经被修复了。那么有朋友跳出来说,中继呢?说实话,除了 PetitPotam 不需要凭证,其他强认证工具是需要带上凭证的。经过测试,不知道是不是域控无法到达我们当前所在段还是被修复了(2022年初被修复)。那么又有朋友说了,那打域控同段啊,嗯嗯嗯,大佬说得对,只是条件有限,小弟打不下来而已。
那么接下来怎么办呢?首先,得先搞一个域凭证(当然,这不是绝对的),后续用于 ADCS 漏洞及其他 AD 域漏洞利用。那么该怎么搞用户凭证呢?这也是本篇文章要说的,思路也很简单,首先肯定要找域用户名,才能进行密码爆破。那么怎么找域用户名呢?如果目标存在邮件服务还好说,直接爬公网能爬到的邮箱,再进行用户名的验证。既然已经收集到了邮箱,为什么还需要验证用户名呢?这还要问的吗?嗯?那还不是因为它不是 Exchange 的缘故吗,如果内网使用 ADDC,又不使用 Exchange,多半只是刚开始时同步了一次 LDAP,因此需要做用户名的验证。如果没有邮服,那只能字典了。
0x01 Kerberos 的 AS_REQ
了解 ADDC Kerberos 协议的同学都知道,关于 AD 域涉及服务的认证,都是通过 Kerberos 进行认证的(域内域外均由 Kerberos 完成)。而 Kerberos 的认证大概分为几个步骤:
1.不带预认证数据的 AS_REQ/Error;2.带预认证数据的 AS_REQ/AS_REP;3.TGS_REQ/TGS_REP;
下面使用 Wireshark
抓取用户登录的流量包进行分析。
1.1 第一个 AS_REQ
我们重点来看第一个 AS_REQ 请求,抓取的流量包如下所示:
这就是一个正常的请求包,具体内容如下所示:
pvno:Kerberos 协议版本号 (5)
msg-type:应用程序类标记号 (10),简单来说就是消息类型
padata:仅包含 PA-PAC-REQUEST 结构的预认证数据
kdc-options:票据请求的标志(可转发、可更新、规范化、可再生)
cname:包含被认证的用户名
realm:域名
sname:请求的服务名称
till:请求的票据的到期时间
rtime:如果请求的是可更新的票据,则该字段包含票据所需的过期时间
nonce:消息随机数
etype:请求的加密类型
addresses:客户端地址
1.2 KRB Error
接下来我们来看它的返回:
从返回的错误数据包可以得到以下信息:
•该用户需要“预认证”,并在请求中未找到所需 "paddata"。•请求的用户在 DC 中存在,并额外返回 "e-data"。
这里列出 3 个常见的错误:
错误 | 定义 | 错误代码 |
KRB5DC_ERR_PREAUTH_REQUIRED | 需要额外的预认证,表示用户存在 | 25 |
KRB5DC_ERR_CLIENT_REVOKED | 客户端凭证已被吊销,表示用户已被禁用 | |
KRB5DC_ERR_C_PRINCIPAL_UNKNOWN | 在 Kerberos 数据库中找不到客户端信息,表示用户不存在 | 6 |
[1]因此,如果要编写工具,我们在组装 Kerberos 数据包的时候,根据上面第一个 AS_REQ 进行组装,然后给 ADDC 进行发送,根据返回错误来判断用户是否存在于域内。
0x02 现有工具
现在有几个很成熟的工具,它们包括但不限于:
1.使用 Go 编写的 kerbrute[2];2.使用 Python 编写的 pyKerbrute[3];
在这里我只介绍 kerbrute 的用户枚举功能:
不存在的用户,直接返回 KRB5DC_ERR_C_PRINCIPAL_UNKNOWN **错误。**
0x03 使用 Csharp 编写工具
至于我为什么要重新造轮子,那是因为关于内网渗透的工具我都是使用 C# 进行编写。除非能力不行,实现不了,否则在学习过后都会落地工具,达到知识 + 工具的落地。由于在 Kerberos 的请求及处理,Rubeus[4] 已经写得很好了,当前学习 Kerberos 时也是通过该源码进行学习的,因此在实现这个功能时,直接从 Rubeus 扣就行。
3.1 AS_REQ 结构
//AS-REQ ::= [APPLICATION 10] KDC-REQ
//KDC-REQ ::= SEQUENCE {
// -- NOTE: first tag is [1], not [0]
// pvno [1] INTEGER (5) ,
// msg-type [2] INTEGER (10 -- AS),
// padata [3] SEQUENCE OF PA-DATA OPTIONAL
// -- NOTE: not empty --,
// req-body [4] KDC-REQ-BODY
//}
使用 C# 表示为:
public calss AS_REQ()
{
public long pvno = 5;
public long msg_type = 10;
public PA_DATA padata;
public KDCReqBody req_body;
}
3.1.1 PA-DATA 结构
其中,padata 的结构固定为:
public PA_DATA()
{
public long type = 128;
// 固定值为:0x30, 0x05, 0xa0, 0x03, 0x01, 0x01, 0x01
public Object value = new KERB_PA_PAC_REQUEST()
{
public bool include_pac = true;
};
}
3.1.2 REQ-BODY 结构
KDC-REQ-BODY::= SEQUENCE {
kdc-options[0] KDCOptions,
cname[1] PrincipalName OPTIONAL
-- Used only in AS-REQ --,
realm[2] Realm
-- Server's realm
-- Also client's in AS-REQ --,
sname[3] PrincipalName OPTIONAL,
from[4] KerberosTime OPTIONAL,
till[5] KerberosTime,
rtime[6] KerberosTime OPTIONAL,
nonce[7] UInt32,
etype[8] SEQUENCE OF Int32 -- EncryptionType
-- in preference order --,
addresses[9] HostAddresses OPTIONAL,
enc-authorization-data[10] EncryptedData OPTIONAL
-- AuthorizationData --,
additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
-- NOTE: not empty
}
使用 C# 表示为:
public KDCReqBody(string domain, string user)
{
public uint kdc-options = 40810010; // FORWARDABLE(0x40000000) | RENEWABLE(0x00800000) | CANONICALIZE(0x00010000) | RENEWABLEOK(0x00000010)
public PrincipalName cname = new PrincipalName()
{
public long name_type = 1;
public List<string> cname_string = new byte[]{ user }; // 用户名
}
public string realm = domain; // 域名
public PrincipalName sname = new PrincipalName()
{
public long name_type = 2;
public List<string> sname_string = new byte[]{"krbtgt", domain};
}
public DateTime till = ;
public DateTime rtime = ;
public uint nonce = 123456; // 随机数
public List<T> etypes = new List<T>();
public HostAddress addresses = new HostAddress();
}
效果如下所示:
相关源码我已经放在星球里了。有能力的同学自己扣扣就好了,很简单的。
0x04 总结
要完成爆破,那么肯定是需要先找到用户名,才拥有爆破的基础条件。至此,获取域内凭证的第一步就这样完成了。接下来就是爆破密码了、
References
[1]
: https://blog.csdn.net/m0_57221101/article/details/124172466[2]
kerbrute: https://github.com/ropnop/kerbrute/releases[3]
pyKerbrute: https://github.com/3gstudent/pyKerbrute[4]
Rubeus: https://github.com/GhostPack/Rubeus
原文始发于微信公众号(RowTeam):【域渗透】域用户枚举
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论