From an authorized Penetration Tester’s perspective, wanted to talk a little bit about cross site scripting (XSS) cross site request forgery (XSRF or CSRF) the differences between the two and show some examples of
these server-side vulnerabilities in action. Let’s start with cross
site scripting and weave our way into cross site request forgery
later on...
Cross site scripting is an
attack and it’s also commonly referenced as a vulnerability (as is
XSRF) so let’s take a moment to clarify. When a web application is
susceptible to XSS it’s said that the website (web application) has
a XSS vulnerability. When an attacker injects a malicious script into
the vulnerable website; that action is the XSS attack.
In order for XSS to exist there has
to first be a vulnerability in the web server or web application that
allows malicious users (attackers) to upload/inject code. The
vulnerability itself is precipitated by a serious underlying issue:
lack of input validation/sanitation. It's the failure of the web
application to validate user supplied input prior to rendering it for
the end-user that causes the vulnerability in the first place.
One point that should be made clear
is that while it's the web application that exhibits the XSS
vulnerability, it’s the end-user of that web application that is
the “target” of the attack i.e. the recipient of the malicious
script mentioned above is the end-user. One last quick note before
showing some examples; two things are being exploited in a successful
XSS attack: one or more vulnerabilities on the website that exposes
the XSS attack vector, and the trust the end-user/client has in that
website to allow scripts to execute.
This is my browser, it’s also
called a user-agent and I, as a consumer of what my browser renders,
am referred to as the end-user.
I am on a fictional banking website
which is being served from a VM on my internal testing network. This
banking website is host to a vulnerable web application which should
prove perfect for showing XSS examples. And now is the perfect time
to mention that no packets are ever sent to a target without explicit
authorization from the owners and those responsible for the target asset/network. During the reconnaissance phase of a web application
penetration testing engagement, one of the first things I like to do
is check the 404 handling, how graceful is it, and how exactly how
does the application or web server handle notifying a user when a
requested resource is not available on the server... will the user be
redirected to the home page, will the requested resource be echoed
back to the user in a message, will the server return a 503 or will
something else happen?
In the case of bankwebsite.com, the
requested resource is echoed back to the user. The resource "blahblah" does not exist on the server and the bank website lets us know that
by displaying a message to that effect. This can be tested for and
reproduced by altering the end of the URL to a value that you
are confident does not exist – remember we are simply requesting a
web page from the server.
To recap, I put in some pseudo random
text at the end of the URL, pressed enter, and the web site echoed it
back to me when the page rendered... let’s find out if the input is
sanitized before being rendered as output. This can be done by
requesting something like the infamous:
<script>alert("xss");</script>
The JavaScript pop-up lets us know
that the webserver is vulnerable to XSS. In order to exploit this,
one could E-mail the target victim the URL shown above in the
screenshot for example, and if:
The victim was on my internal
testing network
Clicked on the link
Was allowing scripts to execute
in her browser
And her browser chose to
execute this specific script (keep in mind browsers have built-in
protections for a lot of this stuff)
Then she would be presented with a
javascript pop-up with the letters x-s-s.
A few things have to line-up for
this attack to work, the pop-up box is just a quick way to identify
the cross site scripting vulnerability; if these efforts get the XSS
pop-up to execute then additional efforts can get malicious code to
execute as well.
Using just a browser to find and
validate a reflected XSS vulnerability did not require anything
particularly noteworthy, a simple typo in the URL would cause similar
results – unfiltered user data submitted via a GET request in the
URL being echoed back to the user's browser. There is however a lot
more to XSS, this is just the tip of the iceberg.
XSRF is more challenging for me to
explain succinctly, which is motivation to write this. When a web
application allows a browser to initiate a sensitive transaction
without validating the end-user actually wanted to initiate said
transaction, the web application is considered to be vulnerable to
XSRF. Sticking with the bank theme, I will log back into my
fictitious account and examine the wire transfer section to learn
what options are available and how to interact with the form to
transfer funds.
During the login process a session cookie was set on my machine which grants me authenticated access to
the website, this cookie will be sent with every HTTPS request my
browser makes to the website, whether I click a link or my browser is
otherwise convinced into sending a request to the website.
In viewing
the wire transfer page I first observe what it looks like in a browser,
then view the source code, then view the underlying HTTP traffic in
an interception proxy; all the time looking for predictable
parameters.
The wire transfer form consists of
several fields that are required to be populated with data such as
the dollar amount of the transfer, recipient account, routing and
account information…. But no additional password prompt or hidden
random token to further authenticate the transaction. Therein lies
the issue, predictable form parameters coupled with the lack of
transaction validation, this is how it works:
Next the attacker must wait
until the target user logs into his online banking account and then
prompt the user to visit the crafted webpage above
The crafted webpage uses
javascript to submit a wire transfer request of $130,487 from the
target/victim account to an account of the attackers choosing via a
hard-coded post request
The request is coming from the
newly opened tab in the victims browser, the banking
site treats the request as a legitimate wire transfer request submitted willfully by
the user
The request however was made
surreptitiously unbeknownst to the victim
At this point the victim has
lost $130,487 which is evident once the balance page is refreshed
This example used a specially
crafted webpage that the victim had to be coaxed into browsing to.
Other attack platforms include public message boards where
user-provided image links are used to launch XSRF attacks on
unsuspecting visitors of the site. Once again however, many variables
have to be just right for this attack to work but javascript being
enabled is not one which is a big difference when contrasted with
XSS. One of the biggest distinctions between XSS and CSRF is that when dealing with XSS, malicious code is executed in the browser and in
the case of CSRF, code is executed on the server. That's all for now, still lots of ground to cover... next time in less than 1000 words hopefully.
* This could be any customer of the
bank enrolled in online banking