Security Tools for Windows applications

The Application Verifier (AppVerifier) is a collection of tests used during the application development and testing process. It helps developers identify potential application compatibility, stability, and security issues. The AppVerifier works by monitoring an application's use of the operating system, including the file system, registry, memory, and APIs, while the application is being run. The tool then provides guidance for source-code level fixes of the issues it uncovers.

Security Tools included with the AppVerifier

On This Page

Encryption Correctness Detector
SecurityChecks
LUA Privilege Predictor
Resources:

Encryption Correctness Detector

Encryption Checks monitors applications and detects weak encryption resulted through the incorrect usage of the Windows Cryptographic APIs. It also allows tracing encryption calls that an application process makes. This test tool determines and signals when weak keys or weak/old algorithms are used to protect data like:

  • Encrypting or decrypting with symmetric keys less than 128bit. For example on older Windows platforms RC2 keys generated by CryptoAPI have a default 40bit effective key length unless explicitly set by the calling application.

  • Encrypting or decrypting with old or out-of-date cryptographic algorithms (like RC2 or DES which should be used only for backward compatibility) or insecure algorithms like RC5. It is recommended for new products to use AES, 3DES or RC4.

  • Use of weak public RSA keys for encrypting or signing: today it is considered that 1024-bit strength is minimum acceptable for short-lived keys. For long-lived keys, 2048bit or higher is recommended.

  • Deriving new keys from existing weak keys

  • Exporting keys to external media encrypted with weak keys or algorithms

  • Importing keys that laid out on external media in an insecure form (encrypted with weak keys/algorithms, easily breakable)

Such events will be recorded as warnings or errors by the tool into the Application Verifier log, which enables also to break in the debugger to get the stack trace and code line number for where the incorrect call was made.

Encryption Checks will ship as part of the next version of Application Verifier (summer 2004). See the References section on how to sign up for the Beta (April 2004).

SecurityChecks

SecurityChecks originally shipped in Application Verifier 2.50. An enhanced version is shipping in the summer of 2004. See the references section on how to sign up for the Beta.

SecurityChecks v1.0 in AppVerifier v2.5: The primary purpose of the Security Checks test is to ensure that applications work securely in the Windows environment. Fundamentally, this test is looking for various known activities the applications may perform that can open holes in the system security by circumventing accepted security usage. The specific threats/conditions that SecurityChecks detects are:

Insecure Objects: Windows has numerous functions for creating and manipulating objects, and most objects in Windows have Security Descriptor settings. SecurityChecks analyzes attempts to create objects (such as files or registry keys) and flags dangerous security descriptors, such as:

  • DACL that is NULL, which grants full control to any user

  • DACL which has WRITE_OWNER or WRITE_DAC set with WORLD access

Object Squatting Vulnerability: Any application that launches other processes may potentially open itself up to squatting attacks. The most common ways to do this are:

  • Passing a NULL lpApplicationName to CreateProcess

  • Passing a command line to CreateProcess (or similar API) that contains unquoted spaces in the program portion. For example, this command line: C:\program files\foo.exe –t –g C:\program files\foo\bar would be flagged as invalid by SecurityChecks

Stacked Impersonation (Servers only): Impersonation allows a server to act on behalf of an authenticated client and access resources using the client’s (usually reduced) access token. However, it’s easy to forget that impersonation is a one-time operation, and does not “stack”.

Sample Code

The Wrong Way

The Right Way

ImpersonateLoggedOnUser( hLogon );
// ..do something as hLogon
ImpersonateLoggedOnUser( hLogon2);
// … do something as hLogon2
RevertToSelf();

// …I am now running as myself
RevertToSelf(); // no effect.

ImpersonateLoggedOnUser( hLogon );
// running as client user
RevertToSelf();
// …running as myself

ImpersonateLoggedOnUser( hLogon2 );
// running as client user
RevertToSelf();
// running as myself again

SecurityChecks detects:

  • Impersonating a client while already impersonating

  • Reverting from impersonation while not impersonating

Excessive Access: Windows requires an application to state its intentions when opening an object. For example, you can open a file for read, write, delete, or other kinds of operations. If the application opens an object for more access than it is likely to ever need, SecurityChecks will flag the operation. Examples of excessive access include:

  • Opening a file for FILE_ALL_ACCESS

  • Opening a registry key for KEY_ALL_ACCESS

  • Opening any object for STANDARD_RIGHTS_REQUIRED

Note: Opening an object for too much access is not a direct threat to the application, but it makes it very difficult to increase the security of the object at a later date, and hurts the system’s ability to audit the operation. So, SecurityChecks flags these as “bad citizen” activities.

SecurityChecks v2.0: A number of enhancements are planned for SecurityChecks, in addition to refinements of existing tests. The new features break down into:

Misuse of Authentication: Windows offers SSPI, an extensible, abstract model for authentication. Via SSPI, Windows also offers security protocols such as NTLM, Kerberos, and Negotiate. This capability is powerful, but can be misused in a variety of ways that SecurityChecks can potentially detect:

  • Using NTLM deliberately for authentication (other protocols offer improved security over NTLM; the Negotiate protocol is preferred)

  • Accidental use of NTLM by supplying bad parameters to Negotiate

  • Authenticating to a site without negotiating any form of encryption or integrity protection, which leaves the application vulnerable to session theft.

Memory Disclosure: It’s common practice to zero or otherwise obscure buffers that contain confidential data, such as passwords. SecurityChecks will detect many cases where password data may be disclosed via memory dumps, such as:

  • Using memset instead of SecureZeroMemory to obscure confidential buffers (memset may be optimized out by overly smart compilers)

  • confidential buffers that get freed without being zeroed

  • confidential buffers that never get freed

Buffer Overrun Potential: Well documented in the industry, buffer overruns offer denial-of-service or code-execution threats. A variety of methods exist today for detecting buffer overruns when they occur—SecurityChecks will offer mechanisms to predict buffer overrun threats in the code without requiring that they actually occur. These types of BO threats will be identified by SecurityChecks:

  • Heap buffer overrun potential

  • Calling BO-prone APIs (gets, vsprintf...)

We’re working on a way to predict stack BOs, but this may not be in the next release.

Miscellaneous Threats:

  • Dependence on PE-sections in loaded modules (code injection threat)

  • use of rand() where CryptGenRandom may be preferable

LUA Privilege Predictor

People have often logged on as administrators so that they could use Windows more easily. This practice has facilitated any number of security threats that would have been non-issues had people been running as regular users, but many (possibly even most) applications don’t work correctly when executed by non-administrators. In Longhorn, Microsoft will be pushing hard to reduce the need for administrative privilege to run most applications (for example, games).

The most obvious way to determine whether an application can be run correctly as a non-admin is, of course, to run it as a non-admin. However, this approach doesn’t work well for non-robust applications—if something goes wrong, those applications may terminate. Then, even assuming a debugger is attached; only the first operation that requires privilege is known. This necessitates a cycle of finding and fixing bugs one at a time, which can take a long time.

The LUA Privilege Predictor (LUA = Least User Access) is being developed to simplify this approach. It has two primary functions:

Predict Privilege Problems: It is intended to allow an application that may require privilege to be tested as an administrator. The Predictor will analyze the operations attempted by the application to determine whether those operations would have succeeded as a non-admin. The result is a list of bugs that an application developer can use in his/her investigations after just a single run. This doesn’t eliminate the need to actually run the application as a non-admin afterward, but it should reduce the number of times an application would need to be tested in order to get it working.

Diagnose Privilege Problems: When run as a non-admin, the Predictor can potentially be used to diagnose errors that might be preventing the application from working due to privilege. For example, if the application tries to write to a system file, or enable a privilege that’s only given to administrators, and the attempt fails, this may be why the app isn’t working.

Resources:

Download: https://www.microsoft.com/windows/appcompatibility/appverifier.mspx
FAQ: https://www.microsoft.com/windows/appcompatibility/appverifier_faq.mspx
Newsgroup: microsoft.public.win32.programmer.tools
Email Support Contact: aeassist@microsoft.com
Beta Sign Up: https://beta.microsoft.com use guest id avrfbeta