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 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)
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:
- A malicious authorized banking user*, examines the wire transfer form just as above, and crafts a single webpage that will serve as the attack platform. Written as such:
- 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 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 could be any customer of the bank enrolled in online banking