ShadowFlyff’s lack of… everything

Amidst the writing of my first blog post, I had a sudden nostalgic urge to relive one of my favorite childhood games: FlyFF, aka Fly for Fun. Exciting, I know. I stumbled upon a private server (which is essentially a custom/fan-made version of the game) by the name of ShadowFlyff. With an active user-base of over 300 people, I figured it would be a pleasant trip through memory lane. However, the game was heavily customized and I rapidly lost interest Instead of playing the unexciting game, I began to fiddle around with ShadowFlyff’s website.

Immediately upon logging in I noticed a red flag: the username and password are being sent back and forth in cookies. 

User and password sent over cookies

I created another account with the same password because I was curious to see how the password cookie was generated, and it turns out that the passwords are NOT uniquely salted. Instead, there’s a site-wide salt. Someone dedicated enough could definitely take the time to crack the salt.

Now, everyone knows the most vulnerable part of a web application is the profile/control panel. Take a wild guess as to where I head next…

User control panel

Stored XSS

I found it strange that it displayed my security question on the main page of the control panel, but that wasn’t even close to the worst part of the application’s design. I clicked through all the tabs and tested for XSS in two of the forms: Change Security Q&A and Change Email.

Stored XSS in Security Question

Stored XSS in Email

Did it work? Sure did! As expected, the email alert popped up first and then the question alert followed.

Absolutely no input cleansing was in sight. BUT, there was a character limit that prevented the input from saving if it was longer than 50 characters. So while there are stored XSS vulnerabilities, you’re only XSS’ing yourself with no dangerous effects.
However, upon further inspection, I discovered that the XSS can go off when the “Forgot Password” form is used. It still won’t do much, but if (and a big if) someone managed to write a cookie stealer in less than 50 characters and then social engineered a staff member to fill out the form to recover the attacker’s credentials… Then, and only then, would there be danger. Because the website authenticates users via user and password sent in a cookie, and the value of the cookie NEVER CHANGES, if the attacker steals your cookie once, he/she has stolen it for good. Why is that? Because the Change Password, Change Email, and Change Security Question form require absolutely no authentication/verification other than the cookie that was stolen. But then again, this is all a very unlikely scenario I’m talking about here.

Unlimited In-Game Currency

Moving along now to the more interesting part of the control panel: the “Add Chips (in-game currency) to Character” tab. The easiest way to break a function that should only accept positive integers is to throw a negative integer at it and see what happens. As you can see below, I did just that.

Modified payload

Well, what happened? Exactly what should happen when the input isn’t validated: A “chip” was removed from my empty bank account. How neat.

-1 chips added to my character

Refresh the page and what did I see?

One chip back, two chips forward

Instead of adding a negative chip to my account, I gained a chip! Ruh-roh… I just found a way to obtain unlimited in-game currency. Let’s make sure it really works and try to send the newly acquired donation chip to my character.

Confirmation of success

One donation chip richer

Now that I’ve proved that it’s possible to get unlimited donator chips, let’s take a look at one of the stranger bugs I found.

Peculiar “Recruit a Friend” Bug

In the control panel tabs, there is a section called “Recruit a Friend”. In my experience, most games reward you for recruiting a friend, so I was wondering if ShadowFlyff did the same. Now, obviously, I hadn’t recruited a friend to this game as I’ve only known of this server for a few hours, so I wasn’t able to check all of the “Recruit a Friend”‘s functionality. Or so I thought…
I modified the payload to input “admin” in the field to see if I could discover information from other accounts even though I didn’t recruit them.

Modified payload

My “recruit’s” characters

It worked like a charm. Actually, more than a charm. If you take a look at the lower right corner of the picture, you’ll see that I had 0 donation chips when I  performed the query. Upon refreshing the page…

500 chips out of where, Houdini-style

Huh? I magically received 500 donation chips. Now, I tried to reproduce this bug with other account names and none of them rewarded me with 500 chips, or disclosed any character information, except for “admin”. Every time I looked up “admin”, I was rewarded with 500 donation chips and the ability to look through his character list.


I can’t quite explain this bug, but if I were to make guess I’d say you’re supposed to be rewarded 500 donation chips per friend you recruit. However, the functionality is so messed up that you get rewarded 500 chips just for looking up your recruits. Anyways, I became more curious about enumerating user information and one final tab in the control panel caught my eye: Character Information.

Lookup Any Character’s Information

The character information functionality is supposed to work such that you can only view your own characters’ information. There’s a list of your characters’ names, you press the check button beside their name, and a page loads with all sorts of statistics and information regarding your character.
That got me thinking: Since the modified payload worked in the data retrieval of the “Recruit a Friend” tab, maybe it’ll work here too. Down below to the left the data that is supposed to be sent to the server (my character’s name, B34N), and to the right is the modified payload of the admin’s character, Krito.

Original data vs. modified data sent to server

I sent the modified payload and it successfully retrieved Krito’s character information. It even showed me Krito’s Bank PIN number.

Krito’s character information

This could easily be prevented if the character’s name in the payload was checked and verified to be on the same account as the username in the cookie.ConclusionLots of vulnerabilities, most of which can easily be fixed. With an active user-base of over 300 people, I was surprised this wasn’t brought to the owner’s attention earlier. Upon speaking with the owner of the server, however, I don’t think he’s aware of what these vulnerabilities are, so my recommendation to him is: Find a premade CMS/Flyff website and use that instead. It’ll be much safer and much nicer looking.Update: As of 2/21/2017, 5 days after sending this report to the owner of ShadowFlyff, the website has been updated to fix these security issues (and also update the design). I’ll be doing another check on the website and deliver a follow-up report this weekend.



I'm a college student currently studying Computer Science with a focus in Information Assurance and Security. I like Python, learning new things, and going fast.


Leave a Reply

Your email address will not be published. Required fields are marked *