Blog: Vulnerability Advisory
You may have read my previous post where I had a look at the SLOK padlock and found it had an interesting BLE interface which I couldn’t find a vulnerability for and a physical designed that took seconds to work around.
Anyway, I alluded to some weirdness from the API and an actual vulnerability in it that could cause private information to be leaked. Now we had a wee bit of a delay in this post because we’ve been trying to disclose to Slok.
Note the word trying. Let me just highlight the appropriate disclosure bingo entry:
That’s right, Radio Silence.
So, it’s time for that joyful thing: full disclosure.
The API and its weirdness
There are many ways of writing an API nowadays, from a simple REST API to some really massive overblown ones with hundreds of different calls. Slok does it differently, it’s, well, unique.
Let’s have a wee peek at a Slok API call:
POST /index.php HTTP/1.1 Content-Length: 68 Content-Type: application/x-www-form-urlencoded Host: www.you-lock.com Connection: close User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4) vkey=1ea446cc945706a1447ba8340e9b50c0&user_id=XXXX&code=270&keyword=
That’s a whole call, post authentication. Those of you who are used to looking at APIs are now mouthing the letters “W”, “T” and “F”. So, what’s weird about this:
- There’s no authorisation header to indicate that the user’s authenticated
- There’s nothing in the URL to tell it what to do
Well, there is, and this is where it gets strange.
Everything is in the POST parameter, let me add some highlighting (I’ve censored my user ID, in case someone feels like messing around):
The parameter, code, highlighted in yellow is the actual API method. It’s defined by a three digit code, which maps to a method, in this case 270 which is the friend search method. There’s a load of these and you need to reverse the app to work out what they do, fortunately the app isn’t obfuscated and all these can be found in the class com.supude.slok.network.NetInterface
Why they couldn’t have just used a REST style interface and had a sensible path in the URL I don’t know.
Authentication and authorisation
So how does authentication work? The API does implement some authentication and it’s not vulnerable to IDOR, but how? If you look up, you’ll see a parameter passed with every request, called vkey, this is a sample:
This is an authentication, integrity and anti-CSRF token rolled into one. Some of you may have noticed that it consists of 32 hexadecimal digits, i.e. 16 bytes, which is exactly the right length for an MD5 hash.
A bit of digging in the source revealed how this parameter is created, in the NetInterface.getPostVerify method.
The above method takes the parameters as a map of Strings, sorts them in order and adds them to a temporary string as if they were parameters to a POST request.
It then concatenates the configuration value AccessToken.USER_ID_KEY and MD5s the whole lot. Further digging reveals that USER_ID_KEY is the user’s password. This was so strange I had to use a simple Frida script to dump the value of this this method, so I knew what it was:
Running this whilst performing any API call to the server dumped the goods:
So we can see that the MD5 is called twice:
- Once to hash the password (“956939”)
- Once to hash the sorted parameters prepended by the password hash
In terms of pseudocode it would be something like:
MD5(sort(parameters) + MD5(password))
So, we have this insanely complex authorisation token which contains a hash of the user’s password and the parameters acting as a dual authentication and integrity step. This has problems:
- The password is stored using the MD5 algorithms, which is quick to calculate, so easy to crack if the database is compromised
- Accounts with the same password could easily be compromised
- The token can’t be timed out
- It’s replayable
- You could brute force the password if you intercept it
One thing that makes a lot of the above attacks important, can be shown in one image:
Yes, in this world of free and easy TLS certificates, the app sends everything in the clear, allowing anybody on the wireless network to just sniff the hash, mitm-tastic.
And, we’ve still not got to the vulnerability.
As I mentioned earlier, there’s no IDOR and in my previous blog posted that once a device has been registered, you can’t take ownership of it.
But, there was one call, Net_isearch_friend (call 270) which had an interesting side effect… This call takes a parameter, keyword, which acts as a search string. But it’s rather friendly about what it searches for, let’s do a simple search for the keyword mailinator, a popular throwaway mailbox domain:
And look at what it returns:
Oh look, it returns a list of users, including their email address and phone number. Interesting and full of GDPR-type fail.
Can we improve this? Trying a search for a letter in the app failed as the app had a minimum search length. But, we know how the API requests are formed, so why don’t we just request this manually:
And what does this return? In short, a record for every account:
That’s only an extract, and, yes there were a lot of valid phone numbers and email addresses in there. We didn’t find any password hashes.
Whilst finishing this up an gathering information we also noticed that there may be a few more vulnerabilities in their backend as we could easily get an error message that implies SQL injection, as shown in the below screenshot. We haven’t looked into this further so as to keep on the right side of the Computer Misuse Act.
Taking all things about the Slok lock in consideration, I was mostly happy with the Slok lock’s BLE implementation, although it wasn’t perfect it was not possible to trivially be able to unlock; although there were a few things they could improve.
Its physical security is, quite frankly, laughable: it could be opened with a cheap screwdriver set and the motor spiked or the device taken apart. The shackle could be cut through with a pair of dirt-cheap bolt cutters.
On the API side, there is a lot of weirdness in the design with makes the tester’s vulnerability sense go off; but it does at least check for authorisation. That said you could extract enough information from the database to gather email address and phone numbers from its users. There were indications that secure coding hadn’t been applied and that there could be further vulnerabilities.
The company itself did not respond to several message whilst trying to disclose these vulnerabilities; this does not instil confidence.
So, in essence, I would not use this device to protect anything; I would not trust the company to protect information I provided to it (and this includes GPS co-ordinates) and I’m not particularly enamoured of its software design processes.