Skip to content

Commit 2092dc0

Browse files
committed
[WINLOGON][HACK] Allow network services access to default window station
HHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCCCCCCCCCCCCCCKKKKKKKKKKKKKKKKKK!!! There are two problems concerning with network services. First, a window station should be created for every network service process that gets started although this doesn't happen. Instead, network services like RPCSS and DNS service host process (svchost.exe) attempt to access the default window station (Winsta0). This is because the access token of these two network service processes have an authentication ID that is uniquely generated. This is incorrect, because NetworkService is a special account with its own designed authentication ID for it. As a matter of fact, no window station is created for a network service and as such both RPCSS and DNS svchost.exe attempt to access Winsta0 which they cannot. The second problem, albeit not quite relevant to the first one but still worth mentioning nevertheless, is that network services have an access token that is primary which it should be an impersonation token. These problems all come from LSASS as LSA infrastructure is responsible for creating access tokens with security context for objects. For the moment being, add a hack on Winlogon that gives allow access to the default window station to network services. When LSASS and involved components are fixed, this hack must be removed.
1 parent f96c39f commit 2092dc0

File tree

1 file changed

+183
-8
lines changed

1 file changed

+183
-8
lines changed

base/system/winlogon/security.c

Lines changed: 183 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ CreateWinstaSecurity(
115115
BOOL Success = FALSE;
116116
SECURITY_DESCRIPTOR AbsoluteSd;
117117
PSECURITY_DESCRIPTOR RelativeSd = NULL;
118-
PSID WinlogonSid = NULL, AdminsSid = NULL;
118+
PSID WinlogonSid = NULL, AdminsSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment below for information */
119119
DWORD DaclSize;
120120
PACL Dacl;
121121

@@ -142,18 +142,62 @@ CreateWinstaSecurity(
142142
goto Quit;
143143
}
144144

145+
/* HACK: Create the network service SID */
146+
if (!AllocateAndInitializeSid(&NtAuthority,
147+
1,
148+
SECURITY_NETWORK_SERVICE_RID,
149+
0, 0, 0, 0, 0, 0, 0,
150+
&NetworkServiceSid))
151+
{
152+
ERR("CreateWinstaSecurity(): Failed to create the network service SID (error code %lu)\n", GetLastError());
153+
goto Quit;
154+
}
155+
145156
/*
146157
* Build up the DACL size. This includes a number
147158
* of four ACEs of two different SIDs. The first two
148159
* ACEs give both window station and generic access
149160
* to Winlogon, the last two give limited window station
150161
* and desktop access to admins.
162+
*
163+
* ===================== !!!MUST READ!!! =====================
164+
*
165+
* HACK -- Include in the DACL two more ACEs for network
166+
* service SID. Network services will be granted full
167+
* access to the default window station. Whilst technically
168+
* services that are either network or local ones are part
169+
* and act on behalf of the system, what we are doing here
170+
* is a hack because of two reasons:
171+
*
172+
* 1) Winlogon does not allow default window station (Winsta0)
173+
* access to network services on Windows. As a matter of fact,
174+
* network services must access their own service window station
175+
* (aka Service-0x0-3e4$) which never gets created. Why it never
176+
* gets created is explained on the second point.
177+
*
178+
* 2) Our LSASS terribly lacks in code that handles special logon
179+
* service types, NetworkService and LocalService. For this reason
180+
* whenever an access token is created for a network service process
181+
* for example, its authentication ID (aka LogonId represented as a LUID)
182+
* is a uniquely generated ID by LSASS for this process. This is wrong
183+
* on so many levels, partly because a network service is not a regular
184+
* service and network services have their own special authentication logon
185+
* ID (with its respective LUID as {0x3e4, 0x0}). On top of that, a network
186+
* service process must have an impersonation token but for whatever reason
187+
* we are creating a primary access token instead.
188+
*
189+
* FOR ANYONE WHO'S INTERESTED ON FIXING THIS, DO NOT FORGET TO REMOVE THIS
190+
* HACK!!!
191+
*
192+
* =========================== !!!END!!! ================================
151193
*/
152194
DaclSize = sizeof(ACL) +
153195
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(WinlogonSid) +
154196
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(WinlogonSid) +
155197
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid) +
156-
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid);
198+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid) +
199+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid) +
200+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid);
157201

158202
/* Allocate the DACL now */
159203
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
@@ -216,6 +260,28 @@ CreateWinstaSecurity(
216260
goto Quit;
217261
}
218262

263+
/* HACK: Fifth ACE -- give full access to network services */
264+
if (!AddAccessAllowedAceEx(Dacl,
265+
ACL_REVISION,
266+
NO_PROPAGATE_INHERIT_ACE,
267+
WINSTA_ALL,
268+
NetworkServiceSid))
269+
{
270+
ERR("CreateWinstaSecurity(): Failed to set ACE for network service (error code %lu)\n", GetLastError());
271+
goto Quit;
272+
}
273+
274+
/* HACK: Sixth ACE -- give full generic access to network services */
275+
if (!AddAccessAllowedAceEx(Dacl,
276+
ACL_REVISION,
277+
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
278+
GENERIC_ACCESS,
279+
NetworkServiceSid))
280+
{
281+
ERR("CreateWinstaSecurity(): Failed to set ACE for network service (error code %lu)\n", GetLastError());
282+
goto Quit;
283+
}
284+
219285
/* Initialize the security descriptor */
220286
if (!InitializeSecurityDescriptor(&AbsoluteSd, SECURITY_DESCRIPTOR_REVISION))
221287
{
@@ -253,6 +319,13 @@ CreateWinstaSecurity(
253319
FreeSid(AdminsSid);
254320
}
255321

322+
/* HACK */
323+
if (NetworkServiceSid != NULL)
324+
{
325+
FreeSid(NetworkServiceSid);
326+
}
327+
/* END HACK */
328+
256329
if (Dacl != NULL)
257330
{
258331
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
@@ -289,7 +362,7 @@ CreateApplicationDesktopSecurity(
289362
BOOL Success = FALSE;
290363
SECURITY_DESCRIPTOR AbsoluteSd;
291364
PSECURITY_DESCRIPTOR RelativeSd = NULL;
292-
PSID WinlogonSid = NULL, AdminsSid = NULL;
365+
PSID WinlogonSid = NULL, AdminsSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
293366
DWORD DaclSize;
294367
PACL Dacl;
295368

@@ -316,6 +389,17 @@ CreateApplicationDesktopSecurity(
316389
goto Quit;
317390
}
318391

392+
/* HACK: Create the network service SID */
393+
if (!AllocateAndInitializeSid(&NtAuthority,
394+
1,
395+
SECURITY_NETWORK_SERVICE_RID,
396+
0, 0, 0, 0, 0, 0, 0,
397+
&NetworkServiceSid))
398+
{
399+
ERR("CreateApplicationDesktopSecurity(): Failed to create the network service SID (error code %lu)\n", GetLastError());
400+
goto Quit;
401+
}
402+
319403
/*
320404
* Build up the DACL size. This includes a number
321405
* of two ACEs of two different SIDs. The first ACE
@@ -324,7 +408,8 @@ CreateApplicationDesktopSecurity(
324408
*/
325409
DaclSize = sizeof(ACL) +
326410
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(WinlogonSid) +
327-
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid);
411+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid) +
412+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid); /* HACK */
328413

329414
/* Allocate the DACL now */
330415
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
@@ -365,6 +450,17 @@ CreateApplicationDesktopSecurity(
365450
goto Quit;
366451
}
367452

453+
/* HACK: Third ACE -- Give full desktop power to network services */
454+
if (!AddAccessAllowedAceEx(Dacl,
455+
ACL_REVISION,
456+
0,
457+
DESKTOP_ALL,
458+
NetworkServiceSid))
459+
{
460+
ERR("CreateApplicationDesktopSecurity(): Failed to set ACE for network services (error code %lu)\n", GetLastError());
461+
goto Quit;
462+
}
463+
368464
/* Initialize the security descriptor */
369465
if (!InitializeSecurityDescriptor(&AbsoluteSd, SECURITY_DESCRIPTOR_REVISION))
370466
{
@@ -402,6 +498,13 @@ CreateApplicationDesktopSecurity(
402498
FreeSid(AdminsSid);
403499
}
404500

501+
/* HACK */
502+
if (NetworkServiceSid != NULL)
503+
{
504+
FreeSid(NetworkServiceSid);
505+
}
506+
/* END HACK */
507+
405508
if (Dacl != NULL)
406509
{
407510
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
@@ -775,7 +878,7 @@ AllowWinstaAccessToUser(
775878
BOOL Success = FALSE;
776879
SECURITY_DESCRIPTOR AbsoluteSd;
777880
PSECURITY_DESCRIPTOR RelativeSd = NULL;
778-
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL;
881+
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
779882
SECURITY_INFORMATION SecurityInformation;
780883
DWORD DaclSize;
781884
PACL Dacl;
@@ -814,6 +917,17 @@ AllowWinstaAccessToUser(
814917
goto Quit;
815918
}
816919

920+
/* HACK: Create the network service SID */
921+
if (!AllocateAndInitializeSid(&NtAuthority,
922+
1,
923+
SECURITY_NETWORK_SERVICE_RID,
924+
0, 0, 0, 0, 0, 0, 0,
925+
&NetworkServiceSid))
926+
{
927+
ERR("AllowWinstaAccessToUser(): Failed to create the network service SID (error code %lu)\n", GetLastError());
928+
goto Quit;
929+
}
930+
817931
/*
818932
* Build up the DACL size. This includes a number
819933
* of eight ACEs of four different SIDs. The first ACE
@@ -830,7 +944,9 @@ AllowWinstaAccessToUser(
830944
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(InteractiveSid) +
831945
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(InteractiveSid) +
832946
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid) +
833-
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid);
947+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid) +
948+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid) + /* HACK */
949+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid);
834950

835951
/* Allocate the DACL now */
836952
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
@@ -937,6 +1053,28 @@ AllowWinstaAccessToUser(
9371053
goto Quit;
9381054
}
9391055

1056+
/* HACK : Ninenth ACE -- Give full winsta access to network services */
1057+
if (!AddAccessAllowedAceEx(Dacl,
1058+
ACL_REVISION,
1059+
NO_PROPAGATE_INHERIT_ACE,
1060+
WINSTA_ALL,
1061+
NetworkServiceSid))
1062+
{
1063+
ERR("AllowWinstaAccessToUser(): Failed to set ACE for logon network service SID (error code %lu)\n", GetLastError());
1064+
goto Quit;
1065+
}
1066+
1067+
/* HACK: Tenth ACE -- Give generic access to network services */
1068+
if (!AddAccessAllowedAceEx(Dacl,
1069+
ACL_REVISION,
1070+
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
1071+
GENERIC_ACCESS,
1072+
NetworkServiceSid))
1073+
{
1074+
ERR("AllowWinstaAccessToUser(): Failed to set ACE for network service SID (error code %lu)\n", GetLastError());
1075+
goto Quit;
1076+
}
1077+
9401078
/* Initialize the security descriptor */
9411079
if (!InitializeSecurityDescriptor(&AbsoluteSd, SECURITY_DESCRIPTOR_REVISION))
9421080
{
@@ -985,6 +1123,13 @@ AllowWinstaAccessToUser(
9851123
FreeSid(InteractiveSid);
9861124
}
9871125

1126+
/* HACK */
1127+
if (NetworkServiceSid != NULL)
1128+
{
1129+
FreeSid(NetworkServiceSid);
1130+
}
1131+
/* END HACK */
1132+
9881133
if (Dacl != NULL)
9891134
{
9901135
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
@@ -1024,7 +1169,7 @@ AllowDesktopAccessToUser(
10241169
BOOL Success = FALSE;
10251170
SECURITY_DESCRIPTOR AbsoluteSd;
10261171
PSECURITY_DESCRIPTOR RelativeSd = NULL;
1027-
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL;
1172+
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
10281173
SECURITY_INFORMATION SecurityInformation;
10291174
DWORD DaclSize;
10301175
PACL Dacl;
@@ -1063,6 +1208,17 @@ AllowDesktopAccessToUser(
10631208
goto Quit;
10641209
}
10651210

1211+
/* HACK: Create the network service SID */
1212+
if (!AllocateAndInitializeSid(&NtAuthority,
1213+
1,
1214+
SECURITY_NETWORK_SERVICE_RID,
1215+
0, 0, 0, 0, 0, 0, 0,
1216+
&NetworkServiceSid))
1217+
{
1218+
ERR("AllowDesktopAccessToUser(): Failed to create the network service SID (error code %lu)\n", GetLastError());
1219+
goto Quit;
1220+
}
1221+
10661222
/*
10671223
* Build up the DACL size. This includes a number
10681224
* of four ACEs of four different SIDs. The first ACE
@@ -1075,7 +1231,8 @@ AllowDesktopAccessToUser(
10751231
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(WinlogonSid) +
10761232
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(AdminsSid) +
10771233
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(InteractiveSid) +
1078-
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid);
1234+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid) +
1235+
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid); /* HACK */
10791236

10801237
/* Allocate the DACL now */
10811238
Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
@@ -1138,6 +1295,17 @@ AllowDesktopAccessToUser(
11381295
goto Quit;
11391296
}
11401297

1298+
/* HACK: Fifth ACE -- Give full desktop to network services */
1299+
if (!AddAccessAllowedAceEx(Dacl,
1300+
ACL_REVISION,
1301+
0,
1302+
DESKTOP_ALL,
1303+
NetworkServiceSid))
1304+
{
1305+
ERR("AllowDesktopAccessToUser(): Failed to set ACE for network service SID (error code %lu)\n", GetLastError());
1306+
goto Quit;
1307+
}
1308+
11411309
/* Initialize the security descriptor */
11421310
if (!InitializeSecurityDescriptor(&AbsoluteSd, SECURITY_DESCRIPTOR_REVISION))
11431311
{
@@ -1186,6 +1354,13 @@ AllowDesktopAccessToUser(
11861354
FreeSid(InteractiveSid);
11871355
}
11881356

1357+
/* HACK */
1358+
if (NetworkServiceSid != NULL)
1359+
{
1360+
FreeSid(NetworkServiceSid);
1361+
}
1362+
/* END HACK */
1363+
11891364
if (Dacl != NULL)
11901365
{
11911366
RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);

0 commit comments

Comments
 (0)