@@ -51,7 +51,7 @@ BOOL RunningAsLocalSystem();
51
51
52
52
void CleanUpInteractiveProcess (CleanupInteractive* pCI)
53
53
{
54
- SetTokenInformation (pCI->hUser , TokenSessionId, &pCI->origSessionID , sizeof (pCI->origSessionID ));
54
+ // SetTokenInformation(pCI->hUser, TokenSessionId, &pCI->origSessionID, sizeof(pCI->origSessionID));
55
55
56
56
// // Allow logon SID full access to interactive window station.
57
57
// RemoveAceFromWindowStation(hwinsta, pSid);
@@ -74,47 +74,83 @@ void CleanUpInteractiveProcess(CleanupInteractive* pCI)
74
74
// hdesk = NULL;
75
75
}
76
76
77
- BOOL PrepForInteractiveProcess (Settings& settings, CleanupInteractive* pCI, DWORD sessionID)
77
+ BOOL CALLBACK EnumWindowStationsProc (LPWSTR lpszWindowStation, LPARAM lParam)
78
78
{
79
- pCI->bPreped = true ;
80
- // settings.hUser is set as the -u user, Local System (from -s) or as the account the user originally launched PAExec with
79
+ Log (StrFormat (L" Seen winstation: %s" , lpszWindowStation), (DWORD)0 );
80
+ return TRUE ;
81
+ }
81
82
82
- // figure out which session we need to go into
83
- Duplicate (settings.hUser , __FILE__, __LINE__);
84
- pCI->hUser = settings.hUser ;
85
83
86
- DWORD targetSessionID = sessionID;
84
+ BOOL PrepForInteractiveProcess (Settings& settings, CleanupInteractive* pCI)
85
+ {
86
+ EnablePrivilege (SE_TCB_NAME, NULL );
87
+
88
+ pCI->bPreped = true ;
89
+
90
+ // settings.hUser is already set as the -u user, Local System (from -s) or as the account the user originally launched PAExec with
87
91
92
+ // figure out which session we need to go into
88
93
if ((DWORD)-1 == settings.sessionToInteractWith )
89
94
{
90
- targetSessionID = GetInteractiveSessionID ();
91
- Log (StrFormat (L" Using SessionID %u (interactive session)" , targetSessionID ), false );
95
+ settings. sessionToInteractWith = GetInteractiveSessionID ();
96
+ Log (StrFormat (L" Using SessionID %u (interactive session)" , settings. sessionToInteractWith ), false );
92
97
}
93
98
else
94
- Log (StrFormat (L" Using SessionID %u from params" , targetSessionID ), false );
99
+ Log (StrFormat (L" Using SessionID %u from params" , settings. sessionToInteractWith ), false );
95
100
96
- // if(FALSE == WTSQueryUserToken(targetSessionID, &settings.hUser))
97
- // Log(L"Failed to get user from session ", GetLastError());
101
+ if (settings.user .IsEmpty ())
102
+ {
103
+ if (settings.bUseSystemAccount )
104
+ {
105
+ HANDLE hProcessToken = INVALID_HANDLE_VALUE;
106
+ OpenProcessToken (GetCurrentProcess (), MAXIMUM_ALLOWED, &hProcessToken);
107
+ DuplicateTokenToIncreaseRights (hProcessToken, __FILE__, __LINE__);
108
+ SetTokenInformation (hProcessToken, TokenSessionId, &settings.sessionToInteractWith , sizeof (DWORD));
109
+ settings.hUser = hProcessToken;
110
+ return TRUE ;
111
+ }
98
112
99
- // Duplicate(settings.hUser, __FILE__, __LINE__);
113
+ // no user given, but want interactive, so run as the currently logged in user
114
+ HANDLE hTmp = INVALID_HANDLE_VALUE;
115
+ if ((FALSE == WTSQueryUserToken (settings.sessionToInteractWith , &hTmp)) || (INVALID_HANDLE_VALUE == hTmp))
116
+ Log (StrFormat (L" WTSQueryUserToken failed for session ID %d" , settings.sessionToInteractWith ), GetLastError ());
100
117
101
- DWORD returnedLen = 0 ;
102
- GetTokenInformation (settings.hUser , TokenSessionId, &pCI->origSessionID , sizeof (pCI->origSessionID ), &returnedLen);
118
+ if (INVALID_HANDLE_VALUE != hTmp)
119
+ {
120
+ Log (L" Using user from WTSQueryUserToken" , (DWORD)0 );
121
+ settings.hUser = hTmp;
122
+ DuplicateTokenToIncreaseRights (settings.hUser , __FILE__, __LINE__);
123
+ }
124
+ return TRUE ;
125
+ }
103
126
104
- EnablePrivilege (SE_TCB_NAME, settings.hUser );
127
+ // This is the hard case - interactive with a specific user. Not sure why it doesn't work better
128
+
129
+ DuplicateTokenToIncreaseRights (settings.hUser , __FILE__, __LINE__);
130
+ pCI->hUser = settings.hUser ;
105
131
106
- if (FALSE == SetTokenInformation (settings.hUser , TokenSessionId, &targetSessionID, sizeof (targetSessionID)))
132
+ // DWORD returnedLen = 0;
133
+ // if(FALSE == GetTokenInformation(settings.hUser, TokenSessionId, &pCI->origSessionID, sizeof(pCI->origSessionID), &returnedLen))
134
+ // Log(L"GetTokenInformation failed", GetLastError());
135
+
136
+ if (false == EnablePrivilege (SE_TCB_NAME, settings.hUser ))
137
+ Log (L" EnablePrivilege failed" , GetLastError ());
138
+
139
+ if (FALSE == SetTokenInformation (settings.hUser , TokenSessionId, &settings.sessionToInteractWith , sizeof (settings.sessionToInteractWith )))
107
140
Log (L" Failed to set interactive token" , GetLastError ());
108
141
109
142
return TRUE ;
110
- // //START FUNKY STUFF
143
+
144
+ // //START FUNKY STUFF - probably doesn't work because OpenWindowStation will get PAExec's Window Station in session 0, which is not what we want
145
+
111
146
// BOOL bResult = FALSE;
112
147
//
113
148
// HDESK hdesk = NULL;
114
149
// HWINSTA hwinsta = NULL;
115
150
// PSID pSid = NULL;
116
151
// HWINSTA hwinstaSave = NULL;
117
- //
152
+ // USEROBJECTFLAGS uof = { 0 };
153
+ // DWORD needed = 0;
118
154
//
119
155
// // Save a handle to the caller's current window station.
120
156
// if ((hwinstaSave = GetProcessWindowStation()) == NULL)
@@ -123,18 +159,28 @@ BOOL PrepForInteractiveProcess(Settings& settings, CleanupInteractive* pCI, DWOR
123
159
// goto Cleanup;
124
160
// }
125
161
//
162
+ // LPCWSTR winStaToUse = L"WinSta0";
163
+ //
126
164
// // Get a handle to the interactive window station.
127
165
// hwinsta = OpenWindowStation(
128
- // _T("winsta0"), // the interactive window station
166
+ // winStaToUse, // the interactive window station
129
167
// FALSE, // handle is not inheritable
130
- // READ_CONTROL | WRITE_DAC); // rights to read/write the DACL
168
+ // READ_CONTROL | WRITE_DAC | WINSTA_READATTRIBUTES ); // rights to read/write the DACL
131
169
//
132
170
// if (BAD_HANDLE(hwinsta))
133
171
// {
134
- // Log(L"Failed to open winsta0.", GetLastError());
172
+ // Log(StrFormat(L"Failed to open WinStation %s.", winStaToUse), GetLastError());
173
+ // EnumWindowStations(EnumWindowStationsProc, NULL);
174
+ //
135
175
// goto Cleanup;
136
176
// }
137
177
//
178
+ // //Some logging
179
+ // if(GetUserObjectInformation(hwinsta, UOI_FLAGS, &uof, sizeof(uof), &needed))
180
+ // Log(StrFormat(L"WinStation visible: %d", uof.dwFlags), (DWORD)0);
181
+ // else
182
+ // Log(L"GetUserObjectInformation failed", GetLastError());
183
+ //
138
184
// // To get the correct default desktop, set the caller's
139
185
// // window station to the interactive window station.
140
186
// if (!SetProcessWindowStation(hwinsta))
@@ -195,8 +241,8 @@ BOOL PrepForInteractiveProcess(Settings& settings, CleanupInteractive* pCI, DWOR
195
241
// bResult = TRUE;
196
242
//
197
243
// Cleanup:
198
- // if (!BAD_HANDLE(hwinstaSave))
199
- // SetProcessWindowStation (hwinstaSave);
244
+ // // if (!BAD_HANDLE(hwinstaSave))
245
+ // // SetProcessWindowStation (hwinstaSave);
200
246
//
201
247
// return bResult;
202
248
}
@@ -1127,7 +1173,7 @@ typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdProc)(void);
1127
1173
DWORD GetInteractiveSessionID ()
1128
1174
{
1129
1175
// Get the active session ID.
1130
- DWORD SessionId = 0 ;
1176
+ DWORD SessionId = (DWORD)- 1 ;
1131
1177
PWTS_SESSION_INFO pSessionInfo;
1132
1178
DWORD Count = 0 ;
1133
1179
@@ -1136,30 +1182,34 @@ DWORD GetInteractiveSessionID()
1136
1182
for (DWORD i = 0 ; i < Count; i ++)
1137
1183
{
1138
1184
if (pSessionInfo [i].State == WTSActive) // Here is
1139
- {
1140
- SessionId = pSessionInfo [i].SessionId ;
1141
- }
1185
+ SessionId = pSessionInfo[i].SessionId ;
1142
1186
}
1143
1187
WTSFreeMemory (pSessionInfo);
1144
1188
}
1145
1189
1146
- if (0 == SessionId)
1190
+ static WTSGetActiveConsoleSessionIdProc pWTSGetActiveConsoleSessionId = NULL ;
1191
+ if (NULL == pWTSGetActiveConsoleSessionId)
1147
1192
{
1148
- static WTSGetActiveConsoleSessionIdProc pWTSGetActiveConsoleSessionId = NULL ;
1149
- if (NULL == pWTSGetActiveConsoleSessionId )
1193
+ HMODULE hMod = LoadLibrary ( L" Kernel32.dll " ); // GLOK
1194
+ if (NULL != hMod )
1150
1195
{
1151
- HMODULE hMod = LoadLibrary (L" Kernel32.dll" ); // GLOK
1152
- if (NULL != hMod)
1153
- {
1154
- pWTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdProc)GetProcAddress (hMod, " WTSGetActiveConsoleSessionId" );
1155
- }
1196
+ pWTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdProc)GetProcAddress (hMod, " WTSGetActiveConsoleSessionId" );
1156
1197
}
1198
+ }
1157
1199
1158
- if (NULL != pWTSGetActiveConsoleSessionId) // not supported on Win2K
1159
- SessionId = pWTSGetActiveConsoleSessionId (); // we fall back on this if needed since it apparently doesn't always work
1200
+ if (NULL != pWTSGetActiveConsoleSessionId) // not supported on Win2K
1201
+ {
1202
+ DWORD tmp = pWTSGetActiveConsoleSessionId (); // we fall back on this if needed since it apparently doesn't always work
1203
+ if (0 == SessionId)
1204
+ SessionId = tmp;
1160
1205
else
1161
- Log (L" WTSGetActiveConsoleSessionId not supported on this OS" , false );
1206
+ {
1207
+ if (tmp != SessionId)
1208
+ Log (StrFormat (L" WTSEnumerateSessions found session ID %u, but WTSGetActiveConsoleSessionId returned %u. Using %u." , SessionId, tmp, SessionId), (DWORD)0 );
1209
+ }
1162
1210
}
1211
+ else
1212
+ Log (L" WTSGetActiveConsoleSessionId not supported on this OS" , false );
1163
1213
1164
1214
return SessionId;
1165
1215
}
0 commit comments