Setting up Web Application Pentesting Tools

This post will walk you through how to set up the basics needed to do web app pentesting. More specificly, we’ll be setting up a web browser for pointing and clicking, an attack proxy for hackety hacking – all while covering the configuration needed.

What Tools do I Need to be a Hacker?

This post is not intended for script kiddies.

I’m not opposed to accessible tools or automatic scanners, though I believe you should know how they work and what they do before using them regularly. A skilled professional should ideally be able to make do with very basic tools, and use more advanced utilities only as a way to increase efficiency.

If you don’t understand the basics, then you will never be good at security testing.

The Attack Proxy

We could get a lot done with just a web browser, though it’s not the best way of working. We want to be able to control how we interact with the web application, and that means being able to:

  1. Audit requests and responses to/from the web server.
  2. Stop requests from being sent.
  3. Edit requests before they are sent to the web server.
  4. … list goes on.

We can use an HTTP proxy instead of instrumenting a web browser with these features. In this case we’ll have a look at the Burpsuite Community Edition.

Head over to and download the free community edition.

A note on the paid version. I can highly recommend getting the professional license, but only if you actually are going to use it for work. The free variant has everything you need when starting out or messing around.

Setting up Burp

It comes with good defaults, so you don’t have to do anything except actually installing it.

Burp organises stuff in “projects”. Projects contain project-specific settings together with all proxy data and state information. We’re free to use a temporary project in the community version. Pro users can either use persistent projects (data is written as you use it, recommended), or save snapshots of temporary projects.

Press Next.

Next up is the project configuration. The defaults are okay. When you are comfortable with Burp and know what settings works best for you, then you are free to flush those specific settings to a JSON file, which could be used to speed up this step in the future.

Click Star Burp, and wait while it initialises a new temporary project for you.

A note on temporary projects. Or rather, a word of advice. Never rely on Burp not crashing. If you have important data in your project, copy it out of Burp immediately. For you this most likely translates into copying interesting URLs into notepad.

Don’t let the interface intimidate you. Burp Suite is a suite of related tools. We’ll cover this in another post. For now, we just want to export the CA certificate. We will be using Burp as a proxy for our web browser, which means that all traffic will pass through Burp. If this traffic is encrypted (HTTPS), then Burp will have to either:

  1. Pass the traffic on, without being able to inspect it (because it is encrypted).
  2. Interfere with the encryption (man-in-the-middle attack). This is what we want.

In order to keep our web browser happy we need to firmly tell it to pretend that everything is all right. We do this by importing a fake certificate and saying it’s “trusted”.

Click “Proxy” in the top tab bar, and then “Options” in the second tab bar. In the top of the options list we’ll find the “Import / export CA certificate”. Opt to export the certificate from Burp in DER format, and save it to Desktop or somewhere convenient.

The Web Browser

I’m not going to impose any web browser restrictions on you. We don’t judge people based on their browser preferences.

Download and install Firefox. You should be able to do that on your own.

When it’s installed, go ahead and open it once just to be sure it’s set up properly. Then close it down.

Firefox Profiles and Configuration

Firefox stores all user data in so-called “profiles”, which are nothing but a folder containing all your data, browsing history, and plugins. I highly recommend using a separate profile when testing, as you might disable a bunch of security features down the line.

Fire up the Run dialogue (hotkey Win+R) and type “firefox -P” followed by firmly pressing the Enter key on your keyboard.

You’ll find the Firefox profile switcher thingie on screen, which I’m sure most users don’t even know exist. Anyhow, you want to create a new profile, give it a good name (I named mine “pentest”), and uncheck the default checkbox. I drew an arrow pointing at it on the above image.

To launch Firefox with a specific profile right away, simply pass the profile name as an argument.

It’s worth mentioning that you of course can save any and all command line arguments in the Windows shortcut. Create a new shortcut and append whatever you need.

Next up is importing the certificate.

To import the Burp CA certificate we go to Settings, then Privacy & Security, scroll down, and click “View Certificates…”. In the resulting dialogue click “Import…” and select the certificate file you exported from Burp.

Check the first checkbox, indicating that you want to trust certificates signed by the Burp CA certificate. You should only do this in a user profile you use for pentesting, not a user profile you use to log on to your bank.

Click OK to save. Next up is linking it to our proxy.

I can highly recommend using a proxy switcher of some sort because changing proxies through the Firefox configuration is painful and slow. Though for the sake of minimising the amount of things we need to install, we’re going to set it up the old fashioned way.

Why switch proxies? Well, everything is set up in a separate profile, so your regular browsing is not going to be affected by the settings we save in the pentesting-profile. Though there are occasions when you might need to do some switching in the field, e.g. Burp or Java doesn’t play nice with the remote server when it comes to cipher negotiation, or perhaps you are running two or three instances of Burp or similar tools simultaneously.

Go to settings, scroll down, open the network proxy settings. Select manual and set it to “localhost” (or and port 8080. The port number should point to the port used by Burp, which is 8080 by default. If you have other software running on that port, then there will be an error message in the Burp logs, and you can set Burp to use a different port. Check “Use this proxy for all protocols” (or at least manually fill in the same values for SSL Proxy).

Note that Firefox will by default ignore the proxy settings if the remote server is at localhost. If you are port forwarding from a virtual machine, or if the application you’re attacking is hosted locally, then you will need to remove localhost and from “No Proxy for” in the dialogue above.

Taking it for a Spin

In Firefox, go to or any other unencrypted site. It should be stuck loading (most likely). Open up your Burp window.

The Proxy tab is highlighted. Click it.

The default setting in Burp is to start with intercept turned on. This means that some requests/responses (configurable) will be caught and held until you decide what to do with them. Press “Intercept is on” to disable this feature. Firefox should now load the page.

If that works, go to a secure page such as and inspect the certificate.

You shouldn’t get any errors. If you get a certificate warning, then you most likely forgot to import and trust the Burp CA certificate.

You should also go to Proxy/HTTP History and make sure you can see the requests there.

There’s a bunch of filters affecting your view by default, so don’t worry if you can’t see everything. The important thing is that you have at least one HTML document on HTTP, and one on HTTPS.

That’s it! I hope the guide helped you get started by showing you a simple example and how to set it up. Let me know if you get stuck or if something isn’t clear :3!

F-Secure Radar Login Page Unvalidated Redirect Vulnerability



The application will upon successfully logging in redirect the user to a user-controlled destination. A victim user may not recognise that a redirection takes place as they expect to be sent to a new page.

Vendor Description

F-Secure Radar is a turnkey vulnerability scanning and management platform. It allows you to identify and manage both internal and external threats, report risks, and be compliant with current and future regulations (such as PCI and GDPR compliance). It gives you visibility into shadow IT – to map your full attack surface and respond to critical vulnerabilities associated with cyber threats.


F-Secure has remediated this issue; no action required for cloud users or on-premise users receiving updates.

Technical Details

Navigating to the Radar application at will result in the user being sent to

Upon successful authentication, the value of the ReturnURL query parameter will be used to determine the redirect destination. It is possible to set this to any arbitrary domain as the value is neither validated nor forced to be a relative path.

The following URL would redirect the user to after logging in:

This could be used to send the user to a phishing site, prompting them to re-authenticate (e.g. “Wrong password or username, please try again”).

Vulnerability Disclosure Timeline

2018-02-05 – Vulnerability discovered
2018-02-05 – Vendor contact & response
2018-02-09 – Vendor confirms fix
2018-02-15 – Public disclosure

F-Secure Radar Persistent Cross-Site Scripting Vulnerability



The application can suggest metadata tags for assets, and in doing so it can execute JavaScript entered previously by a malicious user.

Vendor Description

F-Secure Radar is a turnkey vulnerability scanning and management platform. It allows you to identify and manage both internal and external threats, report risks, and be compliant with current and future regulations (such as PCI and GDPR compliance). It gives you visibility into shadow IT – to map your full attack surface and respond to critical vulnerabilities associated with cyber threats.


F-Secure has remediated this issue; no action required for cloud users or on-premise users receiving updates.

Technical Details

The frontend application issues a PUT request to the server when metadata tags are updated:

PUT /api/latest/vulnerabilityscans/tags/batch HTTP/1.1

The Tags parameter in the JSON request body can be modified to contain arbitrary JavaScript, e.g.:

[…], “Tags”:[“<img src=a onerror=\”alert(1)\”>”], […]

This script will execute whenever the frontend attempts to suggest tags, e.g. when a user opts to add tags to a new asset.

Vulnerability Disclosure Timeline

2018-01-24 – Vulnerability discovered
2018-01-24 – Vendor contact & response
2018-02-01 – Vendor confirms fix
2018-02-15 – Public disclosure

OWASP Top 10 2013 – A3 – Cross-Site Scripting

> Is your address really street”/><script>doStuff();</script>?

Cross-Site Scripting attacks are tremendously prevalent, which I find surprising because it is an easy problem to detect and to remediate. There are even a lot of decent mitigation alternatives out there as well.

What is Cross-Site Scripting (or XSS, if you prefer)?

Cross-Site Scripting occurs whenever someone else is able to run JavaScript within your site. This could, of course, happen if someone can upload HTML files (containing scripts), but the dominating attack vector is regular input fields.

For example, a web application might have a search feature:


The resulting page might then contain:

<h1>Search results for: test</h1>

From this basic example we can assert that the user is in control of two things regarding the content:
1. What search results are present on the search page
2. A section of the body is directly correlated to the search term (parameter search)

So searching for “asdkhafohgsoudghs” would possibly yield zero results. Searching for “e” might match every single entry. That makes sense, but is not that useful to us at the very moment.

The fact that whatever we supply as the search parameter is directly reflected is very interesting. The intended behaviour is to reflect the search query, but what if we enter HTML?

search.php?search=test<img src=test/>

It would probably look something like:

So we managed to inject a broken image by entering the corresponding HTML. Nice. Now, what about that Cross-Site Scripting?

search.php?search=test<img src=test onerror=”alert(‘:)’)”/>

At this point, we have the ability to inject and run JavaScript.

So why is this a bad thing?

> … After all, it’s just alert boxes!

Everyone likes to bash JavaScript for being horrible. While some (most?) criticism is legitimate, keep in mind that it’s possible to do pretty much anything once you can run it.

There are some restrictions in place, one of them being that some stuff can only be performed within the current domain. That’s why we need to inject the scripts on the victim site. Otherwise it would be REALLY easy wreak havoc on the internet.

Because when you have access to inject JavaScript, you can:
1. Steal the cookies, nom nom
2. Hijack the current session (either cookies or other tokens)
3. Modify the cookies, if that is useful
4. Modify or completely replace the current page
5. Steal credentials, keystrokes, and so on
6. Redirect the users

What flavour do you want?

XSS comes in different varieties, as is to be expected.

Reflected Cross-Site Scripting
So the example we had above was a reflected cross-site scripting. You input something, the site reflects it, and the attack triggers. If you do this attack, then you XSS yourself. Not that effective.

Usually, you would want to forge some URL that you can send to a victim, preferably disguise it as well. In some cases (e.g. POST-request) you need to leverage a CSRF-attack in order to get the script in there.

Persistent Cross-Site Scripting
While there is no difference for what you can do, persistence makes further attacks easier. Depending on where the script is presented, it might also make exploitation easier.

For a Persistent Cross-Site Scripting to occur, a script that is injected once must be stored and then consistently be presented by the web application. For example, a user might change their display name to “Derp<script>…</script>”

Semi-Persistent Cross-Site Scripting
Reflected and Persistent pretty much had a baby. Important to note here is the scope of the attack, for how long is the attack persistent? X page loads? X minutes? Per session? Day? Until something else happens?

DOM-Based Cross-Site Scripting
I’ll leave this for another day, but you could of course go ahead and read OWASPs stuff!

Essentially, code can be supplied to and run within the front-end application, with no server interaction.

OWASP Top 10 2013 – A4 – Insecure Direct Object References

> Hello, I’m user number fiftysev…. Fiftyeight.

Insecure Direct Object References are types of authorization issues, where a user can access information (objects) which they are not supposed to.

For example, imagine a bank application where you can view your personal info via:

Now, what does “57” refer to? Probably some kind of reference to your user account. A… Direct… Reference… To your user account.

So the application probably runs a database query like:

SELECT * from profiles where userid = ?

So what happens if you swap 57 to something else? 58? Or perhaps 56 because, you reason, it is probably guaranteed to exist a user with the previous ID if it’s an incrementing counter.

If the application allows you to view profiles of other users (perhaps including their bank details and balances), the application has an issue with A4, as it exposes a direct reference to an object, and does not properly check if whoever queries it is authorised to get access to the data.

What to look out for

Again, this is a set of authorisation-problems. Exposing references and identifiers is never a good thing to do, but it’s not a vulnerability in itself as long as proper access control is in place.

Now, you could go through the following mental checklist in order to check for A4:

A. Does this page always look the same, for all people and under all circumstances?
If not, chances are the application presents different pages depending on some user input.

B. How are the unique/dynamic pages identified?
Look at the HTTP request. Are you sending some kind of token or identifier to indicate what page you want? Is it tied to the session/login?
Make sure to look at:
– GET-parameters, e.g. “?id=57&section=all”
– POST-parameters (request body)
– Cookies (delete one of them at a time, and see if the page changes)
– Common headers (do you get the mobile site if you pretend to be on iOS?)
– Other headers (custom headers?)

C. What is the scope of this identifier?
Let’s say you find “?id=57”. What is the scope? For user profiles… Probably site-wide. An id represents a user globally throughout the application.

Though what if you see “transactions.php?acc=2”? Perhaps that displays the transactions for account number two. Since there are probably thousands of bank accounts in the system, the scope of this identifier is probably bound to your account.

It’s terribly important to recognise that identifiers have a scope in which they are valid. Something that is not unique can only be successfully used in certain contexts, i.e. I could have 100 accounts, but you may only have 3.

From this, you can start to guess (and draft) how the application handles the identifier for the object. Perhaps something is used to set the context, which can be exploited. Perhaps you can change context somehow.

D. Is it possible to access other objects from this control? Should that be allowed?
Swap one reference for another. What happens in the following cases:
1. Use the reference given by the application. This is the default request and should work.
2. Swap to another reference “owned”/associated with your current user account. Most of the time this works as well. If it doesn’t, then we learn something about in which context/scope we can use it… Perhaps there is something else that needs to match up?
3. Refer to an object owned by another user account (might require you to have another account). This will work a lot of the time, you’d be surprised (or not, since it’s on the OWASP top 10 list…)
4. Refer to an object that does not exist. Most of the time this will yield a generic error, though verbose stack traces are also possible.

Some users should be able to view the data of others, keep that in mind when testing. Users should not be able to read private messages belonging to others, but perhaps administrators should be allowed to do so.


For existing applications, make sure to implement access restrictions for all objects. User A should only be able to fetch resources that user A is allowed to view, and so on. Identify all references within the application, implement the necessary checks, and make sure to test it.

For new applications, consider avoiding these references altogether. Do you need to pass the user ID, if the user is already logged in? Do you need to have global references, or could they be references to the specific objects belonging to the current user only? Would you be able to present dummy references and then re-map them to the internal references later on?

Final thoughts

Make sure to double-check that the user is permitted to access whatever they’re trying to access. If not, it might be possible to access other users data by directly modifying the exposed references.

OWASP Top 10 2013 – A9 – Using Components with Known Vulnerabilities

> I didn’t even know we had this old thing!

You know, keeping things up to date is something you pretty much have to do, but the web doesn’t really make it easy. There’s a plethora of things to remember to patch: the proxies, the web server, the web application, any dependencies, and even the front-end libraries themselves! How often do you update your version of jQuery?

There are two distinctly different types of using vulnerable components:
1. Using something that is vulnerable
2. Using something that is end of life

Deceased software

While something that is “end of life” doesn’t mean that it actually is vulnerable – it usually does – though you’ll be out in the cold in case something happens. Some kid discovers the next big vulnerability against Framework Buzzword, and you have no patch coming.

End of life simply means that the company, vendor, or developer who makes the software will no longer maintain it with security updates.

A note on open source projects
Larger projects will most likely keep an up-to-date list with whatever versions and branches they’re supporting, smaller ones might not. Projects on for example GitHub might not have an active community, a low level of support, and no guarantee when it comes to maintenance. For these types of projects, declaring the end of life is hard. In the end, you will have to accept responsibility for applying patches yourself or having a contingency plan in case something happens.

Danger ahead – vulnerable software in use

Though, obviously, software doesn’t have to be end of life to be vulnerable. Sometimes running an out of date version can be dangerous, depending on the associated vulnerabilities.

So what does that mean? Well, simply put, the community keeps track of and share knowledge on software vulnerabilities. Sometimes the specifics are disclosed (perhaps together with a demo), meaning that anyone with some technical know-how could go ahead and exploit anything running that software. Though sometimes only the fact that there is *something* wrong is disclosed.

How to disclose vulnerabilities is a completely different topic.

So what, no one knows if we’re running this and this version!

Wrong. The internet knows.

There are huge searchable databases that can be used to find services and applications running this and this version of that and that software. You could even use Google (with some limitations)!

Okay. Fair enough. But who would attack us?

Probably someone with nothing better to do, depending on the vulnerability. As time goes on, the likelihood of someone building a utility to automatically exploit the vulnerability increases. And when there is a tool for it, anyone (even a twelve-year-old) could use it – no skill required.

> Damn script kiddies.

So to summarise, the final thoughts:
A. Update your software, dependencies, components, whatever
B. Plan to migrate or upgrade from soon-to-be abandoned software