APPCERT.DLL
evaluates the SAFER
security level
of every application to be started by the Win32
functions
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
and
CreateProcessWithTokenW()
:
it allows process creation for the security levels
SAFER_LEVELID_FULLYTRUSTED
alias Unrestrictedand
SAFER_LEVELID_NORMALUSER
alias Basic User, or denies process creation for the security levels
SAFER_LEVELID_CONSTRAINED
alias Restricted,
SAFER_LEVELID_UNTRUSTED
alias Untrustedand
SAFER_LEVELID_DISALLOWED
alias Disallowed.
In case of denial it writes an entry
865,
866,
867,
868
or
882
from source Software Restriction Policies
(on
Windows XP and Windows Server 2003) or
Microsoft-Windows-SoftwareRestrictionPolicies
(on
Windows Vista and newer versions of
Windows NT) to the Event Log.
CREATE_PRESERVE_CODE_AUTHZ_LEVEL
of the Win32 functions
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
and
CreateProcessWithTokenW()
allows unprivileged users to bypass both
AppLocker
and
SAFER
alias
Software Restriction Policies
in all versions of
Windows® NT.
This bypass may also be exercised indirect: the flag
SAFER_TOKEN_MAKE_INERT
of the Win32
function
SaferComputeTokenFromLevel()
allows to create an inert
token
which can then be (ab)used with the Win32 functions
CreateProcessAsUser()
and
CreateProcessWithTokenW()
;
both Win32 functions but require privileges to be held
by their caller which are not assigned to unprivileged users.
Note: the flag
LOAD_IGNORE_CODE_AUTHZ_LEVEL
of the
Win32 function
LoadLibraryEx()
and the flag SANDBOX_INERT
of the
Win32 function
CreateRestrictedToken()
enable this bypass too; both are but disabled for unprivileged
users in Windows 8 and newer versions of
Windows NT (in Windows 7 and
Windows Server 2008 R2 with the hotfix
2532445,
the hotfix
2894252,
or the convenience
rollup update
3125574).
CreateProcess()
,
CreateProcessAsUser()
,
CreateProcessWithLogonW()
and
CreateProcessWithTokenW()
in every (user) process; their CreateProcessNotify()
routine is called with PROCESS_CREATION_QUERY
as
reason whenever an application is to be started.
NTSTATUS
like 0xC0000372 alias
STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY
process creation is denied, and the Win32 functions
CreateProcess*()
yield an error like 786 alias
ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY
;
process creation is allowed only if all AppCertDlls
return a non-negative NTSTATUS
like 0x00000000 alias
STATUS_SUCCESS
.
Note: AppCertDlls are not documented by Microsoft®!
APPCERT.DLL
from the source and install it.
APPCERT.DLL
is a pure
Win32
DLL
and builds without the
MSVCRT
libraries.
Create the text file APPCERT.C
with the following
content:
// Copyright © 2004-2018, Stefan Kanthak <skanthak@nexgo.de>
#define STRICT
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winsafer.h>
#include <wintrust.h>
typedef enum _REASON
{
PROCESS_CREATION_QUERY = 1,
PROCESS_CREATION_ALLOWED = 2,
PROCESS_CREATION_DENIED = 3
} REASON;
// see <https://msdn.microsoft.com/en-us/library/cc231200.aspx>
// and <https://msdn.microsoft.com/en-us/library/cc704588.aspx>
typedef enum _NTSTATUS
{
STATUS_SUCCESS = 0x00000000,
STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT = 0xC0000361,
STATUS_ACCESS_DISABLED_BY_POLICY_PATH = 0xC0000362,
STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER = 0xC0000363,
STATUS_ACCESS_DISABLED_BY_POLICY_OTHER = 0xC0000364,
STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 0xC0000372
} NTSTATUS;
NTSTATUS NTAPI CreateProcessNotify(LPCWSTR lpApplicationName, REASON enReason)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// see <https://msdn.microsoft.com/en-us/library/ms722431.aspx>
SAFER_CODE_PROPERTIES scp = {sizeof(SAFER_CODE_PROPERTIES),
SAFER_CRITERIA_AUTHENTICODE | SAFER_CRITERIA_IMAGEHASH | SAFER_CRITERIA_IMAGEPATH,
(LPCWSTR) NULL,
(HANDLE) NULL,
0L,
{0},
0L,
{0},
(ALG_ID) 0L,
(LPBYTE) NULL,
HWND_DESKTOP,
WTD_UI_NONE};
SAFER_LEVEL_HANDLE slh;
DWORD dwLevelId;
DWORD dwDummy;
switch (enReason)
{
case PROCESS_CREATION_QUERY:
// called once for each process that is to be created:
// return STATUS_SUCCESS to allow process creation or
// return STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY to deny process creation
scp.ImagePath = lpApplicationName;
// see <https://msdn.microsoft.com/en-us/library/ms722428.aspx>
if (!SaferIdentifyLevel(1L, &scp, &slh, NULL))
OutputDebugStringA("AppCert!CreateProcessNotify: SaferIdentifyLevel() failed!\n");
else
{ // see <https://msdn.microsoft.com/en-us/library/ms722426.aspx>
if (!SaferGetLevelInformation(slh, SaferObjectLevelId, &dwLevelId, sizeof(dwLevelId), &dwDummy))
OutputDebugStringA("AppCert!CreateProcessNotify: SaferGetLevelInformation() failed!\n");
else
// see <https://msdn.microsoft.com/en-us/library/ms722425.aspx>
if (dwLevelId < SAFER_LEVELID_NORMALUSER)
{
ntStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
// see <https://msdn.microsoft.com/en-us/library/ms722430.aspx>
if (!SaferRecordEventLogEntry(slh, scp.ImagePath, NULL))
OutputDebugStringA("AppCert!CreateProcessNotify: SaferRecordEventLogEntry() failed!\n");
}
// see <https://msdn.microsoft.com/en-us/library/ms722423.aspx>
if (!SaferCloseLevel(slh))
OutputDebugStringA("AppCert!CreateProcessNotify: SaferCloseLevel() failed!\n");
}
break;
case PROCESS_CREATION_ALLOWED:
// called once for each process that is allowed creation
// …
break;
case PROCESS_CREATION_DENIED:
// called once for each process that is denied creation
// …
break;
default:
;
}
// the return value is only used for PROCESS_CREATION_QUERY,
// all other conditions are ignored
return ntStatus;
}
Run the following three command lines to build the
DLL
APPCERT.DLL
from the source file
APPCERT.C
created in step 1. and cleanup
afterwards:
CL.EXE /c /GA /GF /GS- /Gy /O1 /Os /Oy- /TcAPPCERT.C /W4 /Zl LINK.EXE /DLL /DYNAMICBASE /EXPORT:CreateProcessNotify /LARGEADDRESSAWARE /NODEFAULTLIB /NOENTRY /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /SUBSYSTEM:WINDOWS /VERSION:1.0 APPCERT.OBJ ADVAPI32.LIB KERNEL32.LIB Erase APPCERT.EXP APPCERT.LIB APPCERT.OBJNote: for systems with AMD64 alias x64 processor architecture build
APPCERT.DLL
for the I386 alias
x86 processor architecture too!
Copy the DLL
APPCERT.DLL
built in step 2. into
Windows’
system directory
%SystemRoot%\System32\
.
Note: on systems with AMD64 alias
x64 processor architecture, additionally copy
APPCERT.DLL
built for the I386 alias
x86 processor architecture to
%SystemRoot%\SysWoW64\
.
Create the following Registry entry:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls]
"AppCert.Dll"="C:\\Windows\\System32\\AppCert.Dll"
APPCERT.DLL
is a pure Win32
DLL, written in
ANSI C,
built with the platform
SDK for
Windows Server 2003 R2 without the
MSVCRT
libraries, for use on Windows XP and newer versions of
Windows NT.
APPCERT.DLL
is available for the I386
alias x86, AMD64
alias x64 and IA64 processor
architectures of Windows NT.
APPCERT.DLL
and the cabinet file
APPCERT.CAB
are
digitally signed
using an
X.509
certificate
issued by
WEB.DE TrustCenter E-Mail Certification Authority.
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAxSwxNrFPXXn6y5Abl+0pH7faIK0xVAh70reOBrwSykab/0kIwz0QJldXNTLl
ZaSb4T7A5il2oqhiHUS53owsguXrDaJ+l+iTuCR/NrOVBJ0Xi+1Kv+ni/jb3cLvTS/BQJtFm
fVW3HHtYrQQcYCpd/AVzg1k2p46BEbGfFpjfFREdM589UDSzaiIOWSEBec8RI3HVqIMiG2qL
seuQot9shOcNcV2Y2AgTKHBUrWz10kbCWf8g5QA2hjmSMRvRtBOovCgvSF0nDFk4Odrn9nLB
PVq763s2vh/riO9cheTeg4N/ldbnAywdjLAwwJ1qynh2p/s/V5cnsoav7SZRGDyAoQIDAQAB
-----END RSA PUBLIC KEY-----
Download and install the
CA
and
root
X.509 certificates of
WEB.DE
to validate and verify the digital signature.
Note: due to its counter signature alias timestamp the digital signature remains valid past the X.509 certificates expiration date!
AMD64\APPCERT.DLL
,
I386\APPCERT.DLL
,
IA64\APPCERT.DLL
and the
setup script
APPCERT.INF
are packaged in the (compressed and
digitally signed)
cabinet
file
APPCERT.CAB
.
Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. X:\>EXTRACT.EXE /D APPCERT.CAB Microsoft (R) Cabinet Extraction Tool - Version 5.1.2600.5512 Copyright (c) Microsoft Corporation. All rights reserved.. Cabinet APPCERT.CAB 03-29-2017 4:04:12p A--- 10,406 APPCERT.INF 03-29-2017 4:03:16p A--- 32,472 AMD64\APPCERT.DLL 03-29-2017 4:03:34p A--- 31,448 I386\APPCERT.DLL 03-29-2017 4:03:10p A--- 35,032 IA64\APPCERT.DLL 4 Files 109,358 bytes X:\>dir APPCERT.CAB Volume in drive X has no label. Volume Serial Number is FEED-BAC3 Directory of X:\ 03/29/2017 04:05 PM 29,088 APPCERT.CAB 1 File(s) 29,088 bytes 0 Dir(s) 987,654,321 bytes free X:\>SIGNTOOL.EXE Verify /V APPCERT.CAB Verifying: APPCERT.CAB SHA1 hash of file: (not calculated) Signing Certificate Chain: Issued to: WEB.DE TrustCenter Issued by: WEB.DE TrustCenter Expires: 30.08.2024 09:49:34 SHA1 hash: C8301016951187E6320569B3ED54F34845B51638 Issued to: WEB.DE TrustCenter E-Mail Certification Authority Issued by: WEB.DE TrustCenter Expires: 30.08.2024 09:50:51 SHA1 hash: 8946380C6E370988FB587257A9F9A5CD323045F0 Issued to: Stefan Kanthak Issued by: WEB.DE TrustCenter E-Mail Certification Authority Expires: 14.09.2017 15:14:26 SHA1 hash: 4779B528F084E6CEF8777B62DCC4B31FFEDE0714 The signature is timestamped: 29.03.2017 16:05:10 Timestamp Verified by: Issued to: Thawte Timestamping CA Issued by: Thawte Timestamping CA Expires: 01.01.2021 01:59:59 SHA1 hash: BE36A4562FB2EE05DBB3D32323ADF445084ED656 Issued to: Symantec Time Stamping Services CA - G2 Issued by: Thawte Timestamping CA Expires: 31.12.2020 01:59:59 SHA1 hash: 6C07453FFDDA08B83707C09B82FB3D15F35336B1 Issued to: Symantec Time Stamping Services Signer - G4 Issued by: Symantec Time Stamping Services CA - G2 Expires: 30.12.2020 01:59:59 SHA1 hash: 65439929B67973EB192D6FF243E6767ADF0834E4 Successfully verified: APPCERT.CAB Number of files successfully Verified: 1 Number of warnings: 0 Number of errors: 0 X:\>Run the command line
"%SystemRoot%\System32\Expand.exe" /R APPCERT.CAB /F:* "‹target directory›"on Windows Vista and newer versions of Windows NT to extract all files into the specified directory, preserving their paths.
Note:
Expand.exe
from prior
versions of Windows NT ignore the paths and junk them;
use Extract.exe
from
the Support Tools on Windows XP and
Windows Server 2003 instead!
Note: switch to Details
view and turn on
the Path
column when you open APPCERT.CAB
in
Windows Explorer!
The setup script
APPCERT.INF
copies the appropriate APPCERT.DLL
to
%SystemRoot%\System32\APPCERT.DLL
and creates the
following
Registry
entry to activate it:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls]
"AppCert.Dll"="C:\\Windows\\System32\\AppCert.Dll"
Note: on systems with AMD64 alias
x64 processor architecture the installation
must be run in the native (64-bit) execution
environment to install APPCERT.DLL
for both processor
architectures!
APPCERT.CAB
and verify its digital signature, then open it in
Windows Explorer, extract its contents preserving the
directory structure, right-click the extracted setup script
APPCERT.INF
to display its context menu and click Installto run the installation.
On Windows XP and Windows Server 2003
open the Add/Remove Programs applet of the
Control Panel,
tick the checkbox Updates
, select the entry
Prevent bypass of AppLocker and SAFER alias Software Restriction Policies
underneath Systemkonfiguration
and click the Remove
button.
On Windows Vista and newer versions of
Windows NT open the Control Panel and
click the entry View installed updates underneath the
Programs and Features or Programs
category.
In Installed Updates select the entry
Prevent bypass of AppLocker and SAFER alias Software Restriction Policies
underneath Systemkonfiguration
and click the
Uninstall
menu entry.
Use the X.509 certificate to send S/MIME encrypted mail.
Notes: I dislike
HTML (and
even weirder formats too) in email, I prefer to receive plain text.
I also expect to see a full (real) name as sender, not a nickname!
Emails in weird formats and without a proper sender name are likely
to be discarded.
I abhor top posts and expect inline quotes in replies.
as iswithout any warranty, neither express nor implied.