Jump to content


* * * * * 1 votes

Various Findings Regarding Dragon Nest Sea's Networking [Now With 200% More Flawed Login Credential Encryption]


  • Please log in to reply
13 replies to this topic

#1 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 18 May 2017 - 02:09 AM

Out of curiosity the other day I decided to use Wireshark and capture some DN (SEA) packets.

Section 1. Foreword

Disclaimer #1: This is in no way a violation of the Game Abuse Policy. I am not hacking nor cracking, nor am I encouraging these activities. I was simply curious as to how the DN client handled networking, as this information can be used to better understand various in-game phenomena and such, and help us understand how private / secure communications are between client and server.

Disclaimer #2: I filtered out all TCP packets that contain no data. Thus, when I say, for instance, "I received no TCP packets", it means that I received no TCP packets with data in them.

Disclaimer #3: The game server IPs will most likely be different depending on your character's server. I am from HW/SW, so keep that in mind.

Disclaimer #4: I use the term "packet header" and "packet identifier code" almost interchangeably. The latter refers strictly to the first three bytes of data in a packet, and the former referring to the same thing with or without including several bytes afterwards, however much constitutes the "packet header". I am not referring to the TCP packet header when I say "packet header".

I do not intend for there to be serious discussion nor replies to this thread. These are just some of my findings. I will update these list of findings should I find something interesting, however understand that studying packets from a client whose source code you don't even know isn't necessarily the most entertaining thing to do, for me at least. If I have the urge to do it, I will. Otherwise, I will not. Without further ado:

Section 2. The Findings

1) This game is dual TCP/UDP. In town, it is entirely TCP. Upon entering a combat / instanced zone (e.g. GTS), I start to receive UDP packets, however the TCP packets still pour in. I believe these TCP packets are mostly chat (general chat, world chat, world notices) packets. It's a bit of an interesting find as I am also using a dual TCP/UDP setup for Project S, with the TCP connection handling the chat mostly.

2) TCP packets are sent to and received from "203.116.155.18". UDP packets are sent to and received from "203.116.155.39". Thus, if you wish to do your own DN SEA packet capture using Wireshark, I suggest you use the filter (ip.host matches "203\.116\.155").

3) (A criticism) I shouted the exact same chat message multiple times, yet the packet data was exactly the same. Assuming DN implements TLS (preferably with AES-128/256), this signals the lack of an IV. In layman terms, an IV basically makes encrypting two identical packets produce different results. Without it, an attacker (packet sniffer, what have you) is able to know that you sent two identical packets to the server (even though he may not be able to read the message contents themselves), which compromises your chat privacy to a certain extent. (If you want a longer post about IVs (since I don't have all day to write about basic cryptography), this answer seems to explain it rather well. This is just from a quick Google search and glance-through, though).

4) (Also a[n even bigger] criticism) The TCP packets - the chat ones at least - seem to lack a MAC. Literally, I sent out chat messages going "5 4 3 2 1 0", with each message containing only one number, and the only thing that was different in each message packet was the second-to-last byte. This is very much an appropriate time for the Jean Luc Picard face palm meme. A MAC is something that you add to a packet in order for the receiver of the packet to verify that its contents have not been altered by an attacker. A MAC is generated in part by the actual packet contents, thus it should be different for non-identical packets. Since the only difference is the second-to-last byte, which we know must be the actual message content itself, what this tells us is that there is no MAC for chat packets, at least. What this basically means is that an attacker can alter your chat message to a certain extent and the server is unable to verify that it has been changed. Though, the attacker still does not necessarily know how to alter your message data to form a specific message that he wants as the communication is encrypted. What will realistically end up happening is that the attacker alters your message to complete gibberish.

5) The launcher employs dual HTTP/TCP. Both protocols are sent to and received from "203.116.185.132" and "203.116.185.141". Most of it is HTML. ".141" seems to handle version info / patch requests while ".132" handles everything else (e.g. launcher images), it seems.

6) DN SEA's login server is "203.116.155.17". I do see what seems to be a TLS handshake taking place. This handshake takes place after the opening cinematic is finished. Some time between logging in and loading to town, some packets are sent to and received from the TCP game server ("203.116.185.18"; see point #2).

7) You start to receive a flood of packets from "203.116.185.130" during the initial load to town. The protocol is TCP. Some HTTP requests are also sent to this IP for the event / cash shop banners.

8) (A huge criticism) There is some weird behavior regarding encryption, at least for chat packets. The encryption of two identical chat packets does not change upon logging out and logging in again. However, the chat message was encrypted differently compared to my initial test 2 days ago. Either their TLS implementation has some weird session resumption behavior (this is a bad implementation if this is the case; logging in again should generate a new pair of symmetric keys even if it is a session resumption, I'm not going to go into detail regarding how to properly implement TLS, however this answer seems to explain it quite well yet again.), or they randomize the symmetric key generation every few hours (3, 6, 12, 24, et cetera) or so. This seems to be pointing towards a botched TLS implementation. The cipher suite is unknown as of now.

9) (Another huge criticism) I am fairly sure that the header of the chat packets did not change compared to two days ago. I am 100% certain, however, that the actual message content bytes (the last 2 bytes) have been changed compared to two days ago, signalling that a new symmetric key has been used. To be clear, the message contents themselves were exactly the same. What I am deducing from this is that encryption isn't applied to the entire packet, but rather to just the message contents or everything except the packet header. This is simply unacceptable to me. An attacker knows exactly what type of packet you sent (in this case, a chat packet) just by looking at the packet header.

10) The packet identifier code seems to be the first three bytes. The format seems to be "X-0-0", where 'X' is the identifier code (e.g. chat, movement, et cetera). I have already mapped out several values of 'X' and the identifier it corresponds to. 'X' simply denotes the packet length. My guess is that it is a short (2 bytes) as one byte cannot represent packet lengths of (> 255). We know that there are packets of size 1400 and above. Thus, the format should be X-X-0, where (X-X) is the packet length short (2 bytes).

Section 3. Packet Identifier Code Map

Spoiler


Section 4. Conclusion

I've done quite a bit more regarding packet structure analysis, however I will need conduct a few more tests in the future in order to verify. The packets (the chat ones at least) are encrypted, as expected. The protocol is most likely / obviously TLS, though I have yet to verify. See point #8.

Needless to say, I take networking and security very seriously for Project S. Discoveries such as #3 and #4 made me rather disappointed in Eyedentity as my standard for player privacy is much higher than Eyedentity's, it seems. Having said that, Eyedentity has always disappointed me, just that now, they disappoint me even more since they are not meeting my standard for player privacy.

Edited by Riuga, Yesterday, 05:10 PM.


#2 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 18 May 2017 - 01:36 PM

Added point #5, #6, and #7.

Edited by Riuga, 18 May 2017 - 01:45 PM.


#3 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 18 May 2017 - 03:02 PM

Added point #8 and #9. Please be wary - this goes out to the entire DN population. The communications (your chat in particular) are not as private / secure as we once thought it was. I'll talk to PawHammer regarding notifying Eyedentity of this.

Edited by Riuga, 18 May 2017 - 04:40 PM.


#4 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 18 May 2017 - 04:55 PM

Added point #10.

#5 PawHammer

PawHammer

    Moderator

  • Moderator
  • 1020 posts
  • PawMimi
  • DN, Desmodeus
  • Dreamfarer

Posted 18 May 2017 - 07:14 PM

Hello there. I have been contacted by the person who started the thread and I've started reading and trying to comprehend the magnitude of what's being explained. Once I have a clearer idea, I will decide what to do with the information posted here.

We appreciate your concern towards the security and privacy of other players!

Have a nice day.

#6 spacem

spacem

    Member

  • Members
  • PipPip
  • 64 posts

Posted 18 May 2017 - 10:19 PM

I think most players dont care about in-game privacy so much. Load times and disconnections are more important issues that should be addressed.

Who is doing super secret private messages in-game anyway?

#7 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 18 May 2017 - 10:33 PM

It's not just about privacy. The lack of a MAC along with everything else also means that an attacker can alter your message to gibberish, thereby effectively screwing you over, say, if you're raiding and need to communicate some type of message urgently.

Regarding long load times, what I find is that a ton of 1400 byte TCP packets get sent from the ".130" address during the initial load to town. I am not exactly sure why these many max-size TCP packets are necessary. In addition to that, HTTP requests are sent during this time for every single cash shop banner and the event banner popup you get when you finally load in. What's basically happening is that you re-download a couple of rather high-resolution images every time you load in to town. It's rather inefficient honestly. They should send some type of hash of a concatenation of the current images to the client and let the client determine whether it needs new images or not. Alternatively, make it a conditional HTTP request.

Having said that, loading the graphics still takes longer than the amount of time it takes to receive all of the above packets and images. The only exception to this is if your connection is extremely slow (e.g. due to a submarine cable rupture). Those image downloads will screw you over in that case, which is why I'd still like them to make those HTTP GET requests conditional.

Spoiler

Edited by Riuga, 18 May 2017 - 11:19 PM.


#8 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 20 May 2017 - 02:07 PM

It's going to take a while for me to overhaul the original post. I will simply quote myself from another thread for now:

View PostRiuga, on 20 May 2017 - 05:47 AM, said:

Dear Diary,

Dragon Nest: possibly the only commercially-successful MMORPG that uses Caesar ciphers to encrypt your chat. Yes. I said it correctly. Caesar ciphers.

I have proven beyond a reasonable doubt that the chat isn't even encrypted with a symmetric cipher at this point. Neither block nor stream ciphers. What I do notice is how consecutive characters (e.g. "5 4 3 2 1 0") all maintain a fixed difference after encryption - the shift value of a Caesar cipher. Are you for real Eyedentity!

It will still be a while before I make the official, extremely extensive write-up for the "Networking Findings" thread. It will be mostly evidence and deduction, however, thus this post is effectively a very short summarize of what I'm going to write on that thread.

Please be very wary of your chat. Caesar ciphers are a joke. Your chat is effectively unencrypted for all I care. Anyone half-determined enough to crack the shift value will do so very quickly and without much effort.

View PostRiuga, on 20 May 2017 - 02:02 PM, said:

ROT-13 shifts by a fixed amount, here the shift value gets randomized upon logging in after x amount of hours. I have yet to test how frequently the shift value gets changed, for now I can only say that it is (<= 24) hours.

Ignore everything I said about symmetric keys and AES in the original post. It isn't even the case anymore. Replace every instance of "symmetric key" with "shift value" and "AES / symmetric cipher" with "Caesar cipher".

It seems as though the more research I do, the worse the whole security situation is becoming. I'll have to check the login packets at this point. I used to trust in Eyedentity's network security out of the sheer fact that few to none have ever gotten hacked without leaking their password somehow. This is no longer the case to say the least.

Edited by Riuga, 20 May 2017 - 02:14 PM.


#9 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 20 May 2017 - 05:15 PM

We're officially in situation critical at this point. Upon a successful login, 2 packets are sent to the server. The second one sent is way too short to contain our login credentials, thus the first packet has to be it. The problem is that the first packet's data isn't even encrypted differently upon successive logins - even when I restart the client.

If they also Caesar cipher the password, I just don't even at this point. I mean, there is some reason to believe that the packet is encrypted using AES as the encrypted portion can potentially be a multiple of the block size (16), but it would have to be running in ECB mode. Everyone should know what's wrong with ECB mode. Every other mode will not produce the same result for every round, even with the same input. Here we see consecutive logins producing the exact same result. I mean it could be a non-ECB mode, just that the usage would have to be fundamentally flawed by restarting the chaining / counter every login and not supplying a new, random IV per connection. Even if this were the case, it would fundamentally be no different from running in ECB mode.

I am not sure how many of you understand the magnitude of what this means for account security. I do not wish to say what exactly an attacker can do to easily get into your account, for it may encourage an account hacking spree. I will have to forward this urgently to PawHammer and ED. I have already forwarded this to PawHammer, however no one is in the CC office currently as it is a weekend.

My advice for now would be to completely avoid logging in using public WiFi and Internet cafes, if possible. If you must do so, please ensure that no one with malicious intent (i.e. to get into your account) is on the network with you.

I do not intend for any of you to panic. Please remain calm and refrain from sharing the same connection with those who have malicious intent. This doesn't really guarantee that your account will not get compromised, but it will lower the likelihood of that happening drastically. Understand that changing your password will not help defend against the security flaw that I have identified. It will only help in the event that you know that your account has already been compromised. Also understand that even if an attacker does get into your account, he or she does not necessarily know your login credentials (I will refrain from elaborating for reasons stated above). As such, you should not be paranoid about an attacker compromising your other (non-DN) accounts that happen to use the same login credentials.

If the moderators think that I should redact this post until it is fixed, I will do so immediately.

Edited by Riuga, 20 May 2017 - 11:39 PM.


#10 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 20 May 2017 - 11:57 PM

It only gets worse. I've analyzed two LoginCredentials packets, one from me and one from someone else kind enough to help me test, and the format goes "IDCode-Data-Filler-Data-Filler-Data-Filler-Data-Filler". I will need to do a few more tests before I can firmly say what the exact length of each segment is. Right now some of the lengths have an error margin of +- 1 byte. What I can say, however, is that the IDCode and Filler segments were exactly the same in both packets. There are three possibilities at this point:

1) This packet is encrypted using a Caesar cipher and everyone shares the same shift value.
2) This packet is encrypted using AES under ECB mode or what's fundamentally ECB mode (see the above post) and everyone shares the same key.
3) Only the Data segments were encrypted using AES under ECB mode (non-shared key) or a Caesar cipher (non-shared shift value), the IDCode segment is not encrypted at all, and the Filler segments are either encrypted with #1, #2, some other silly encryption scheme that is shared by all clients, or aren't encrypted at all.

All three possibilities sound bad, however the third one is the "least worse". The problem with #3 is that some of the data segments are not a multiple of the AES block size (16), thus I can only think of it being encrypted with ciphertext stealing, a Caesar cipher, or with what I described in the above post:

Quote

I mean it could be a non-ECB mode, just that the usage would have to be fundamentally flawed by restarting the chaining / counter every login and not supplying a new, random IV per connection.

There is always the possibility of nothing being encrypted, which I hope is not the case. I'll have to do another test in order to verify this, however I think this is most likely the case.

Edited by Riuga, 21 May 2017 - 12:12 AM.


#11 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 21 May 2017 - 01:29 AM

Having done another test, I can say that Data1 and Data2 are the username and password segments (they change depending on the credentials you input, and are the same regardless of your IP address), whilst Data3 and Data4 seem to be determined by your IP address and are the same regardless of the credentials you input.

To put it simply, since Data1 and Data2 are the username and password segments, and since they do not change even when you log in from different locations, we can be sure that they are not encrypted using a unique session key / shift value. In my above post, when I was talking about possibility of nothing being encrypted, I was implying that they would at least be stored as hashes and not plaintext. I had a reason to believe so, as regardless of username and password length, Data1 and Data2 maintain a fixed length. As much as I'd like to think that they are at least sending cryptographically-secure hashes of the credentials, what I find is that Data1 and Data2 are extremely similar (first half is identical, in fact) when comparing a set of very similar login credentials. When comparing a set of very different login credentials, however, Data1 and Data2 have nothing in common. All of the cryptographically secure hashing functions that I know of (SHA, bcrypt, etc.) do not produce these types of extremely similar hashes, even when supplied with very similar input. This leads me to believe that they are rolling their own (crytographically insecure) hashing function.

Actually, we can rule out the possibility of the Data segments being encrypted using AES ECB at this point. Even AES ECB should be able to make Data1 and Data2 completely different. At best it could have been Caesar-ciphered using a universal shift value that all clients share, but it's not like that will add any extra dimension of security or anything.

I currently speculate that Data3 and Data4 are a part of a really bad anti-replay mechanism. Nothing stops an attacker from chopping off Data3 and Data4 and adding the Data3 and Data4 that matches his or her IP address.

Just to be clear, we did not share accounts for any of these tests. We were purposefully using bogus IDs and passwords (which was how we were able to test similar credentials). It doesn't have to be credentials of a real account in order to test. The client encrypts / hashes / sends all credentials in the exact same way, for it does not know whether a set of credentials is valid or not until the server sends a reply packet.

Edited by Riuga, 21 May 2017 - 02:19 AM.


#12 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted 22 May 2017 - 08:45 PM

I decided to revisit chat packet encryption today, this time with messages longer than 1 character.

As it turns out, the "packet identifier code" (as I once thought it was) simply denotes the length of the packet. Having said this, it is not hard for someone to filter out your chat message packets just by packet length. Every chat packet length is (>= 23 && (length % 2) != 0).

Each character in a chat message adds 2 bytes to the packet. The first byte is the actual character, while the second byte is the locale of that character (e.g. English, Russian, et cetera).

The Caesar cipher is a bit more complex than I first thought. First of all, the character set is divided into groups, and then these groups have their order randomized. This is why going "a b c d e f g h i j k l m n o p", with one character per message, will produce results such as "91 92 93 88 89 90 94 95 96 97 98". Furthermore, the length of a message will affect the entire packet's shift value. A message going "abc" (3 characters) will produce a result such as (ignoring the second locale byte) '30 91 57', while a message going "ab" (2 characters) will produce a result such as '50 31'. Lastly, the position of a character in a message will also affect its shift value (see the previous examples). Just to be even more clear, "abc" and "abd" will produce results such as "50 31 86" and "50 31 87", however "abc" and "acb" will produce results like "50 31 86" and "50 67 98".

This does make a message harder to reverse, but it surely isn't "hard" by any standard if the attacker is competent enough and has enough time.

I still have several more tests to do regarding chat packet encryption, namely whether or not all clients share a universal shift value and whether or not these character groups are randomized every time the server sends a new shift value every ~24 hours or so.

Edited by Riuga, Yesterday, 01:11 AM.


#13 Mantou

Mantou

    Super Ninja Moderator

  • Super Moderator
  • 5900 posts
  • 馒头Clan

Posted Yesterday, 04:05 PM

Just a curious note from Mantou personally, have you done the same/similar analysis for other games?

And mantou have forward this to the relevant departments :)

#14 Riuga

Riuga

    Member

  • Members
  • PipPip
  • 845 posts
  • iRiuga
  • DN, Holywood
  • Programmers

Posted Yesterday, 05:03 PM

View PostMantou, on 23 May 2017 - 04:05 PM, said:

Just a curious note from Mantou personally, have you done the same/similar analysis for other games?

And mantou have forward this to the relevant departments :)

Thank you for your cooperation Mantou. I understand that this thread is a bit messy as it is, and that the first post needs to be updated with the new findings, plus a "TL;DR" section should Eyedentity read this. I'll try to get it done by today.

I've done an analysis on a certain Maplestory private server in the past. They actually implemented proper TLS and encryption for login packets. Needless to say, the encryption made it impossible to break down and study the packets like I am doing here.