Aside from vulnerabilities such as HeartBleed, CRIME, etc. usual attacks over SSL take advantage of:
- Rogue certificates: that’s when an attacker hacks into a certificate authority, plays in some way the CA role inside a network, or takes advantage of an procedural error, to issue her/him a certificate that looks just like the real certificate of an entity but it is fake. In the past few years we have plenty of these examples.
- SSLStrip techniques: it consists basically in the interception of one initial unsecure connection and redirect from there all of the subsequent requests over HTTP and not HTTPS.
For the first problem, HPKP is one of the proposed solutions. It forces the browser to remember all the legitimate certificates served by the browser, because the server sends them over an HTTP header. For the second, HSTS is proposed. It consists of a header sent to make the browser remember that it always has to connect over TLS/SSL, so there is not any unsecure connection made after this header is sent.
We have analyzed how browsers implement these (relatively) new features and what we found (between some other minor mistakes) is:
As we explained when PinPatrol was delivered, Firefox uses a TXT file with a limit of 1024 entries to remember HSTS and HPKP domains. It seems that they though it was unlikely that an user would store more than that but, anyhow, they implemented a concept of “score” for each domain too.
|Firefox source code coment about 1024 limit|
The score indicates how often the user visits that domain on different days. Score 0 means that the header is expired or it is the first day he has visited the site. Score goes to 1 next day if he visits it again. It would go to 2 next different day (not necessarily to be the day after) he visits that site. In a nutshell, the more often (in different days) the user visit the site the higher the score. In case of having to remove one of this 1024 entries to make space (free up a slot), the one with the lower score is removed.
|Simple script to send headers from our site cloudpinning.com|
What happens if a legitimate domain has a higher score and is less likely to be removed? To get that, we need to make this attack again in a different day, so our junk entries get a score of 1, and the legitimate ones with 0 score or 1 score, will probably go away. And so on.
|Junk entries with Score = 0 have removed legitimate domains|
If we do not want to wait a whole day, we may use a known technique by Jose Selvi called Delorean, speeding up the time in some Linux and Mac clients. Combined, we may likely evict HSTS and HPKP entries in Firefox for important domains in minutes.
|Using Delorian to speed up the process, if you want to|
Even if this does not work and we are not able to evict a domain from the table (evict a domain from that 1024 is equal to disable HSTS and HPKP for it and allows the Man in The middle attack), Firefox, because of this slot-based mechanism, will end up with just one single slot (the one that remains with score 0) to store HSTS entries, which will be constantly replaced by new domains with score 0 as well which, eventually, is like making HSTS useless.
|If we get to fill up the 1024 entries with a score higher than 0, there will be just one slot left|
|Lots and lots and lots of pins sent to Chrome|
Basically, the function or API that manages HSTS in Windows is located in the WININET.DLL library, and it is called HttpIsHostHstsEnabled, which seems not to have any official documentation. We understand that knowing the system in depth would require extensive reverse engineering and forensic work, which is beyond the scope of this report. In recent versions of Internet Explorer (and even Edge), Microsoft uses a type of proprietary database called Extensible Storage Engine (ESE) to store HSTS data among many others. The base file with the bulk of information is usually hosted in WebCacheV01.dat file under the user profile, in WebCache folder.
|With lack of documentation, this is all you can “know” from how IE/Edge store their HSTS information|
This is complex since a deeper research is needed. HSTS does not seem to work properly in this browser. We have discovered the tables where this information is stored, but it only seems to work with popular domains. Incredibly, it seems that it does not remember HSTS for not so popular domains. And furthermore, even removing the cache (not the HSTS storage system) seems to not affect this entry list. We have reversed some of the APIs that should be involked to store this information they are neved used. As a PoC, we called 131 times our https://www.cloudpinning.com site, and after restarting browser, and even computer, not a single change was made to HSTS permanent tables.
|Some requests do not seem to have any impact in Internet Explorer|
If you want to have a look and play around with this concept, we created this webpage (cloudpinning.com) and feel free to use it.