All posts for the month September, 2018

A couple of months ago I discovered 9 kernel vulnerabilities a security product called STOPzilla AntiMalware. It’s been over a month with no response from the vendor so I’m going public with this one. All of the vulnerabilities stem from output buffer address not being validated apart from ioctl 80002028 where the size of the output buffer is not validated. The table below lists the ioctls, related CVE and type of vulnerability

IOCTL CVE ID Vulnerability Type
0x8000204B CVE-2018-15729 Denial of Service
0x80002067 CVE-2018-15730 Denial of Service
0x8000205B CVE-2018-15731 Denial of Service
0x80002063 0x8000206F CVE-2018-15732 Arbitrary Write
0x80002028 CVE-2018-15733 Null pointer dereference
0x8000206B CVE-2018-15734 Arbitrary Write
0x8000205F CVE-2018-15735 Arbitrary Write
0x8000204F CVE-2018-15736 Denial of Service
0x80002043 CVE-2018-15737 Denial of Service

Here I’m exploiting the arbitrary write vulnerability (CVE-2018-15732) by overwriting the _SEP_TOKEN_PRIVILEGES structure to obtain the SeCreateTokenPrivilege privilege. Then it’s just a matter of calling the ZwCreateToken API to create a new privileged token. The excellent paper “Abusing Token Privileges For LPE” and source code provided needed assistance in exploiting using this privilege.

The “what” dword value starts with 1 and increments each time our ioctl is called so a number of writes needed to be done in order to obtain a useful privilege. Normal privileges would look like this

kd> dt nt!_SEP_TOKEN_PRIVILEGES fffff8a002f11060+40
+0x000 Present          : 0x6`02880000
+0x008 Enabled          : 0x800000
+0x010 EnabledByDefault : 0x800000

kd> !token fffff8a002f11060
19 0x000000013 SeShutdownPrivilege              Attributes - 
23 0x000000017 SeChangeNotifyPrivilege          Attributes - Enabled Default 
25 0x000000019 SeUndockPrivilege                Attributes - 
33 0x000000021 SeIncreaseWorkingSetPrivilege    Attributes - 
34 0x000000022 SeTimeZonePrivilege              Attributes - 

After a few writes the SeCreateTokenPrivilege privilege has been obtained. This is one of the privileges received most of the time.

kd> dt nt!_SEP_TOKEN_PRIVILEGES fffff8a002e61a90+40
+0x000 Present          : 0x6`00000015
+0x008 Enabled          : 0x16
+0x010 EnabledByDefault : 0x800000

kd> !token fffff8a002e61a90
00 0x000000000 Unknown Privilege                Attributes - 
02 0x000000002 SeCreateTokenPrivilege           Attributes - Enabled 
04 0x000000004 SeLockMemoryPrivilege            Attributes - Enabled 
33 0x000000021 SeIncreaseWorkingSetPrivilege    Attributes - 
34 0x000000022 SeTimeZonePrivilege              Attributes - 

For Windows 7 I’ve spawned a shell by switching to session 0 by calling WinStationSwitchToServicesSession(). The Windows Service “Interactive Services Detection” (UI0Detect) is set to manual and not started to begin with but starts when WinStationSwitchToServicesSession() is called. The first instance a prompt will be given to switch sessions, thereafter will switch automatically as the service is already started.

In Windows 10 (1803) the “Interactive Services Detection” service has been removed and doing a quick test on 1703 I realized the service can’t be started anyway so on Windows 10 I’m just adding the current user to the local administrators group.

The CreateProcessAsUser API doesn’t always behave as expected as occasionally returns 1314 error which means “A required privilege is not held by the client”. Running the exploit a few times and it ends up working so not sure exactly what is really happening here. Trying to run the exploit in another user accounts shell i.e. not logging in with the account doesn’t seem to work at all and always returns 1314 error so bear that in mind.

UPDATE: I just figured out the reason behind the 1314 error, since the CreateProcessAsUser API is still being called by our current process token so after the arbitrary writes sometimes the “SeAssignPrimaryTokenPrivilege” privilege is also obtained along with the “SeCreateTokenPrivilege” allowing the exploit to work. So even when our elevated token is successfully created we’ll need an added privilege “SeAssignPrimaryTokenPrivilege” for the CreateProcessAsUser API to succeed.

The current vulnerable version of STOPzilla AntiMalware is of which the driver version szkg64.sys is The exploit can be downloaded from here [zip] and here is the direct link to the package on the StopZilla site if you wish to play with the exploit [msi]