Loading...
  OR  Zero-K Name:    Password:   

electric sheepsploit

28 posts, 1497 views
Post comment
Filter:    Player:  
Page of 2 (28 records)
sort

9 years ago
Some details about the nightwatch bug allowing lobby connection injection:

I think the infrastructure deserve some freshening. If you don't, keep reading anyway. I'm currently reading a lot of code because I want to understand what exactly all this ZK code is doing and how it interacts with lobby clients, lobby server and various bots. In particular, I'm looking at authentication.

Here are the tools I used:
- grep
- less
Sometimes I use better tools too. But that's when I want to find a needle in a haystack and not the opposite.
MSDN documentation is also required.

Often, I come across code that doesn't look right when reading code from ZK repository.
Here is an example:

https://github.com/ZeroK-RTS/Zero-K-Infrastructure/blob/master/NightWatch/AuthService.cs#L481

Got it? It doesn't look right. This thing is concatenating strings together, but its not checking whether the strings actually contain spaces (or other suspicious chars) and it is not escaping them. If you don't want to dig TasClient (instance client) code... I can assure you that SendRaw does what its name suggest: it will send anything, raw.

Now, if you have a playful mind... you may wonder what would happen if you could slip spaces in either login or hashedPassword. Even nastier... can you imagine what you could do if you could slip newlines into that command?

Imagine, if you could manage to reach line 481 with the following values:

-login is a multiline string:
"bla bla
SAYEX sy is dreaming of electric sheep
PING"

-hashedPassword: anything will do... lets say we use "BAAAA"

This would get sent over the lobby channel as:

1234 TESTLOGIN bla bla
SAYEX sy is dreaming of electric sheep
PING BAAAA

Brillant!

(maybe at this point you think it would be wise to send a valid login/pass pair instead of bla/bla... but don't do it, it would probably create a mess in zk's db)

But can we manage to slip this multiline string into login?

The number #1 security advice is: don't trust user inputs. So normally, this should not be possible... it would be non-sense to allow a user to pick a multiline username anyway. But remember about the needlestack and the haystack. When you see suspicious code like that, its not always obvious that it may be exploitable or how to control the values of the variables... but in this case, the variables are named login and hashedPassword.

So now, we need to find what is calling this function.
grep can do wonders. Sure, it sucks when compared to tools that have some knowledge of the structure of the code you are analyzing. But its a needlestack, we need gloves more than a radar.

https://github.com/ZeroK-RTS/Zero-K-Infrastructure/blob/master/Zero-K.info/AppCode/AuthServiceClient.cs#L54
AuthServiceClient.VerifyAccountHashed() is calling NightWatch.Auth.VerifyAccount().
Before that, it makes a few checks. No problem with my multiline login... it has multiple lines, so it is not empty :)
Also, there is no account in database with such a stupid login name, so of course, VerifyAccount() gets called.

Lets move up... what do we need to do to reach AuthServiceClient.VerifyAccountHashed() ?

https://github.com/ZeroK-RTS/Zero-K-Infrastructure/blob/master/Zero-K.info/Global.asax.cs#L120
MvcApplication_PostAuthenticateRequest()

Ok... if you want the gory details regarding when exactly this handler gets called, have fun with the MSDN documentation.
All I cared is that it gets called at some point. And that it calls AuthServiceClient.VerifyAccountHashed() without any extra check.

Read this line, then read it again:

if (acc == null) if (Request[GlobalConst.LoginCookieName] != null) acc = AuthServiceClient.VerifyAccountHashed(Request[GlobalConst.LoginCookieName], Request[GlobalConst.PasswordHashCookieName]);

I spent some time wondering how to fit a multiline string into a cookie. I have not found a way to do it, but maybe there is.
You may think its a dead end then? You read that code line many times, right? You have seen how the code gets 2 cookies whose names are in GlobalConst.LoginCookieName and GlobalConst.PasswordHashCookieName. You agree with that?

Actually... that's what is expected by the code author(s). (Note: all this authentication system is horrible, but that was the subject of another issue so I won't cover it).

The unintended benefits of using a tool such as grep rather than a high-level tool is that sometimes your regex matches unexpected stuff. (For that reason, I suggest that grep should be renamed to serendipity.). I noticed something odd while looking for code accessing cookies in ZK's repository. Like every piece of code in ZK, there is no consistency in the methods... there is code duplication and just random stuff. But in the end, I wondered about the Request[something] notation. I mean... its probably not a dumb array of only cookie values with such a generic name. And indeed:

http://msdn.microsoft.com/en-us/library/System.Web.HttpRequest%28v=vs.110%29.aspx

"To access data from the QueryString, Form, Cookies, or ServerVariables collections, you can write Request["key"], as shown in the example for the QueryString property."

You must be kidding right? That is a really stupid way to design an API (hi microsoft). I can not think of any reason why someone would design such a stupid function and I can not think of any reason why it is used here... but maybe that opens new doors:
- QueryString... why not? maybe later
- Cookies... I know that... how do you think I arrived here?
- ServerVariables... I do not control that! well, maybe, but that is beyond the point... :)
- Form... ewwww... a form, like one of those that can include textarea fields... and so, are multiline?

Game over.
I'm not posting more details or the electric sheepsploit code. But I gave working proof... ;)

My rant about how fucked up the infra is will come later...
+9 / -0


9 years ago
Fixed now. Testing access is a nonstandard command, it uses Raw send over socket, unlike all other usage which should be protected from similar exploits.
+0 / -0
The moment I learned ZKL stores (and sends) plaintext passwords, I immediately realized that I should basically be prepared to lose the account at any time. Granted, while this doesn't necessarily mean I (or we) could "lose" ZK at any moment to a malicious user, it appears that's not too far-fetched.

Pretty scary thought, given the effort people like Anteep put into hurting this community...
+0 / -0
9 years ago
quote:
ZKL stores (and sends) plaintext passwords

Why does it send them in plaintext? I only have a very primitive understanding of this but that seems very exploitable. Could the login data stored in that xml file be seen by anyone but the user without malware having access to the computer?
+0 / -0

9 years ago
"I spent some time wondering how to fit a multiline string into a cookie."

[humour] I tried to make sense of this sentence but couldn't...
+0 / -0
quote:
Why does it send them in plaintext? I only have a very primitive understanding of this but that seems very exploitable. Could the login data stored in that xml file be seen by anyone but the user without malware having access to the computer?

ZK accounts are tied to Uberserver accounts. Uberserver protocol is plaintext in its entirety. Though passwords are still sent hashed ... with unsalted md5.

It's not just ZK that should make your guts twitch in abject terror.
+2 / -0
@[v]sheep, nice code digging, i admire your effort.

it would be nice if security gets some focus in the future. as complex as this is, its gona be hard though...
+2 / -0
9 years ago
I thought the first rule of Uberserver account security was "You do not talk about Uberserver account security?"
+5 / -0

9 years ago
quote:
this doesn't necessarily mean I (or we) could "lose" ZK at any moment to a malicious user

This definitely used to the case.
+0 / -0

9 years ago
CHrankConnetable I was trying to explain what is the process of vulnerability discovery... from a (nice) attacker point of view. And also to make it clear that I did not make a comprehensive security review. I fear it may be misunderstood as "you are just one fix away from a secure system and here I tell you what is broken".

Hopefully people will get curious about the system, follow the call stack, read some code and think... and will then be more open about discussing a radical alternative.
+1 / -0


9 years ago
ZK does not send or store passwords in plaintext. Uberserver does that (stores plaintext in database).
+0 / -0

9 years ago
ZKL store passwords in plaintext.
ZK infra store passwords in md5 form. This is the format the server expects you to provide them. So for all security matters, this should be regarded as plaintext, as it is reusable for impersonation (and crackable too).
+1 / -0

9 years ago
For all intents and purposes, if playing ZK the "default" way means I can read my password in the (ZKL) settings, then "ZK" stores passwords in plaintext.

The differentiation between uberserver, spring and the ZK mod is completely whatever for people playing the game.
+0 / -0


9 years ago
All I know is that uberserver has passwords unhashed in DB in true plaintext. ZK site has them hashed in DB.
Zero-K lobby has them in config file in plaintext. You can add encryption but thats really minimum security, because anyone who knows what that config file is can check source code to learn how to decrypt it..
+0 / -0

9 years ago
Right, and the solution is not to encrypt and decrypt the password in ZKL. The solution is to make uberserver use appropriate security.

As long as uberserver doesn't do that it's impossible to provide anything close to safe accounts.
+1 / -0

9 years ago
BRrank[V]sheep i do not doubt for one second that you're well intentoned and I also greet your effort of pointing out things. Unfortunately, all this is well beyond my knowledge.
+0 / -0

9 years ago
quote:
All I know is that uberserver has passwords unhashed in DB in true plaintext. ZK site has them hashed in DB.

No.
This is pure nonsense, because you never send the "unhashed password" to uberserver, and they were not vicious enough to reverse the md5 just to store it in unhashed form. Check lobby protocol specs.

ZK can do that, because you send the password to ZK website when authenticating. Lobby server can not.

I just checked (again) uberserver code to make sure.
It is doing exactly what ZK is doing:
- ask for login
- ask for secret
- compare stored login+secret with provided login+secret
If it matches, authentication succeeds.
If an attacker gets access to the db, he has login+secret for everyone and can use it to impersonate everyone. Because lobbyserver only asks for login+secret... not the original password that is used to generate the secret.
Only difference is that uberserver code has some checks on provided secret to make sure it has been base64(md5()) encoded.

The rest is masturbation or disinformation.

Regarding the fact that ZKL stores a secret, this is a non-issue. It is doing what people are asking: store a secret (password) and provide it to lobbyserver so they don't have to for each login. Do you think your email client, instant messenger and web browser have found a magically safe place to store secrets? :)

The solution to this problem is hardware tokens... such as fido/u2f. Thats an overkill requirement to put on players, though it could optional.
+0 / -0


9 years ago
Abma told me passwords are stored in plaintext in uberserver ... Maybe he meant as hashed plaintexts.
+0 / -0
[AG]abma
@licho:

passwords in uberserver db are stored as they are sent from clients which is basicly plaintext:

clients send the password md5 hashed and then converted to base64.

there are a lot of online md5 online password decryptors, so you could even recover the originial password easily. but if you have the base64 string from the uberserver db, you can easily use it to login as this is what is used as password.


basicly what we use/have in lobby protocol is plaintext, md5 doesn't protect the original password nor does the protocol prevent sth. like a "replay attack" (=send the sniffed data again)

if zero-k is using the base64/md5 password to store it in db its equivalent plaintext, too.

(very likely i wrote a short version of this)
+0 / -0
quote:
Do you think your email client, instant messenger and web browser have found a magically safe place to store secrets

Firefox password storage with a strong master password? You call it magic, I call it secure.

(Yadda yadda rootkit, keylogger, software vulnerabilities... That's not what this is about.)
+0 / -0
Page of 2 (28 records)