Yahoo login security

By Paladion

August 20, 2005

Yahoo has added code obfuscation and filter-evasion tactics to their login scheme. There's constant innovation on that page!

Regulars will recall that we have been all praise for Yahoo's salted MD5 login scheme. So imagine the surprise when Karmendra pointed out that the login page does not contain the javascript for a salted hash login anymore!

We investigated the "new" scheme today.

A closer look at the "View Source" showed that the older javascript for salted MD5 was definitely not there. But, all the old hidden variables were still there - challenge, hash etc. These were the variables that yahoo used for constructing the salted hash.

I then logged in to Yahoo and used LiveHTTPHeader, a firefox extension to examine the headers. LiveHTTPHeader is simple and saves you the time of configuring a proxy to intercept and examine traffic. With a single click, you get access to all the HTTP headers from the convenience of your browser.

Well, the password did *not* go in plain-text. And it seemed very similar to the hashed passwords of Yahoo's yesterday.

Clearly, Yahoo was still computing a hash, but we weren't "getting it"!

Scrolling dejectedly through the html source, I came across this suspicious line:

if (window.yzq_a == null) document.write("<scr" + "ipt> type=text/javascript src=></scr" + "ipt>");

Oh oh! Yahoo seems to be dynamically embedding a javascript into the html. That doesn't appear in the static "View Source". Further, notice that "<scr" + "ipt>" ? That's a common practice to beat filters that look for <script> tags. Proxies that block scripts from getting downloaded can be evaded by splitting the tag, as Yahoo did.

The fun begins now.

It was the work of a few seconds to download the javascript the URL was pointing to. And then bc_1.7.0.js turned out to be an inscrutable piece! Here's a snippet from that.

function yzq4(r){var w=window;var d=w.yzq1;if(d==null)return;if(typeof(d)==yzq5){var u="";if(d.s!=null)u+=d.s;if(d.p!=null)u+=d.p; if(u.length>yzq6){w.yzq1=null;return;}d.s=d.p=null;var z="";var s=0;var o=Math.random();var b;for(b in d){if(d[b]!=null){if(u.length+z.length+d[b].length<=yzq6)z+=d[b];else {if(u.length+d[b].length>yzq6){}else {s++;yzq2(u+z+"&Q="+s+"&O="+o);z=d[b];}}}}if(s)s++; yzq2(u+z+"&Q="+s+"&O="+o);w.yzq1=null;}} function yzq9(yzqa, yzqb, yzqc){if (yzqc){var o=yzqc.toString();var m=yzqa;var a=o.match(new RegExp("\(([^\)]*)\)"));a=(a[1].length >0?a[1]:"e");m=m.replace(new RegExp("\([^\)]*\)","g") , "("+a+")");if(o.indexOf(m)<0){var b=o.indexOf("{");if (b>0)o=o.substring(b,o.length);else return yzqc;o=o.replace(new RegExp("([^a-zA-Z0-9$_])this([^a-zA-Z0-9$_])","g"),"$1yzq_this$2");var s=m+";"+"var rv = f( "+a+",this);";var n="{"+"var a0 = '"+a+"';"+"var ofb = '"+escape(o)+"' ;"+"var f = new Function( a0, 'yzq_this', unescape(ofb));"+s+"return rv;"+"}";return new Function(a, n);}else return yzqc;}return yzqb;}

Looking at that code, it's difficult to make out what Yahoo is doing. The developers have changed all variable and function names, removed line spacing, etc. It has been made difficult to reverse engineer. That's Code Obfuscation in action. [ahem...for a good article on Obfuscation, check out Sonali's tutorial on Code obfuscation techniques in Palisade.

There are several obfuscated functions in Yahoo's login page, and some of them most likely are part of the hashing algorithm. Considering that the old variables are there intact, our best guess is the algorithm has not really changed. Yahoo has just added a layer of obfuscation to their login process.

Out of curiosity, Karmendra then checked what happens on failed login attempts. It turns out that Yahoo switches from Standard mode to the secure SSL login mode after 2 failed attempts.

And the SSL login mode of Yahoo does not use a salted hash scheme: when the connection is established over SSL, Yahoo relies on SSL encryption and foregoes the salted hash.

Yahoo has thus raised the bar for attacks against the system by obfuscating their code. They have also added techniques to evade filters that block javascripts.

Tags: Uncategorized