19 Attacks - Attacking Software Design
Design Overview.
It is very difficult to look at 300 pages of design documentation
and determine whether the finished product will be secure. It is no
surprise then that some security vulnerabilities creep in at the
design phase. The problem is that subtle design decisions can lead
to component interaction and inherent flaws that create
vulnerabilities in the finished product. Attacks 6-8 help expose these design insecurities in software it
will tackle insecure defaults, test accounts, test instrumentation,
open ports, and poor constraints on user-supplied program logic.
Attack 9: Try common default and test
account names and passwords
In applications that have restrictions on data and functionality,
all users are not treated equally. User actions are governed by
their assigned level of access. In most instances, users are
identified and authenticated with user names and passwords. Many
applications, however, ship with some special user accounts built
in; the most common examples being the “Administrator” or “root”
accounts. These accounts usually don’t present a problem; they are
typically well documented, and the user is prompted to change or
initialize the password upon installation. Problems arise, though,
when undocumented, invisible, or unconfigurable accounts ship with
the product. We must understand when user credentials are
entered, checked and whether or not they get cached. This
attack is designed to weed out “hidden” accounts so that they can be
dealt with before release.
Attack 10: Use
Holodeck to expose unprotected test APIs
Complex, large-scale applications are often difficult to
test effectively by relying on the APIs intended for normal users
alone. Sometimes there are multiple builds in a single week, each of
which has to go through a suite verification tests. To meet this
demand, many developers include hooks that are used by custom test
harnesses. These hooks—and corresponding test APIs—often bypass
normal security checks done by the application the sake of ease of
use and efficiency. Developers add them for testers, intending to
remove them before the software is released. The problem is that
these test APIs become so integrated into the code and the testing
process that when the time comes for the software to be released,
managers are reluctant to remove them for fear of “destabilizing”
the code, potentially causing a major delay in the ship date.
It is
critical to find these dangerous programmatic interfaces and
ensure that, if they were to be accessed in the field by hackers,
they could not be used to compromise application, its host system,
or user data. By watching the application with
Holodeck while automated test
suites are running, we can identify dlls that are loaded and used,
and then evaluate their impact on application security. In this
attack, we try to expose test APIs.
Attack 11: Connect to all ports
A port is a method of organizing network traffic that is
received or sent from a machine, so that different types of data can
be transmitted simultaneously. When a port is “open,” the operating
system is “listening” for data through that interface. Applications
commonly open ports to send data across the network. However, an
open port is not automatically a secure conduit for communication.
Without proper measures taken by application developers, an open
port is a welcome mat for a hacker attempting to gain unauthorized
access to a system. This attack finds these "open doors."
Attack 12: Fake the source of data
Some data is trusted implicitly, based on its source; for example,
applications tend to accept values from sources like the OS with
minimal scrutiny. Some sources should be trusted (in fact they must
be trusted) for the application to function—sources such as
configuration commands from an authenticated administrator. Problems
arise when the trust an application extends to a particular source
is not commensurate with the checks it makes to ensure that data is
indeed from that source. This attack focuses on ensuring that
applications take the proper precautions to verify the source of
data, and that even when verified, the level of trust the
application extends to that source is appropriate.
Attack 13: Create loop conditions in any application that
interpret script, code, or other user-supplied logic
Some commands, when executed in isolation, are harmless.
Imagine opening a Web browser and navigating to a Website that
launches another window. This action by itself may be annoying, but
it doesn’t represent a threat to the end user. Now imagine that new
window launching a third window, followed by another and another.
Without some sanity checks by the browser, the system would become
deadlocked. This attack investigates these repeated actions: taking
commands that are
relatively benign and executing them over and over again to deny
functionality to entitled users or processes.
Attack 14: Use alternate routes to accomplish the same task
How many ways can you open a Microsoft WordŽ file in Windows.
You could:
- Type the path in the Run dialog box
- Double-click on the file’s icon in an Explorer windowType the path and file name in an Explorer window
- Type the path and file name in an Internet Explorer window
- Select it from the My Recent Documents tab on the Start menu
- Type the file name in the Open dialog box within Word
- Etc., etc., etc.
Attack 15: Force the system to reset values
This is one of our favorites, because you don’t really need to do anything; indeed, that’s the whole point of the attack. Leave fields blank, click Finish instead of Next or just delete values. These types of actions force the application to provide a value where you haven’t. Establishing default values is a fairly intricate programming task. Developers have to make sure that variables are initialized before a loop is entered or before a function call is made. If this isn’t done, then an internal variable might get used without being initialized and the result is often catastrophic.
Whenever a variable is used, it must
first be assigned a legitimate value. Good programming practice is
to assign a value to a variable as soon as it is declared in order
to avoid these types of failures. In practice, though, programmers
often assume that the user will provide a legitimate value in the
course of the application’s execution before the variable is used.
For security, the biggest concern is that default values and
configurations can leave the software in an unsafe state. This
attack is focused on forcing the application to use these default
values and then assessing the vulnerabilities that these values
produce.



