Code Security
The two primary development
languages for Windows Mobile are C/C++ and .NET. However, several
additional language runtimes have been ported to the platform, and
developers can choose to write code targeting Python and others. For
these alternative runtimes, application developers must have users
install the runtime manually or they must include the runtime with the
application.
C/C++ Security
C and C++ are the primary
development languages for Windows Mobile. Both of these languages
provide access to the entire Windows Mobile API set. Because programmers
must manually manage memory in C/C++ and there is no intermediate
runtime required for execution, Microsoft refers to code written in
these languages as native code.
Native code provides no protections against memory corruption
vulnerabilities such as buffer overflows, integer overflows, and heap
overflows. The onus is placed on the programmer to prevent these
vulnerabilities through secure coding practices.
Fortunately, many of the
protection technologies introduced first in desktop Windows have been
ported to Windows Mobile. Using these technologies, developers can write
more secure code that has a lower chance of being successfully
exploited. The three main technologies are StrSafe.h, IntSafe.h, and
Stack Cookie protection.
StrSafe.h
Many buffer overflows
result from mishandling string data during copying, formatting, and
concatenation operations. Standard string functions such as strcpy,
strncpy, strcat, strncat, and sprintf are difficult to use, do not have a
standard interface, and fail to provide robust error information.
Microsoft introduced the StrSafe.h string-manipulation library to help
developers working with strings by addressing all of these problems.
StrSafe.h is included within the Windows Mobile 6 SDK and defines the
following functions: StringXXXCat, StringXXXCatN, StringXXXCopy,
StringXXXCopyN, StringXXXGets, StringXXXPrintf, and StringXXXLength. In
the preceding function definitions, XXX is replaced with either Cch for
functions that work with character counts or Cb for functions that
require the number of bytes in either the input or output buffer.
StrSafe.h functions always
require the size of the destination buffer and always null-terminate the
output. Additionally, StrSafe.h returns detailed status through an
HRESULT. Using StrSafe.h is as simple as including the StrSafe.h file in
the target project. StrSafe.h undefines all of the functions it is
designed to replace, thus leading to compile errors. These errors are
eliminated by replacing the dangerous functions, such as strcpy, with
their StrSafe.h equivalents. For more detail and full guidance on how to
use StrSafe.h, review the Microsoft documentation on MSDN (http://msdn.microsoft.com/en-us/library/ms647466.aspx).
IntSafe.h
Integer overflows are
another native code issue that often leads to security vulnerabilities.
An integer overflow results when two numbers are added or multiplied
together and the result exceeds the maximum value that can be
represented by the integer type. For example, adding 0x0000FFFF to
0xFFFFFFF3 exceeds the maximum value that can be stored in a DWORD. When
this happens, the calculation overflows and the resulting value will be
smaller than the initial value. If this overflowed size is used to
allocate a buffer, the buffer will be smaller than expected. A
subsequent buffer overflow could result from this poorly sized buffer.
The solution for integer overflows involves
checking every mathematical operation for overflow. Although this seems
straightforward, several potential problems can occur due to the
complexity of C/C++’s type system.
IntSafe.h provides
addition, subtraction, multiplication, and conversion functions for
performing integer operations safely. Use these functions when doing any
integer operations with user-supplied data. Each function returns an
HRESULT value indicating whether the operation succeeded or if an
integer overflow occurred. For more detail, review the IntSafe.h
documentation on MSDN (http://msdn.microsoft.com/en-us/library/dd361843%28VS.85%29.aspx). The following sample code shows how to use the DWordAdd function properly:
//dwResult holds the output of the calculation.
DWORD dwResult = 0;
//dwUserData is supplied by the user
//0xFFFF is the value to add to dwUserData
if (FAILED(DWordAdd(dwUserData, 0xFFFF, &dwResult))
{
//An integer overflow or underflow occurred.
//Exit the program or handle appropriately.
}
Stack Cookie Protection
The final protection for native
code is the Stack Cookie protection mechanism, also referred to as
“/GS,” which is the compiler parameter used to turn it on. Stack Cookies
are used to mitigate buffer overflows that occur when stack-based data
is overwritten. Included on the stack are return addresses, and if these
addresses are overwritten an attacker can gain control of a program’s
execution. To mitigate this risk, the compiler places a “cookie” between
user data and the return address. This cookie is a random value
generated on application startup. In order to reach the return address,
an attacker has to overwrite the cookie. Before using the return
address, the application checks to see if the cookie has been modified.
If the cookie has changed, the application assumes a buffer overflow has
occurred and the program quickly exits. This mechanism has reduced the
exploitability of many stack-based buffer overflows and continues to
improve with each new version of Microsoft’s compiler.
Unlike StrSafe.h or
IntSafe.h, enabling Stack Cookie protection does not require code
modifications because the cookie-checking code is automatically inserted
at compile time. Additionally, Stack Cookie protection does not
actually remove vulnerabilities from code; it simply makes them more
difficult to exploit. Non-stack-based buffer overflows, such as heap
overflows, are not mitigated by Stack Cookie
protection. Mitigating these vulnerabilities by fixing code is still a
necessity. The Visual Studio 2005 compiler enables the /GS flag by
default, and forces developers to explicitly disable it. Therefore,
almost all recently compiled applications have Stack Cookie protection
enabled.
.NET Compact Framework Languages
Windows Mobile includes
the .NET Compact Framework (.NET CF), a mobile version of Microsoft’s
.NET Framework. The .NET CF consists of a runtime, which provides memory
management capabilities, and an extensive class library to support
application developers. The most current version is 2.0, which is
included as part of the Windows Mobile OS. Prior versions of the .NET CF
had to be distributed by application developers manually.
.NET CF supports writing code in both Visual Basic .NET (VB.NET) and C# (pronounced C-sharp). This code is referred to as managed code
by Microsoft. All managed languages are compiled by the .NET CF to
bytecode known as Microsoft Intermediate Language (MSIL). The .NET CF
runtime runs MSIL to carry out the program’s instructions. The class
library included with the .NET CF is expansive and includes functions
for using the majority of the phone’s capabilities. Developers use this
class library instead of the Windows Mobile Native API. For cases where
the .NET CF does not include a function for using a phone platform,
developers can use Platform Invoke (P/Invoke). This is a marshalling
method for calling functions contained within native code.
Because the .NET CF
runtime manages memory for developers, integer overflows and buffer
overflows are very rare in .NET CF code. Generally, memory corruption
vulnerabilities only occur when developers misuse P/Invoke
functionality. This is because P/Invoke is similar to using the Native
API directly, and it is possible to provide incorrect parameters to
system calls, thus leading to memory corruption. If developers avoid
using P/Invoke, code vulnerabilities should be limited to business logic
flaws.
There is a performance impact
to using managed code, and developers often choose to write native code
for performance-critical applications. As mobile device memory and
processing power increase, more developers will write managed
applications, thus further reducing the potential for memory management
errors.
PythonCE
PythonCE is a port
of the popular Python scripting language to Windows Mobile. The runtime
is freely available and includes much of the class library and
functionality from Python 2.5. Because Python is a scripting language
and does not require
compilation, it is a useful tool for exploring Windows Mobile. PythonCE
is not signed and runs at the Normal privilege level. To call
Privileged APIs from PythonCE script, configure the security policy to
Unlocked.
To call native platform
APIs, use the ctypes interop package. This package can load DLLs,
marshal parameters, and call platform methods. Due to a large
distribution size and complexity in porting Python to Windows CE,
PythonCE development has slowed. The project continues, but updates are
slow in coming.
Application Packaging and Distribution
The methods for
distributing Windows Mobile applications include CAB files, PC
installers, and SMS download. The Cabinet (CAB) file format is used for
packaging applications regardless of distribution mechanism.
Applications can also be distributed through raw file copy to the
device’s file system, but this presents two drawbacks: not having an
installer and not having the application registered with the system’s
program manager.
CAB Files
The CAB file format
was originally developed for distributing desktop Windows installation
media and is used in many Microsoft technologies. Each CAB file can
contain multiple files and/or directories; optionally, the CAB file can
be compressed. Unlike most archive file formats, CAB files are
considered executables and are therefore subject to the same security
policies. Developers bundle the application and any required resource
files within the CAB file; this way, applications can be distributed as
one single file. The desktop Windows Explorer supports the CAB file
format, so CAB files can be easily opened and extracted on the PC.
Windows Mobile
applications packaged in CAB files can also contain custom setup code,
application provisioning information, and registry key information. This
functionality is implemented not within the CAB format itself, but by
including a special provisioning XML document the Windows Mobile
application installer looks for. This document must be named _setup.xml
and be stored in the root folder of the CAB archive. When the user
installs the CAB file, Windows Mobile will open the _setup.xml file and
carry out the provisioning instructions within.
The _setup.xml file contains
wap_provisioning XML, and it’s capable of modifying much of the device’s
configuration. The wap_provisioning format is documented in detail on
MSDN and is relatively easy to read after the first couple of times. The
registry and file elements are the most interesting when you are
security-testing and reverse-engineering an application’s install
process. The following XML blob shows
the portion of a _setup.xml file used for installing files. Each node
includes an XML comment describing the node’s purpose.
<!-- Mark the start of a file operation -->
<characteristic type="FileOperation">
<!-- Signals a directory node named "\Windows" -->
<characteristic type="\Windows" translation="install">
<!-- Instruct the Installer to Create the Directory -->
<characteristic type="MakeDir" />
<!-- Signals a file node named "mypro_image.bmp" -->
<characteristic type="cclark_image.bmp" translation="install">
<!-- Instruct the installer to expand the file -->
<characteristic type="Extract">
<!-- The file "MYPRO~1.001" will be expanded to
"cclark_image.bmp" in the "\Windows" directory -->
<parm name="Source" value="MYPRO~1.001" />
<parm name="WarnIfSkip" />
</characteristic>
</characteristic>
</characteristic>
</characteristic>
A minor annoyance is that all
files stored within the Windows Mobile CAB archive must be named in the
8.3 file format (for example, MYPRO~1.001), a holdover from the format’s
use during the days of MS-DOS. Truncated filenames make browsing the
CAB file for executables or DLLs difficult. To work around this, either
install the application to an emulator and copy the files off, or read
_setup.xml to find executable files and their 8.3 sources. Either method
involves manual effort, but unfortunately this is the only way.
Windows Mobile files can
also contain a CE Setup DLL. This DLL contains native code that is
invoked before and after installation. Installation authors use the
setup DLL to perform custom installation steps that cannot be expressed
using wap_provisioning XML. The DLL will run with the permissions of the
CAB file granted by the device’s security policy.
CAB files can be signed
with an Authenticode signature. The signature is embedded within the CAB
file and maintains the integrity of the CAB file’s metadata and
contents. The signature prevents tampering and enables users to make
trust decisions based on the publisher of an application. To view the
signature, use the Security Configuration Manager tool and select Check
File Signature from the File menu. Browse to the desired CAB file and
click Open. Security Configuration Manager will display the signature on
the CAB file.
To
generate CAB files, use the CabWiz.exe tool bundled with Visual Studio.
To use this tool properly, an Information File (.INF) must be provided
that lists the application’s publisher, files bundled with the
application, registry keys and default values, and other information
such as the shortcuts to create upon installation. CabWiz.exe consumes
the .INF file, generates the appropriate _setup.xml file, renames
installation files, and produces the output CAB file. This file can then
be signed and deployed to devices.
Manual Deployment
To deploy CAB files
manually, copy the CAB file to the device and navigate to the containing
directory using the device’s File Explorer. Selecting the CAB file will
invoke the installer and process the CAB file. After installation is
complete, Windows Mobile displays a status message and adds the program
to the device’s Program directory.
PC-based Deployment
Applications can be deployed
from a PC when a device is cradled. To package these applications,
developers create a Windows Installer package and device CAB package.
When the Windows installer runs, it invokes the Mobile Application
Manager (CeAppMgr.exe) and registers the application for installation
the next time the device is cradled. When the user cradles a device, the
Mobile Application Manager is launched and the application is pushed to
the device for installation. The user is then able to manage the
application through the Mobile Application Manager on their PC. The same
signing requirements as manual deployment are enforced.
OTA SMS Deployment
Starting with Pocket PC
2003, applications can be deployed using SMS messages. The SMS messages
appear within the user’s Message inbox. When a user reads the message,
they can choose whether or not to install the application. If they
select to install the application, the CAB file will be downloaded and
then executed on the device. Some mobile software providers, such as
Handango, distribute purchased applications using this technique.