Web Security Negligence and the JetButt Vulnerability
A few weeks ago my internet service provider decided to take a vacation for the day; left me up a creek without a paddle (Who? take a wild guess). I had a lot of work to complete and decided to just go buy a 4g hotspot (Verizon Ellipsis jetpack - latest firmware as of this post). I liked the idea of having a backup for future fails and it’s for the most part quick and easy to setup.
What should have been a somewhat productive day of work turned into an investigation of the device and its firmware. It didn’t take long to find some pretty hilarious problems. I decided to report the vulnerabilities to Verizon and left a very respectful time period of silence (1 month) before writing this post. Anyway, the takeaways from this post are as follows:
- Javascript developers should understand web security.
- Always audit a device before going to market.
There are a lot of companies and tools to help with both.[2]
The Web Application #
Notice how the application tells you the number of connected devices without being authenticated. We will revisit this later.
I knew right away there was going to be a lot of issues with the security of this product because it was built completely client-side. Now, it’s not hard to secure a client-side app but most client-side frameworks[1] don’t offer anything as far as best practice in this area. One important note is you also publicly document your server api which can save researchers and/or attackers a lot of time reverse engineering them (apis for client-side tend to be designed for use with javascript and not general consumption). Client-side javascript frameworks all pretty much make the assumption you know what you’re doing and most javascript devs I’m sure couldn’t explain XSRF (well, maybe most can but I know for a fact the devs that wrote this masterpiece can’t).
You may be saying:
“Dustin, all fault falls on the shoulders of the server logic and not the implementation of the client code. The backend folks should have enforced X or abstracted route Y.”
First, I completely agree with you but it’s a double edge sword. If the server generates a valid session ID it is both sides’ responsibility to respect and enforce this. My point is even if the security on the server-side logic was bulletproof, it can all fall apart if the client-side developers do not understand or enforce them. It’s also important to note that the client-side is part of the device in this case as it’s served from the device itself. It’s incharge of all state and becomes the complete interface outside of the physical buttons on the device. Additionally, most if not all of the validation should be shared equally between both sides.
The Fails #
So, remember above when I mentioned the connected device count shows outside a valid session? Take a look at this screenshot and try to make a few assumptions or point out things you would look into.
Anything interesting stick out to you? If you noticed the looping json request to general_monitor.cgi then you move on to the next round. Now, why someone thought it was important to show the connected users outside of authentication is one thing, but having all this information exposed from general_monitor.cgi outside of a session is another.
Now, this information alone is not very interesting but it’s a clear sign that if I keep looking into the API and web application i’m sure to find all kinds of fun stuff.
Remote reboot & auth bypass. #
With a clear indication that this application was poorly designed I decided to review the settings in detail. Luckily for me, they didn’t remove any of the console.log output so pretty much all of the params, requests and results were right in front of me.
It was pretty straightforward from here that I need to just replicate the same request with custom params to see what happened. I already knew the app had not XSRF protection because the ajax requests being sent had nothing extra added to the request. If my session was still valid it will obviously work: but if I kill my session and try, what will happen? I knew the web application was creating a session ID at login.
Note: let’s ignore that it’s not secure and all over http.. but anyway
So, that’s a good sign but lets just send a request anyway after killing my session and see what the server returns. I could go through all that work to rebuild their request but let’s just copy a route, move to incognito mode and see what happens. Well, like I suspected, they don’t validate the session id at all. The only thing they actually use the session ID for is replacing link HREF attributes with #
vs the actual path (No, i’m not lying - seriously). So, to bypass auth on the Verizon hotspot one just simply has to type in the full url to the settings page and you’re done.
WARNING: if you’re a person that cares about security this video could be highly disturbing.
From Small To Large #
Well, since it has no XSRF protection, doesn’t respect the session ID, and is riddled with XSS, the options are endless. You could have a victim click a link, inject some javascript for the post request and change the SIM settings and make the device worthless. You could have the device reboot and change the wifi SSID and password. Oh, and by default the wifi password is the ADMIN password. Changing the wifi password using something like this
$.ajax({
url: "http://my.jetpack/cgi-bin/settings_wifi.cgi",
type: "POST",
dataType:"json",
data: '{"Command":"SetWifiSetting","MaxConnectedDevice":8,"OnePassword":false,"PrivacySeparator":false,"SSID":"evilevil","WMM":true,"WiFiAuthentication":6,"WiFiChannel":0,"WiFiEncription":4,"WiFiMode":0,"WiFiPassword":"evilevil"}',
success: function(s) {console.log(s)},
error: function(a,b,c) {console.log(a,b,c)}
})
will allow you to completely change the Admin password (not that it even really matters).
[1]: A few frameworks have support and/or wrapper for common web security pitfalls. ie angularjs and others have community plugins like backbone. None of them seem to enforce it or enable it by default.
[2]: For advanced XSRF protection checkout http://threatbutt.com