Skip to content

A Web Application Security Audit.

In this article we will give an introduction to the security audit process for Web Applications. It will introduce some of the key concepts that we will use over the next couple of weeks. We will also introduce the main stages of a pentest for web applications.

When to Test.

With software development, it is still reasonably common for the testing phase to take place after all the code has been developed. While this means we can test the full application, but can also increase the time taken and cost of fixing issues. This is similar to having, security audit during development VS a pen-test of developed software.

While we are going to focus on the "red team" side of things, any Security Audit should not be limited to pentesting. Security Audit certainly has a place as part of a more general software development process3, with the "Security" and "Development" teams working together to deliver a secure piece of software.

Important

In software design, there is a strong argument for "Test early and test often".

The later in the development process an issue is discovered, the harder and more costly it can be to fix. For example: discovering an logical error such as using Local time, rather than UTC for timestamps after the code is deployed would mean extensive work refactoring code, and rebuilding the database.
If it is picked up at the design stage, its a quick fix to the design documents.

A process such as test driven development, where the tests are designed and written before any of the code is implemented means we can be sure of writing code that meets the design5

We can apply a similar approach with security. If the software team decide to store passwords as MD5 Hashes, its a lot easier to fix during a security audit at the design phase, rather than during a pentest of the final product.

By integrating security audit as part of the development process we can:

  • Avoid design decisions that can lead to security flaws
  • Confirm the Implementation meets the design
  • Check for security issues we had not anticipated during the design process.

On the whole the process used for testing during development is similar to that used for a pen-test. In this weeks materials we will focus on the general testing strategy, and highlight where the approach may differ.

Agile and Security

Rapid Application Development (RAD) appoaches such as Agile are popular for web development. Here, tasks and functionality are broken into "sprints" where the focus is on implementing small chunks of code in a short time frame4. The approach ephasises flexibility and a focus on the actual development, rather than the longer drawn out planning phases involved in traditional software development.

This rapid development is great for getting functionality implemented quickly and efficiently. It also allows developers to respond to problems during development.

However, this seems to go against the requirements for security. Where a more strucured approach to development seems to be required

Can Agile development also be secure ?
What are your views,  can you think of ways that we could incoproate security with rapid development?

Dont worry too much if you havent come across agile before, the question is more about getting you to think
around how security could be added to development, than the specific software design process.

Why have Structure to our tests

We look1 at a general pen-test process in detail in the Practical Pentesting module. For a Web application, the same general stages are applied:

  1. Preparation
  2. Reconnaissance
  3. Exploitation
  4. Post Exploit
  5. Writeup
Preparation
We set out our rules of engagement, and the scope of any testing. This will be much the same as the process we discuss in 5063CEM.
Reconnaissance
Is probably the most important element of any pen-test, and we will focus on it over the next couple of weeks.
Here we look at identifying potential issues with the site, and we will build upon this for the later stages. A Key element here when assessing web applications is understanding the flows of information on the site.
Where can an user use data to interact with the site, how is that data processed and presented back to the user?
Exploitation
The Fun part, working out how to break the site for fun and profit. While it might be fine just to jump into the exploitation in a CTF (of for learning), as a professional pen-tester you will also be expected to report on any vulnerabilities you find.
Without the earlier stages can you be sure that you have identified all2 the possible issues, and properly documented them.
Post Exploitation
Aims at strengthening any foothold we have gained during exploitation.
This could include understanding the types of data that are available, or gaining a foothold on the server itself.
Writeup:
Where the money gets made. Categorising and rating the issues that were discovered, and presenting solutions for mitigation to the customer.

What information is available to us?

The level of information about the site will change the way we approach the test. If we have design documents showing all of the data inputs, then it reduces the amount of work we need to do in the recon phase inferring these elements. Similarly an overview of the site structure makes it easier to identify API endpoints.

Broadly speaking there will be different levels of information available.

Black Box Testing

Is where we have no prior knowledge of the system behind the site. This is our 'classic' pen-test where we act like an attacker to try to gain access.

Without knowlege of the system, our job becomes to infer the structure of the application then try to exploit it.
This has some benefits, as we will tend to use the same tools, techniques and exploits as real world attackers. However, it also has the disadvantage that some exploits could be missed, as its incredibly difficult, and time consuming, to identify and test all of the application logic.

White Box Testing

Is where we have access to the source code, and / or design documents for the application.

This can make aspects of our work much easier. As we can use the source to work out the logic behind the site. This means it can be easier to identify potential security issues. It also means that our tests are likely to cover a wider range of problems, as elements that may be "hidden" (for example API end points) are shown, and dont need to be inferred.

Grey Box Testing

Commonly we will be testing somewhere in-between. For example, we could not have access to the source for a site, but the specification of the pen-test may give us some information on the backend structure due to the things it asks us to test.

We may also be able to gain more insight into components we have identified during the recon phase of a black box test. For example, if open-source or publically available software compoenets are used.

Types of Testing: Static Analysis

Static analysis is a set of techniques that can analyse the correctness of the software code without executing it. While a lot of these methods may be more applicable to branches of computer science such as formal methods6 where we aim to prove our code is correct before implementing it.

Some forms of Static analysis involve low-level techniques like Code Inspection or Review, Syntax Checking and Standards, which can be used manually or through a simple automated tool.

There are also more complex methods of Static analysis require more advanced technology, and use automated tools for the reasoning and examination of software. Such cases are the Automated analysis of programs (e.g. Data Flow Analysis) and the Finite state verification (e.g. Model checking).

Data Flow Analysis

This form of testing involves examining all data flows in the system, and checking the logic behind processing. This can help us to see how data is manipulated before being used.

For example, Consider a website login page, We know that the data should:

  1. Be transmitted from the site to the server in a secure way
  2. Have input sanitised (remove potential bad input) before processing
  3. Input password should be hashed to allow it to be checked in the database
  4. Input should be used for validation in the database.

We can then go through each stage of our program and map these requirements against what actually happens in the code. For Example

  • Step 1: (secure transport) happens as part of HTTP when the user connects
  • Step 2: (sanitisation) May happen:
    • on the client side, IE check format of emails etc. This can help filter some bad input and improve user experience.
    • As we KNOW we cannot trust client side validation It also needs to occur on the server side after the input is received.

By documenting each of the requirements, and mapping it to a code component that performs this task, we can demonstrate the requirements are met.

Code Review

Code review can also be used at this stage. Here we look through the code manually, searching for potential vulnerabilities.

While its time consuming (and sometimes hard to do right) If we have access to the source for the application, it can make our life easier, as it reduces the number of unknowns in our audit. We are able to see the logic that is applied to user input, the queries sent to databases etc, and analyse them for weaknesses.

Types Of Testing: Dynamic Analysis

Is all about running the code and checking if it works. You should be familiar with this approach through the standard Unit Testing.

Dynamic analysis allows us to check for flaws in the way data is handled and input.

Tools for Dynamic Analysis include:

  • Unit Testing
  • Fuzzing
  • Vulnerability Scanning.

Automated VS Manual Testing.

There are many automated tools that can help with the testing process.
For example automated vulnerability scanners like Nessus, or OpenVAS will try to automate aspects of black box testing. Tools like Wapiti or Bandit will perform analysis of source code to identify potential issues.

Manual analysis can be time consuming, and require knowledge of the systems the application is based on. For example if the tester is not aware of SQL injection, then they may miss any possible issues where databases are involved. However, it does give us an opportunity to perform a comprehensive test.

While automated vulnerability scanner can reduce the amount of work we need to perform, we still need a manual element here. A tool will only perform as well as the input parameters it is given, and the tests coded into the tool itself. This means that they can miss potential security issues in the site.

Example

Lets take the ProFTP Backdoor vulnerblity from 2010 as an example here.

At some point the source code for ProFTP 1.3.3c was comprimised with a backdoor being added. Sending the Creds HELP ACIDBITCHEZ when authenticating with the FTP server would open a remote shell.
The issue was quickly (within 1 day) discovered during a source code audit, and the code was fixed.

This kind of thing is reasonably easy to detect during a code audit. We would identify an input stream, and see that it calls a shell function, which should be enough to be suspicious.

However, with automated testing this would be harder to detect.

Lets say our tool does input fuzzing on the username / password combination. This means that we test lots of different combinations of usernames and passwords to see if we get a result. The combination is unlikely to be in any password lists, and testing on a character by character basis would require around \(15^{72} == 4 \times 10^{84}\) different combiations. This means that an automated scan would not be likely to detect the issue.

Note: Now we know about the problem, checks for it have been incorporated into the scanning tools. However, we would have been unlikely to detect it in the first place.

One area where automated tools are invaluable is automated testing issues you have identified. Unlike a general vulnerability scanner, this means that we can target the tool towards an specific issue identified during a manual review, thus saving time and effort checking multiple inputs.

Lets say we identify areas where user input is directed to the database during the manual review process.
Automated tools like SQLMap would allow us to test the input sanitisation (and extent of any issues) without having to manually check all possible problems.

Additionally, writing automated POC code for exploits you have discovered in a site can allow you to check the process with different inputs, and gives us some way of checking if the exploit has been fixed.

Summary

In this article we have introduced the concepts behind security audit for web applications.

We have discussed how testing shouldn't just be limited to the traditional penetration test, but part of the development process.

We have also looked at how we may have access to different parts of the application when testing, and how this can effect the way we test and its outcomes.

Finally, we looked at some common testing methodologies, examining static and dynamic analysis. We also discussed the benefits and drawbacks of manual and automated testing.

In the next article we will take a look at the Reconnaissance process, how we can start to infer the structure of a site, and identify areas that should be tested.

Further Reading


  1. Whether we "Have" or "Will" is going to depend on timetables. The Plan is to be doing it the same week in both, but at the time of writing, I don't have timetable information. 

  2. We could argue whether it is ever possible to identify all issues. However, applying structure can help you find the majority of them. 

  3. Which is Why I teach a security module to the 3rd year comp-sci students 

  4. Its a heck of a lot more than this, but that's a whole software design module. 

  5. Test Driven development is a great idea, but not without its own problems. Sometimes the design of a component wont be clear until other elements are implemented, making the tests hard to write. This is where the agile style of working on features is a great idea. 

  6. Why don't people use Formal Methods 

Back to top