|
This page contains the answers to the questions posed at the
end of each chapter.
Jump to chapter: 2 3
4 5
6 7
8 9
10 11
12 13
14 15
16 17
18
Chapter 2 – Core Defense Mechanisms
| 1. |
In a typical application, access is handled using a
trio of mechanisms relating to authentication, session
management, and access control. These components are
highly interdependent, and a weakness in any one of them
will undermine the effectiveness of the overall access
handling mechanism. For example, a defective
authentication mechanism may enable an attacker to login
as any user and so gain unauthorized access. If session
tokens can be predicted, an attacker may be able to
masquerade as any logged in user and gain access to
their data. If access controls are broken, then any user
may be able to directly use functionality that is
supposed to be protected.
|
| 2. |
A session is a set of data structures held on the
server, which are used to track the state of the user’s
interaction with the application. A session token is a unique
string that the application maps to the session, and is
submitted by the user to reidentify themselves across successive
requests.
|
| 3. |
There are many situations where an application may
be forced to accept data for processing that does not
match a list or pattern of input that is known to be
“good”. For example, many people’s names contain
characters that can be used in various attacks. If an
application wishes to allow people to register under
their real names, it needs to accept input that may be
malicious, and ensure that this is handled and processed
in a safe manner nevertheless.
|
| 4. |
Defects in the any of the core mechanisms for
handling access may enable you to gain unauthorized access to
the administrative functionality. Further, data that you submit
as a low privileged user may ultimately be displayed to
administrative users, enabling you to attack them by submitting
malicious data designed to compromise their session when it is
viewed.
|
| 5. |
Yes. If it were not for Step 4, this mechanism
would be robust in terms of filtering the specific items it is
designed to block. However, because your input is decoded
after the filtering steps have been performed, you can
simply URL-encode selected characters in your payload to evade
the filter:
%22>%3cscript>alert(%22foo%22)</script>
If Step 4 were performed first (or even not at
all) then this bypass would not be possible.
|
Chapter 3 – Web Application Technologies
| 1. |
The
OPTIONS method
asks the server to report the HTTP methods that are available
for a particular resource.
|
| 2. |
The
If-Modified-Since
header is used to specify the time at which the browser last
received the requested resource. The
If-None-Match
header is used to specify the entity tag that the server issued
with the requested resource when it was last received.
In the two ways described, these headers are used
to support caching of content within the browser, and they
enable the server to instruct the browser to use a cached copy
of a resource, rather than responding with the full contents of
the resource if this is not necessary.
When you are attacking an application, your
browser may already have cached copies of resources that you are
interested in, such as JavaScript files. By removing these two
headers, you can override the browser’s caching information and
ensure that the server responds with a fresh copy of the
resource you wish to view.
|
| 3. |
The
secure flag is
used to instruct the browser that the cookie should only ever be
resubmitted over HTTPS connections, and never unencrypted HTTP.
|
| 4. |
The 301 status code tells the browser that the
requested resource has moved permanently to a different
location. For duration of the current browser session, if your
browser needs to access the originally requested resource, it
will use the location specified in the 301 response instead.
The 302 status code tells the browser that the
requested resource has moved temporarily to a different
location. On the next occasion that the browser needs to access
the originally requested resource, it will request this from the
originally requested location.
|
| 5. |
The browser sends a
CONNECT request to
the proxy, specifying the destination hostname and port number
as the URL within this request. If the proxy allows the request,
it returns an HTTP response with a 200 status, keeps the TCP
connection open, and from that point onwards acts as a pure
TCP-level relay to the specified destination.
|
Chapter 4 – Mapping the Application
| 1. |
The filename
CookieAuth.dll
indicates that Microsoft ISA server is being used. This is the
URL for the login function, and after a successful login the
application will redirect to the URL
/default.aspx.
|
| 2. |
The URL is a common fingerprint for the phpBB
web forum software. Information about this software is readily
available on the Internet, and you can perform your own
installation to experiment on. A listing of members can be found
at the following URL:
http://wahh-app.com/forums/memberlist.php
Individual user profiles can be found via URLs
like the following:
http://wahh-app.com/forums/profile.php?mode=viewprofile&u=2
Various vulnerabilities have been found in the
phpBB software so you should confirm the version in use and
research any associated problems.
|
| 3. |
The
.asp file
extension indicates that Microsoft’s Active Server Pages are in
use. The use of a
/public path
indicates that other interesting paths might exist, such as
/private. The
action=view
parameter suggests that other actions may exist, such as
edit,
add
or
delete. The function of the
location=default parameter should be investigated
– this may contain a filename, and you should probe the
application for path traversal vulnerabilities.
|
| 4. |
If the header is accurate, it indicates that the
server is running Apache Tomcat. Tomcat is a Java Servlet
Container, so the application probably uses Java and JSP
technologies.
|
| 5. |
The first response uses the HTTP status code 200,
which normally indicates that the request was successful.
However, the Content-Location header indicates the location from
which the response was retrieved. This appears to be a
dynamically generated error page, and includes the value 404 in
its query string, indicating that the response contains a
customized “file not found” message.
The second response uses the HTTP status code 401,
which suggests that the requested resource is present but that
users must supply HTTP authentication credentials in order to
access it.
In each case, you could substantiate your
conclusion by requesting a clearly non-existent item in the same
directory with the same extension (for example,
/iuwehuiwefuwedw.cpf)
and comparing the responses. In the first application, you would
expect to see a response very similar to the original. In the
second application, you would expect to see a different response
containing a “file not found” message.
|
Chapter 5 – Bypassing Client-Side Controls
| 1. |
The data can be encrypted or hashed using a key
stored on the server, as is optionally done for the ASP.NET
ViewState. Unless an attacker somehow captures the key, they
will be unable to encrypt arbitrary data or compute a valid hash
for arbitrary data. However, the attacker may still be able to
take data from one context and replay it in another – for
example, the encrypted price for a cheap item could be submitted
in place of the encrypted price for an expensive item. To
prevent this attack, the application should include sufficient
context within the protected data to be able to confirm that it
originated in the same context as it is being employed – for
example, the product code and price could be combined in a
single encrypted blob.
|
| 2. |
The defense is trivial to bypass. An attacker does
not need to submit the cookie that tracks the number of failed
login attempts. They can either disable cookies in their
browser, or use an automated script that submits requests
without the relevant cookie.
An alternative defense would be to use CAPTCHA
controls to slow down an attacker, or to block the source IP
address after five failed logins, although this may have an
adverse impact where multiple clients are located behind a proxy
or a NAT-ting firewall.
|
| 3. |
(a) The Referer header can be set to an
arbitrary value by an attacker, and so is not a safe means of
performing any access control checks.
(b) This method will only be effective if the
web server containing the diagnostic functions is in a parent or
child domain of the originating web server, and the session
cookie is appropriately scoped, otherwise the cookie will not be
submitted to the diagnostic server. A back-end mechanism will
need to be implemented for the diagnostic server to validate the
submitted tokens with the originating server.
(c) This method will be effective regardless of
the domain name of the diagnostic server. It may be regarded as
safe provided that the authentication tokens are not predictable
and are transmitted in a secure manner (see Chapter 7). Again, a
back-end mechanism for validating tokens will need to be
implemented.
|
| 4. |
There are two basic methods:
(a) You can intercept the request containing
the form submission, and add the disabled parameter.
(b) You can intercept the response containing
the form, and remove the
disabled=true
attribute.
|
| 5. |
There is no means by which an application can ensure
that a piece of logic has been run on the client.
Everything that occurs on the client is within the
control of the user.
|
Chapter 6 – Attacking Authentication
| 1. |
(a) The credentials are transmitted
within the query string of the URL. These are at risk of
unauthorized disclosure via the browser history, the logs of the
web server and IDS, or simply by appearing on-screen.
(b) The credentials are transmitted via
an unencrypted HTTP connection, making them vulnerable to
interception by an attacker who is suitably positioned on the
network.
(c) The password is an English word
consisting of four lower case alphabetical characters. The
application is not enforcing any effective password quality
rules.
|
| 2. |
Self-registration functions are very often
vulnerable to username enumeration because users can choose
their own username and the application prevents them from
registering an existing username.
Applications can avoid self-registration
functionality being misused in this way through two methods:
(a) The application can generate its own
usernames, assigning a non-predictable username to each new user
when they have supplied the required personal information.
(b) The first step of the self-registration
process can require users to enter their email address. The
application then sends the user an email containing a one-time
URL that they can use to continue the registration process. If
the supplied email address is already registered, the user is
notified of this in the email.
|
| 3. |
The rationale for requesting two randomly chosen
letters from the user’s memorable word, rather than the entire
word, is that even if an attacker captures all of the
credentials supplied by a user in a single login, it is unlikely
that the attacker will be able to repeat the login using those
credentials, because a different pair of letters will be
requested.
If the application requests all of the required
information in a single step, then it must select the randomly
chosen letters in advance, without knowing the claimed identity
of the authenticating user. This means that an attacker who
knows only two letters from a user’s memorable word can simply
reload the login form repeatedly until those two letters are
requested, enabling them to log in using the captured
credentials.
To avoid this defect, the application must choose
a new pair of letters following each successful login, and store
these in the user’s profile until such time as the user
successfully logs in again. When the user has identified
themselves at stage one of the login, the pair of letters is
retrieved from their profile, and requested from the user. In
this way, an attacker who has captured the credentials in a
single login will typically need to wait a very long period
until the them items are re-requested by the application.
|
| 4. |
An attacker attempting to guess valid credentials
can easily determine whether an individual item is valid or
invalid. The application’s behavior effectively enables an
attacker to break down the brute-force problem into a series of
individual challenges.
The vulnerability can be corrected by continuing
through all steps of the login process even if an invalid item
is submitted, returning a generic “login failed” message after
the final stage, regardless of which item caused the failure.
This massively increases the number of requests required to
guess a user’s credentials using brute force.
|
| 5. |
The presence of the anti-phishing mechanism
enables an attacker to break the problem of guessing valid
credentials into two stages. An attacker can verify whether or
not a particular username and date of birth are valid by
completing step (a) twice with these values. If the same anti-phishing
image is returned on each occasion, then the guessed credentials
are almost certainly valid; otherwise, they are not. A scripted
attack could quickly iterate through a wide range of dates of
birth for a targeted username, in order to guess the correct
value.
Worse still, the mechanism devised is not
effective in preventing phishing attacks. A cloned web
application will receive the username and date of birth supplied
by the user in step (a), and can submit these directly to the
original application to retrieve the correct image to present to
the user in step (b). If users have been told to trust the image
to provide assurance of the application’s identity, then the
mechanism may actually be counter-productive and may cause users
to log in to a phishing site that they would not otherwise
trust.
|
Chapter 7 – Attacking Session Management
| 1. |
The
sessid cookie
contains a Base64-encoded string. Decoding the two values you
received reveals the following values:
jim23:1241:1194870863
jim23:1241:1194875132
The decoded cookie contains three items of data,
separated by semicolons. On first inspection, the three values
may contain a username, numeric user identifier, and a changing
numeric value. The latter contains 10 digits, and looks like a
Unix time value. Translating these two values reveals the
following:
Mon, 12 Nov 2007 12:34:23 UTC
Mon, 12 Nov 2007 13:45:32 UTC
These represent the times at which each of your
sessions was created.
Hence, it appears that the session tokens are
comprised of meaningful user-specific data and a predictable
item. In principle, you could mount a brute force attack to
guess the tokens issued to other application users.
|
| 2. |
A 6-character session token allows for a
considerably larger range of possible values than a 5-character
password. It may therefore appear that the shorter passwords
present the most worthwhile target for an attack.
However, there are important differences between
brute force attacks targeting passwords and those targeting
session tokens. When attempting to guess passwords, it is
necessary to supply a username and password together, thus
targeting at most one account with each request, and maybe none
at all. You may already know some usernames, or be able to
enumerate them, or you may need to guess usernames and passwords
simultaneously. The login mechanism may contain multiple stages,
or be slow to respond. The login mechanism may also enforce
account lockout, considerably slowing down your attack.
When attempting to guess session tokens, on the
other hand, you can often target multiple users simultaneously.
There may be 20 users logged in, or 2000, or zero. If a user is
not presently logged in, then you cannot target them in this
way. There is no easy way for an application to enforce any kind
of “lockout” when a large number of invalid tokens are received.
Token guessing attacks normally run very quickly – requests
containing an invalid token usually receive a fast response
containing an error message or redirection.
In short, there is no definitive answer to the
question, and the most worthwhile target will depend upon your
purposes and other aspects of the application. If many users are
logged in and you simply need to compromise any user, then
targeting sessions may be best. If you wish to compromise the
single administrative account, which rarely logs in, then a
password guessing attack will be more effective.
|
| 3. |
(a) Yes. The domain and path both match
the scope of the cookie.
(b) No. The domain is not the same or a subdomain of the domain scope of the cookie.
(c) Yes. The domain is a subdomain of the
domain specified in the scope, and the path matches the scope.
(d) Yes. The domain and path both match
the scope of the cookie. Although the protocol is HTTP, the
secure
flag was not specified, so the cookie is still transmitted.
(e) Yes. The domain matches the scope of
the cookie. Because the path scope did not include a trailing
slash after
/login, the scope
includes not only the path
/login/ but also
any other patch matching the
/login prefix.
(f) No. The path does not match the
scope of the cookie.
(g) No. The domain is the parent of the
domain specified in the scope, and so is not included.
(h) No. The domain is not the same or a subdomain of the domain scope of the cookie.
Note that the
HttpOnly flag
affects whether cookies are accessible via client-side
JavaScript. It does not determine whether they are transmitted
via HTTP or HTTPS connections.
|
| 4. |
Session hijacking is still possible. If an attacker
obtains the tokens issued to a user, the attacker can
immediately make requests using those tokens, and the
server will accept the requests. However, if the user
issues a single further request to the application, then
the per-page token submitted by the user will be out of
sequence, and the entire session will be invalidated.
Hence, if the user is still interacting with the
application, the window for exploitation may be very
small. If an attacker simply wishes to perform a
specific action with the user’s privileges, it is likely
that they can script an attack to perform the desired
action within the available window.
|
| 5. |
The logout function is broken.
The script invalidates the session token currently
held in the browser, meaning that its previous value will not be
submitted in any subsequent requests. It then initiates a
redirection to the application start page. Any attempt to access
protected functionality will be denied because the request will
not be made as part of an authenticated session.
However, the client-side application does not
communicate to the server that a logout action has been
performed. The user’s session on the server will remain active,
and the token previously issued will continue to be accepted if
issued to the server. This will remain the case indefinitely
until the session is timed out or otherwise cleaned up. During
that interval, an attacker who has captured or guessed the
token’s value through some means can continue to use it to
hijack the user’s session.
|
Chapter 8 – Attacking Access Controls
| 1. |
Choose a range of important application functions
that you are authorized to access. Walk through each
function submitting a modified or absent
Referer header. If the
application rejects your requests, it may well be vulnerable.
Try making the same requests in a user context where these are
unauthorized, but restore the original Referer header each time.
If the requests are now accepted, then the application is
certainly vulnerable.
|
| 2. |
You should attempt the following tests, in order
of effectiveness:
(a) Modify the
uid value to a
different value with the same syntactic form. If your own
account details are still returned, then the application is
probably not vulnerable.
(b) If you are able to register or
otherwise access a different user account, log in using that
account to obtain the other user’s
uid value. Using
your original user context, substitute this new
uid
in place of your own. If sensitive data about the other user is
displayed, then the application is vulnerable.
(c) Use a script to iterate up and down
for a few thousand values from your
uid, and determine
whether any other users’ details are returned.
(d) Use a script to request random
uid
values between 0 and 9999999999 (in the present example) and
determine whether any other users’ details are returned.
|
| 3. |
It is possible to spoof another user’s IP address,
although in practice this may be extremely difficult. More
significantly, different end users on the Internet may share the
same IP address if they are behind the same web proxy or
NAT-ting firewall.
One way in which IP-based access controls can be
effective in this situation is as a defense-in-depth measure to
ensure that users attempting to access administrative functions
are located on the organization’s internal network. Those
functions should also, of course, be protected by robust
authentication and session handling mechanisms.
|
| 4. |
There is no horizontal or vertical segregation of
access within the application, so there is no need for any
access controls that discriminate between different individual
users.
Even though all users are in the same category,
the application still needs to restrict the actions that any
user can perform. A robust solution will use the principle of
least privilege to ensure that all user roles within the
application’s architecture have the minimum permissions
necessary for the application to function. For example, because
users only need read access to data, the application should
access the database using a low privileged account with
read-only permissions to only the relevant tables.
|
| 5. |
The files are Excel spreadsheets. These are static
resources which cannot enforce any access controls over
themselves, in the way that dynamic scripts can. It is
possible that the application is using other methods,
such as at the web server layer, to protect access to
the resources, but this is not typically the case. You
should quickly check whether the resources can be
accessed without authentication.
|
Chapter 9 – Injecting Code
| 1. |
You can determine the number of columns in two
easy ways. First, you can
SELECT the
type-neutral value
NULL from each
column, increasing the number of columns until the application
returns data, indicating that the correct number of columns were
specified, for example:
' UNION SELECT NULL--
' UNION SELECT NULL, NULL--
' UNION SELECT NULL, NULL, NULL--
Note that on Oracle you will need to add
FROM
DUAL after the final
NULL in each case.
Second, you can inject ORDER BY clauses and
increment the specified column until an error occurs, indicating
that an invalid column was requested:
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--
|
| 2. |
An easy way to confirm the database type is to use
database-specific string concatenation syntax to construct some
benign input within the query you control. For example, if the
original value of the parameter is
London you can
submit the following items in turn:
'||'London
'+'London
If the first results in the same behavior as the
original, the database is probably Oracle. If the second results
in the same behavior, the database is probably MS-SQL.
|
| 3. |
While it may seem counterintuitive, the user
registration function is probably the safest. Registration
functions normally use
INSERT statements,
which are unlikely to affect other records if you modify them. A
function to update personal records is probably using
conditional
UPDATE statements.
If you inject a payload like
' or 1=1-- you may
cause all records in the table to be modified. Similarly, the
function to unsubscribe is probably using conditional
DELETE
statements, and could impact on other users if you are not
careful.
That said, it is impossible to be completely
certain in advance which statements are being carried out by any
kind of functionality, and you should advise the application
owner of the risks before you perform the test.
|
| 4. |
An easy way to achieve the same effect without using
comment characters is with the input
' or
'a'='a.
|
| 5. |
You can SQL comment characters to separate
keywords and other items in your injected payloads, for example:
'/**/UNION/**/SELECT/**/username,password/**/FROM/**/users--
|
| 6. |
You can use the CHAR command to return a string
value from a numeric ASCII character code. For example, on
Oracle the string
FOO can be
represented as:
CHAR(70)||CHAR(79)||CHAR(79)
|
| 7. |
This situation arises where user-supplied input is
being placed into other elements of a query, such as
table and column names, rather than the query’s
parameters. A parameterized query cannot be precompiled
with placeholders for these items, so a different
solution needs to be used, probably based on very
stringent input validation.
|
| 8. |
Because you already have administrative access, it
is likely that you can retrieve any data you desire
using the application itself, meaning that a SQL
injection attack to retrieve the application’s own data
may be redundant. However, you can still leverage the
attack to access any data relating to other applications
that is held within the same database, or to escalate
privileges within the database or the underlying
operating system, to compromise the database server and
extend your attack into the wider internal network.
|
| 9. |
XPath injection can only be used to retrieve
data from the targeted XML file. Hence, if the application
contains no sensitive data this is likely to be a low impact
issue. Similarly, SQL injection flaws may not enable you to
extract any sensitive data from the database. However, they can
sometimes be leveraged to escalate privileges within the
database and develop your attack in other ways. Depending on the
situation, SQL injection may be a more significant
vulnerability. OS command injection, on the other hand, is
almost always a high impact vulnerability, because it usually
enables you to directly compromise the underlying server and use
it as the launch point for further attacks against internal
systems.
|
| 10. |
If the function is accessing a database, then
submitting the SQL wildcard
% as the search
query is likely to return a large number of records. Similarly,
if the function is accessing an Active Directory, then
submitting the wildcard
* is likely to
return a large number of records. Neither wildcard should have
the same effect on the other system.
|
Chapter 10 – Exploiting Path Traversal
| 1. |
Your attack appears to have successfully traversed
to the
/etc directory,
however the application is appending
.log to your
supplied filename. You can try a null byte attack to cause the
file system API to truncate the resulting filename at the end of
your input:
https://wahh‑app.com/logrotate.pl?file=../../../../../etc/passwd%00
|
| 2. |
The application appears to be performing some
sanitization on your input before it is processed by the file
system. It is possible that the application is stripping
../
sequences. To test for this filter, you should supply the
following input:
bar/....//foo.txt
It is also possible that the application is
replacing
../ with
./
instead. To test for this filter, you should supply the
following input:
bar/.../foo.txt
If either of these inputs succeeds in retrieving
the file
foo.txt then you
have probably determined how the filter works. Your next step
should be to use multiple instances of your successful traversal
sequence to attempt to step above the starting directory.
|
| 3. |
Attempting to retrieve the default file
boot.ini resulted in a built-in access denied
message. It is likely that your attack succeeded in traversing
to the target file, but that the web server process does not
have permissions to read this file (which by default can only be
read by Administrators, Power Users and System). You can confirm
this hypothesis by requesting a nonexistent file, such as:
https://wahh‑app.com/manage/customize.asp?file=../../../../zyxw.ini
and determining whether you receive a different
response – probably an error message indicating that the
requested file was not found.
If this test is successful, you can proceed to
retrieve arbitrary files from the file system that the web
server does have permission to access. For example, given that
you know the starting directory from which the files are being
retrieved, you can traverse via the web root to retrieve the
source code to the file
customize.asp
itself:
https://wahh‑app.com/manage/customize.asp?file=../manage/customize.asp
|
| 4. |
File systems tolerate redundant traversal sequences
that appear to traverse “above” the root of the file
system, and simply ignore any that are superfluous.
Hence, you do not need to know the depth of the starting
directory from the file system root. Indeed, it is often
safest to insert a large number of traversal sequences,
just in case your starting directory is unusually deep
within the file system.
|
| 5. |
Yes. Although you cannot access other logical
volumes, such as those holding operating system files,
you may still be able to exploit the vulnerability to
access sensitive information that you cannot obtain via
any other means, such as the source code to all scripts
hosted within the web root.
|
Chapter 11 – Attacking Application Logic
| 1. |
Forced browsing involves circumventing any
constraints imposed by in-browser navigation on the
sequence with which application functions may be
accessed. You should use forced browsing to test for
faulty assumptions in multi-stage processes and other
areas. These assumptions often lead to access control
weaknesses which you can exploit using forced browsing.
|
| 2. |
If quotation marks are doubled up before the
length limit is enforced, then you can introduce an odd number
of single quotes into your input by causing the input to be
truncated in between two doubled up quotes (see Chapter 9).
If the length limit is applied before the doubling
up, then you may still be able to exploit any buffer overflow
conditions by placing a large number of single quotes at the
start of your payload, causing this to extend sufficiently far
to overflow the buffer with crafted data positioned towards the
end of your payload.
|
| 3. |
Using valid credentials for an account you
control, you should repeat the login process numerous times,
modifying your requests in specific ways:
-
For each parameter submitted, try submitting
an empty value, omitting the name/value pair altogether, and
submitting the same item multiple times with different values.
-
If the process involves multiple stages, try
performing these stages in a different sequence, skipping
individual stages altogether, proceeding directly to arbitrary
stages, and submitting parameters at stages where they are not
expected.
-
If the same item of data is submitted more
than once, probe to determine how each value is processed, and
whether data that is validated at one stage is trusted later on.
|
| 4. |
The application may well be performing these two
checks independently, validating the password against one
username and the token’s value against a different username, and
then creating an authenticated session in the context of one
of the validated usernames.
If an application user who possesses their own
physical token manages to obtain the password of another user,
they may be able to login as that user. Conversely, depending on
how the logic functions, a user who can read the value from
another user’s token may be able to login as that user without
knowing their password. The overall security posture of the
solution is thus significantly diminished.
|
| 5. |
This behavior indicates that the error message
functionality is not thread safe, and is returning the
details of the last error generated by any user. You
should probe further using two different sessions
simultaneously to confirm whether this is the case. If
so, you should use a script to constantly trigger an
informative message and log any deviations in its
contents for interesting information relating to other
application users.
|
Chapter 12 – Attacking Other Users
| 1. |
User-supplied input is returned unmodified within
the application’s response to that input.
|
| 2. |
In most cases, XSS flaws within
unauthenticated functionality work just as effectively against
authenticated users – the functionality behaves in the same way,
resulting in arbitrary JavaScript execution within the context
of the authenticated user’s session.
Even if a target user is not logged in at the time
of the attack, they may still be compromised. If the application
is vulnerable to session fixation, then an attacker can capture
their token and wait for them to log in. An attacker can inject
code into the login page to capture keystrokes, or even present
a Trojan login form which sends their credentials elsewhere.
|
| 3. |
The answer to both questions is yes. The behavior
of course enables arbitrary JavaScript to be injected via a
crafted request. And although the attack vector does not appear
within the query string or the message body, arbitrary HTTP
headers including the Cookie header can be injected into the
request of a victim user via a Flash object hosted on a
third-party web site.
|
| 4. |
In isolation, it appears that this behavior could
only ever be used by a user to attack themselves.
However, in conjunction with another suitable
vulnerability, such as an access control flaw, it could
be highly significant, and could enable an attacker to
inject stored JavaScript into the pages displayed to all
other application users. From a defense-in-depth
perspective, the vulnerability should definitely be
fixed.
|
| 5. |
If the application displays HTML or text files
without any sanitization, then JavaScript contained within these
will execute within the browser of any user who views the
attachment. Further, if a JPEG file contains HTML, then this
will be automatically processed as HTML within the Internet
Explorer browser. Many web mail applications do not adequately
defend against XSS in message attachments.
|
| 6. |
Because XMLHttpRequest can be used to retrieve
the full response from an HTTP request, it can only be used to
make requests to the same domain as the one that is invoking it.
|
| 7. |
There are countless different attack payloads for XSS exploits. Some of the more commonly discussed payloads
are:
-
stealing the session cookie;
-
inducing user actions;
-
injecting Trojan functionality;
-
stealing cached autocomplete data;
and
-
logging keystrokes.
|
| 8. |
You can perform a request forgery attack, by
injecting an arbitrary URL into the image tag that is crafted to
perform some malicious action. When a user views the page, the
action will be performed within their user context.
You can perform a stored XSS attack by injecting
arbitrary script into an event handler, for example:
"onerror="alert(document.cookie)
|
| 9. |
You can “convert” the reflected XSS flaw into
a DOM-based one. For example, if the vulnerable parameter is
called
vuln, you can use the following URL to execute an
arbitrarily long script:
/script.asp?vuln=<script>eval(location.hash.substr(1))</script>#alert('long
script here ......')
|
| 10. |
If the POST method is mandatory, you cannot simply
construct a crafted URL within the application that will
execute an attack when a user visits it. However, you
can create a third-party web page that submits to the
vulnerable application a form using the POST method and
the relevant parameters in hidden fields. You can use
JavaScript to automatically submit the form when a user
views your page.
|
| 11. |
In browsers that support HttpOnly cookies,
setting this flag prevents client-side JavaScript from gaining
direct access to the cookie’s value, thus preventing one common
attack payload for exploiting any XSS flaws. However, if the
TRACE method is available,
XMLHttpRequest can be used to make a
TRACE request to the web server, and (in the response to this
request) retrieve the values of all cookies submitted.
Unfortunately for the attacker, XMLHttpRequest no longer
supports the TRACE method in today’s browsers, and so the
security significance of having this method enabled has
diminished.
|
| 12. |
(a) Arbitrary redirection to lend credibility
to a phishing attack.
(b) Injection of a cookie header to exploit a
session fixation flaw.
(c) A response splitting attack to poison the
cache of a proxy server.
|
| 13. |
The application is using named frames and so is
vulnerable to frame injection attacks against older
browsers.
|
| 14. |
An attacker must be able to determine all of the
relevant parameters to the function in advance – that is, they
must not contain any secret or unpredictable values that an
attacker cannot set without already having hijacked a victim’s
session.
|
| 15. |
(a) The standard anti-XSRF defense of including
an unpredictable parameter within requests for JSON objects
containing sensitive data.
(b) The insertion of invalid or problematic
JavaScript at the start of a JSON response.
(c) The mandatory use of the POST method for
retrieval of JSON objects.
|
Chapter 13 – Automating Bespoke Attacks
| 1. |
(a) HTTP status code
(b) Response length
(c) Contents of response body
(d) Contents of Location header
(e) Setting of any cookies
(f) Occurrence of any time delays
|
| 2. |
There are no definitive answers to this question.
The following are examples of fuzz strings that are suitable for
testing each of the categories of vulnerability. There are many
other strings that would be equally suitable.
(a)
'
'; waitfor delay '0:0:30'--
(b)
||ping -i 30 127.0.0.1;x||ping
-n 30 127.0.0.1 &
(c)
../../../../../../../../../../etc/passwd
..\..\..\..\..\..\..\..\..\..\boot.ini
(d)
http://<yourservername>/
|
| 3. |
In many situations, modifying a parameter’s value
in some way will result in an error, causing the application to
stop the rest of its processing on that request. The application
will not therefore execute various code paths in which the other
parameters may be processed in unsafe ways.
One effective way to ensure that you achieve a
decent level of code coverage with your automated fuzzing is to
use a benign request as your template, and to modify each
parameter in turn, leaving the other parameter with their
initial values. You can then go on to perform manual testing of
multiple parameters simultaneously, based on the results of the
fuzz testing and your understanding of the role of each
parameter. If time permits, you can also go on to perform more
elaborate fuzzing, changing multiple parameters simultaneously
using different permutations of payloads.
|
| 4. |
Often, in addition to the redirection, the
application will set a new cookie when you submit to valid
credentials, assigning you an authenticated session that will
result in different content when you follow the redirection. If
this is the case, then you can use the presence of a
Set-Cookie
header as a reliable indicator of a hit.
If this is not the case, and the application
simply upgrades your existing session when you submit valid
credentials, then your script will probably need to follow the
target of the redirection and inspect the contents of the
resulting page to determine whether you have successfully logged
in.
|
| 5. |
If you are lucky, you will be able to devise a
regular expression that uniquely matches the data
preceding the information you need to capture, or the
data item itself. Otherwise, you will probably need to
create a completely custom script to parse each
application response and identify the interesting item.
|
Chapter 14 – Exploiting Information Disclosure
| 1. |
The application is inserting your input directly
into a dynamically constructed query. However, it appears to be
stripping any whitespace characters from your
input, as can be seen from the expression
having1
that appears in the error message.
The condition is certainly exploitable. You can
use SQL comments instead of whitespace to separate items of
syntax in your query, for example:
https://wahh-app.com/list.aspx?artist=foo'/**/having/**/1%3d1--
which returns the different error message
Server: Msg 8118, Level 16, State 1, Line 1
Column 'users.ID' is invalid in the select
list because it is not contained in an aggregate function and
there is no GROUP BY clause.
This confirms that the
condition can be exploited and completes the first step in
enumerating the structure of the query being performed.
|
| 2. |
The error message indicates the usernames that the
application is using to access the database, the mode of
connecting, the absolute file paths of the application’s
web content, and the line numbers in the scripts where
the errors were generated. In isolation, each item of
information may appear inconsequential. However, in
conjunction with other vulnerabilities this information
may assist you in developing a focused attack against
the application.
|
| 3. |
This is a system-generated error message produced
by
cgiwrap. It
indicates that the script you requested cannot be executed on
the server because it does not have suitable file permissions.
This script is therefore probably of little interest to you.
The error message contains some information that
may be of use, including an email address. More significantly,
however, it contains various details that have been copied from
the client request. You should probe the server’s handling of
crafted input in the relevant request headers to see if the
error message is vulnerable to XSS. Note that a user can be
induced to make a request containing arbitrary request headers
via a Flash object.
|
| 4. |
You supplied the value
admin
in the
name parameter. The error message indicates that
the application attempted (and failed) to connect to a database
on a host named
admin. It appears
that the application is letting you control the database that it
will use to fulfill the request.
You should try submitting the IP address or
hostname for a server that you control, and see if the
application connects to you. You should also try to guess a
range of IP addresses within the internal network, to see if you
can probe for other databases reachable from the application
server.
Given that the supplied hostname has been copied
into the error message, you should also investigate whether the
application is vulnerable to XSS. Peripheral content such as
error messages is often subject to less rigorous input
validation and other controls than the primary functionality
within the application.
|
| 5. |
The error message is generated by a script that is
attempting to assign your string-based input to a
numeric variable. It appears that you will hit this
error any time that you supply data in this parameter
that is not numeric. There is no indication that your
input has caused a database error, or even been
processed by a database. This parameter is almost
certainly not vulnerable to SQL injection.
|
Chapter 15 – Attacking Compiled Applications
| 1. |
With stack-based overflows, you can usually get
immediate control of the saved return address on the stack, and
therefore the instruction pointer when the current function
returns. You can point the instruction pointer at an arbitrary
address containing your shellcode (usually within the same
buffer that triggers the overflow).
With heap-based overflows, you can usually set an
arbitrary pointer in memory to an arbitrary value. Leveraging
this modification to take control of the flow of execution will
normally involve a further step. Further, once a heap buffer has
been overflowed, your attack may not execute immediately but may
depend upon unpredictable events that impinge upon the
allocation of heap memory.
|
| 2. |
There is no separate record of the length of a
standard C/C++ string. The string is considered to
continue until the first null byte after the start of
the string.
|
| 3. |
Although it may be relatively easy to probe for
and detect a buffer overflow vulnerability in a remote web
application, developing a working exploit for the bug will in
general be extremely difficult (though not absolutely
impossible).
With local access to a vulnerable network device,
on the other hand, it is possible to attach debugging equipment
and fully investigate the nature of the vulnerability, and
thereby develop a finely crafted attack to exploit it reliably.
|
| 4. |
The
%n format
specifier has been disabled by default in the latest
implementations of the
printf family of
functions. Hence, you should always supply a large number of
%s
specifiers, which will always be supported and are very likely
to trigger an exception if your input is handled in an unsafe
way.
Further, using only the
printf family of
specifiers will not detect vulnerable calls to other formatting
functions, such as FormatMessage.
|
| 5. |
You have probably identified a heap overflow
vulnerability. Every overlong request you are submitting is
probably causing corruption of the heap control structures.
However, heap corruption normally only results in an exception
when a relevant heap operation takes place, and the timing of
this operation may depend on other events that are unrelated to
the requests you are submitting.
Note that in some rare situations, the same
behavior may occur for different reasons – for example, because
of load balancing or deferred processing of your input.
|
Chapter 16 – Attacking Application Architecture
| 1. |
You can almost certainly exploit the vulnerability
to retrieve application data held within the database.
The application itself must possess the necessary
credentials and privileges required to access its own
data. You can examine the server-side application’s
scripts and configuration files to discover how it
access the application. An obvious way to exploit the
vulnerability you have found would be to create some new
scripts within the web root that enable you to perform
arbitrary queries and retrieve the results using your
browser.
|
| 2. |
Even if you fully compromise the entire database
server, this may not necessarily provide a means of
compromising the application server. In a typical case,
the application server accesses the database server
solely as a database client, and the database server may
not be trusted in any other way by the application
server. Nevertheless, it is probably possible to modify
the content returned to users, since some of this will be
generated using data contained within the database. For example,
even if the application contains no stored XSS vulnerabilities
that can be triggered within the application itself, you may be
able to inject arbitrary scripts into the application’s
responses by modifying data directly within the database. If
this enables you to attack an administrative user then you may
quickly be able to compromise the entire application.
|
| 3. |
The PHP language contains a number of powerful
functions, which can launch operating system commands and access
the file system. If you are able to modify the files used by
another application, then you can probably compromise that
application. However, the possibility of achieving this depends
greatly on the configuration of the PHP environment, and the
existence of any controls over your actions implemented lower
down the technology stack.
|
| 4. |
Locating all application components on the same
server normally prevents effective segregation between
those components, meaning that a compromise of one part
of the application’s architecture can quickly lead to
the compromise of others. For example, a file disclosure
vulnerability within the web application may enable you
to retrieve files containing sensitive data from the
database. Similarly, a SQL injection vulnerability may
enable you use database functions to write arbitrary
files on the server file system, creating scripts within
the web root that you can access from your browser, and
thereby directly compromise the application tier.
|
| 5. |
You can perform Internet searches on key URLs and
parameter names to locate other applications employing
items with the same names. If these applications appear
to contain a large overlap of shared functionality, you
can investigate where they are physically hosted to gain
additional evidence.
|
Chapter 17 – Attacking the Web Server
| 1. |
A web server will display a directory listing if
you request a URL for a directory and:
(a) the web server cannot find a default
document such as
index.html;
(b) directory listings are enabled;
(c) you have the required permissions to access
the directory.
|
| 2. |
WebDAV methods allow web-based authoring of
web content.
These methods may be dangerous if they are not
subjected to strict access control. Further, because of the
complex functionality involved, they have historically been a
source of vulnerabilities within web servers – for example, as
an attack vector for exploiting operating system vulnerabilities
via the IIS server.
|
| 3. |
If the proxy allows connection back out to the
Internet, you could use it to attack third party web
applications on the Internet, with your requests appearing to
originate from the misconfigured web server.
Even if requests to the Internet are blocked, you
may be able to leverage the proxy to access web servers within
the organization that are not directly accessible, or to reach
other web-based services on the server itself.
|
| 4. |
The PL/SQL Exclusion List is a pattern-matching
blacklist designed to prevent the PL/SQL gateway from being used
to access certain powerful database packages.
Various bypasses have been discovered to the
PL/SQL Exclusion List filter. These essentially arise because
the filter employs very simple expressions, while the back-end
database follows much more complex rules to interpret the
significance of the input. Numerous ways have been discovered of
crafting input that does not match the blacklist patterns but
nevertheless succeeds in executing the powerful packages within
the database.
|
| 5. |
It is possible that using HTTPS for communication
may conceal your attacks from some network-layer
intrusion detection systems. Using HTTP, however, will
typically enable your automated attacks to execute much
faster. The application may contain different content or
behave differently when accessed via the different
protocols, so in general you should be prepared to test
using both.
|
Chapter 18 – Finding Vulnerabilities in Source Code
| 1. |
(a) Cross-site scripting
(b) SQL injection
(c) Path traversal
(d) Arbitrary redirection
(e) OS command injection
(f) Backdoor passwords
(g) Some native software bugs
|
| 2. |
PHP uses a range of different built-in arrays
to store user-submitted data. If
register_globals
is enabled, then PHP creates a global variable for every request
parameter, and applications may access a parameter simply by
referencing a variable with the same name – there is no
syntactic indication that this variable represents user input as
opposed to any other variable defined elsewhere.
|
| 3. |
Method 1 is more secure.
Although method 1 constructs a SQL query
dynamically from user input, it doubles up all single quotation
marks that appear within that input, and all user-supplied
parameters are treated as string data. Although this is not the
best practice way to handle SQL queries safely, there does not
appear to be any opportunity for SQL injection in the present
case.
Method 2 uses a parameterized query, which is the
preferred way to incorporate user-supplied data into SQL
statements in a safe way. However, only two of the three items
of user input are properly parameterized. One of the items is
erroneously placed directly into the string that specifies the
query structure, and so the application is fully vulnerable to
SQL injection.
|
| 4. |
The application may be vulnerable to reflected XSS, because it appears that an on-screen welcome message is
being constructed directly from a request parameter.
It is not possible to confirm conclusively whether
the application is vulnerable from this code snippet alone. To
do this, you would need to investigate:
(a) whether any input validation is performed
on the
name parameter elsewhere; and
(b) whether any output validation is performed
on
m_welcomeMessage before it is copied into the
application’s response.
|
| 5. |
Yes. With knowledge of the token creation
algorithm used, it is possible to extrapolate forwards and
backwards to identify all tokens created by the application, on
the basis of a single sampled token.
The Java API
java.util.Random
implements a linear congruential generator that generates
pseudo-random numbers according to a fully predictable
algorithm. Knowing the state of the generator at any iteration,
it is possible derive the sequence of numbers that it will
generate next, and (with a little number theory) derive the
sequence that it generated previously.
However, the
java.util.Random
generator maintains 48 bits of state, and the
nextInt
method only returns 32 bits of that state. Capturing a single
output from the
nextInt method is
not sufficient to determine the state of the generator, or to
predict its sequence of outputs.
In the present case, this difficulty can be
easily circumvented because the algorithm used by the application makes
two successive calls to
nextInt. Each
session token created contains 32 bits of state from one
iteration of the generator, and 32 bits of state from the next
iteration. Given this information, it is straightforward to
perform a local brute force exercise to discover the missing 16
bits of state at the first iteration (by trying each possible
permutation of the missing 16 bits, and testing whether the
generator outputs the 32 bits captured from the second
iteration). Once the missing 16 bits have been confirmed, the
full state of the generator is known, and you can proceed to
derive subsequent and earlier outputs in the standard way.
Ironically, the developers’ decision to make two
calls to
nextInt and
combine the results renders the token creation algorithm more
vulnerable than it would otherwise be.
See the following paper by Chris Anley for more
details of this type of attack:
http://www.ngssoftware.com/research/papers/Randomness.pdf
|
|