77 comments

[ 3.3 ms ] story [ 142 ms ] thread
Who figured it would be a good idea to allow received chats to be interpreted as code?! That's a pretty big security fail if you ask me.
Read the article. Received chats are executed only after the victim has run the script provided by the attacker. The real question is "why does the scripting system allow overriding functions like that?".
Don't most scripting languages allow overriding functions like that? My only experience hacking on Lua has been in game UIs.
Lua was created to be a configuration file system that was turing complete, to be used by a oil mining company.

Lua was never intended to be used for games, UI, etc... It just proved useful to be used like that.

Because of Lua "real" intentions, it was made in a way that you can assign "everything" to "everything", and you don't need () to refer or call functions. (in fact, many of the stuff that make Lua look like a "normal" programming language, like dot syntax, () and whatnot, are "synctatic sugar")

Please do not spread false misbeliefs. Wow's Lua is 5.1-flavoured afaik, and that's completely different language from 5.0, 4.x or what you describe.

This entire thread mentions fatality of function substitution in Lua, but that is easily prevented (by setting proxy metatable on global table and system libraries, even any lua-noob knows that, blizzard devs are just losers). But even that missing protection is not what breaks security. In dynamic languages like lua or javascript you control the dynamicity via localization of global values at eval-time ('eval' as in repl). 'local trim = path.to.sys.lib.trim'. So, once trim function is localized in console code, you can assign anything to original location and that will not interfere with console logic. Lua is just too hot to handle for wow-devs, and python, perl, javascript have the same issue more or less the same way.

> Read the article. Received chats are executed only after the victim has run the script provided by the attacker.

I did read the article, which is why I said that this was big security issue that the chat could be interpreted as code. This should have been tested against.

It is evaluated as code only after the (legitimate) player modified the environment to do exactly that.

If I can convince you to paste some random code from this HN comment into a command interpreter, that could do similar things to your system.

The attacker figured. WoW doesn't do this normally - the attack involves the victim explicitly replacing an innocuous "RemoveExtraSpaces" function - which ostensibly is used as a scripting hook to trim spaces from incoming chat messages - with an eval-equivalent "RunScript". They basically just tied the ends of the right wires together.

I'm not even sure this is a vulnerability at the scripting level. I think it's just a bad idea to include `/run` by default.

The `/run` command is pretty essential for debugging mods. I think that it'd be a wise idea to disable it by default, and allow an advanced user to change a setting in a file to turn it back on.
To add to this, any barriers Blizzard introduces will just become an extra step in the social engineering portion of the attack, getting the victim to enable the feature.
Facebook has had the same problem with the browser devtools. Fun seeing a repeat of it in a different sector.
It is reminiscent of "Press Alt-F4 for ops", used to troll Mirc users on IRC back in the 90's; or having people enter "+++ATH0,ATDT,911" from the BBS days.
Incidentally, that ALT+F4 trick worked in WoW too, since we're on the subject.
I understand that WoW doesn't execute all received chat.

My issue is that this exploit was possible AT ALL and that this wasn't tested. As a web developper, this is the kind of exploits I keep in the back of my mind every time I develop something.

No part of this attack involves exploiting a bug. There is a deliberate feature which lets you enter and run arbitrary code. Tricking people into running malicious code results in bad things happening to them.
Users shouldn't be able to alias anything to RunScript. Much less alias RunScript to RemoveExtraSpaces or other functions which are called by the core. This is a big big big security fail.

Yes, this bug involve some social engineering but the bug itself is big. This is not a bug but a really bad oversight. If someone made it so that the field of a website's form called eval() directly we would all be pointing fingers right now. This bug is the exact same thing.

You can make every website in existence call eval() directly on the contents of a form field if you persuade the user to paste some arbitrary text into the developer tools. The attack here happened to involve hooking an internal helper function, but that hook was in no way necessary for the attack; it could have instead just registered for the incoming chat text event and called eval() on it there.
Nope. Perl (e.g.) calls this 'tainted' data and it should never be passed to any kind of evaluator. And that means that console should never pass arrived data to anything initially unknown. It's implementor HAS NO RIGHT to call functions that can be overridden, he should save startup values of all used functions as local values and never look there again, at least. As I already said in this thread, blizzard devs are just incompetent in trivial security.
At least someone else in the comments has heard of "tainted" data. How in the world incoming chat text from other players is ever allowed to wind up in an executable/scriptable context is baffling.
I know, right? I can't believe that my message are getting downvoted so much.

Yes, the user has to be tricked into writing a piece of code into the console. The problem here is that this piece of code shouldn't have been able to be executed at all. Who in their right mind would allow incoming messages to be parsed? They should have caught that bug in development!

> As a web developper, this is the kind of exploits I keep in the back of my mind every time I develop something.

As a web developer, you should also know that there is absolutely nothing you can do to prevent attacks performed through the developer console. This is the moral equivalent.

At that point, yes, it's too late. The issue here is that their developer console is also the chat and that users can receive external messages from anyone in that "console". If you want to have the chat be the console, you really need to make sure everything is safe.
> Who figured it would be a good idea to allow received chats to be interpreted as code?!

They didn't allow it on purpose. They have a "RunScript" command that allows you to execute code on your machine. However, the attacker tricks the user into overwriting a function that is called when a message is received to run the "RunScript" function instead.

> That's a pretty big security fail if you ask me.

That's the point of the article.

Pretty cool that they allow players to run their own scripts, and in a full Lua environment no less. I imagine that could be useful in a game with a lot of repetitive tasks.
The ability to run Lua scripts has been a WoW feature since its release in 2004-2005.

To prevent the game from being easily being botted to death, there's not much you can script aside from automating UI interactions. This was a killer feature for the Master Plan mod last expansion, which automated clicking through poorly-designed menus for a poorly-designed mechanic, and it single-handedly broke the economy.

> and it single-handedly broke the economy.

Could you get money by clicking menus? I'm curious

If you had a number of characters optimized for it, you could get thousands of gold every day for a half an hour of menu clicking.

This technique has just been removed from the game, however.

From what I understand they essentially made a part of the expansion which worked like farmville where you through a UI sent out your followers on missions which would finish in a certain amount of real world time later.
> it single-handedly broke the economy

Let's be fair here. It's the Garrison's design that broke the economy - Master Plan just made it worse by turning "a few click every few hours" into "one click every few hours".

Fair. :p although it would have made using alts much more infeasable, and cause people to quit faster.
Sort of. Blizzard goes to great lengths to keep players from running "bots". For example, a bot might allow a player to run an account 24/7 that would just kill a specific monster over and over until a certain rare and valuable item dropped. This isn't possible, because certain actions (such as "Attack the monster") can only be taken in a script that is running in response to a UI event. This isn't a security fix though, just a way to prevent players from gaining an unfair advantage by running bots.

On the other hand, I did write a handy few handy little addons despite this restriction. For example, when you're doing lots of wheeling and dealing at the auction house (a perfectly legitimate way to make in game money), you tend to receive a huge amount of "mail". When another player buys an item you're selling, you receive the payment via your mailbox. It can be tedious to go through all the messages and take the money or items (mostly a UX issue if you ask me). To get around this, I just added a "take all AH stuff" button to the mailbox UI. There were a few problems, in particular that you'd have to "pump" it, because moving to the "next page" of mailbox items was an asynchronous operation, and the callback wouldn't be able to do the "take item" action.

Users contribute huge numbers of useful addons despite this restriction - for example, auction house addons can remember price data and show you items that are substantially above or below their general market value. The famous "Carbonite" addon made gigantic improvements to the in-game map, most of which were later incorporated into the default interface. And no serious raider would go into battle without a host of combat helpers, DPS meters, and so forth.

The Zygor add-on does your in-box trick, and has a gold-farming module that helps quite a bit in identifying below-market pricing (user-seen auction data gets sent to the cloud for analysis and downloading by subscribers)
I haven't played since early WotLK, so I'm not too familiar with the latest in WoW tech :-)
reminds me of people writing IRC bots doing something like:

    if $line =~ m/!calc (.*)$/ {
        return eval $1;
    }
which is about the worst possible way you can easily write a calculator :P

In fact, irc bot/script writing is a great place to learn about security and generally distrust of the rest of humanity.

Even things like the pathological regex backtracking DoS from the other day turn up fairly regularly with popular bots.

In some programming IRC channels I've seen similar done intentionally. On the plus side, they were sandboxed. On the minus side, the sandbox didn't prevent playing sounds on their locally hosted machine... needless to say, there was a lot of beeping.
Ahh... allowing users to run code they don't understand. The same reason Facebook tried to kill the Chrome Dev Tools[0] and Apple more recently killed the javascript: URL scheme in the address bar

[0] https://news.ycombinator.com/item?id=7222129

> and Apple more recently killed the javascript: URL scheme in the address bar

wait, WHAT? This isn't good! This raises the barrier of entry for new programmers to play with Javascript! I had no idea this was done!

And for those of us who use Bookmarklets - it has made Safari a non-choice of browser.
Just enable `Develop > Allow JavaScript from Smart Search Field` in the menubar.
Bookmarklets still work for me (and as andrethegiant said, you can re-enable it in the Develop menu)
So what is the point of trashing the Javascript URI? People with malicious intent will just have the person make the code into a bookmarklet and run it. Which is actually easier than explaining how the URL bar works.

Or does it do what Chrome does and you can't copy/paste Javascript: until the URL bar you have to type "Javascript:"?

All they need to do is open the developer console, which is probably better anyway.
What's happening here is the 'RemoveExtraSpaces' function (ie. basically a trim) is called by the game engine every time a chat message is received. But apparently, you can rebind this name and point it to any other function, including 'RunScript', which is an eval.

When this was revealed, Blizzard quickly patched in a warning dialog that warns against running scripts from untrusted sources, including being social-engineered to enter stuff yourself (which is what's happening here). That attitude seems prudent, but isn't entirely helpful, as many players in fact use Lua in their chatbox to do complex actions or calculations.

Like this one that prints your current position in 'map coordinates':

  /script x,y = GetPlayerMapPosition("player");
  map=GetZoneText();
  c1=x*100;c2=y*100;
  print(string.format("%s: %.2f, %.2f", map, c1, c2));
or the 'CTC macro' that was used to calculate a value that raid tanks must have attained:

  /run DEFAULT_CHAT_FRAME:AddMessage("Need 102.4 combat table coverage. Currently at:"
  ..string.format("%.2f", GetDodgeChance()+GetBlockChance()+GetParryChance() +5))
It's true that users shouldn't run untrusted code, but realistically, they'll probably click through most warnings to run legitimate functions like this. A better fix is to prevent rebinding the 'RunScript' function to some other name, and to prevent rebinding the 'RemoveExtraSpaces' function by anything else.
Another contributing factor in this vulnerability is that the 'chat compose input' and the 'script console' are one and the same.

While this was done to simplify UX, it's really not a good idea in retrospect.

Even as something simple as a different chat frame that only allowed script commands, into which only local script output can go, would also serve as an effective mitigation.

Or do it like Quake and HL did and have tilde be the console. You can do things like "/say foo" or commands / settings through there, and in the case of quake at least, it can load scripts from files in a directory. This is not new stuff, and it's surprising that it doesn't do this already. Example: http://ezquake.sourceforge.net/docs/?scripting
It supports this already, or at least did. Console just needs to be manually enabled.
I'm not sure how that would solve anything, the attacker would just convince the victim to type that line of code into the script console instead of the chat console.
Sure, the rebinding could still happen. But, the remote execution is prevented (right now, after rebinding the trim function, the attacker can enter script in the chat window to be executed - this part goes away with a separate console).
I don't think so.

The attacker is executing script through the RemoveExtraSpaces function that gets run on every chat message, not by executing it with either player's chat console.

The assumption is that a proper mitigation would result in the script console being in a separate execution context; such that variables that are (re-)declared in the script console would not affect the chat console's context, or its 'RemoveExtraSpaces' function, nor the global context. I should've been more clear.
That assumption wouldn't work. If the script console is a separate Lua environment, it's completely useless. As long as it's the same environment that the rest of the game/addons use (which it must be), then there's no "mitigation" that can be done like you're hoping for.
You (presumably) couldn't send chat messages directly to another player's script console, which is how this works.
> A better fix is to prevent rebinding the 'RunScript' function to some other name

Breaking a huge number of addons in the process, for literally no benefit because the attacker can just use that other name.

> and to prevent rebinding the 'RemoveExtraSpaces' function by anything else

Which wouldn't really solve anything because the attacker can just find some other function that is regularly executed with attacker-supplied input and use that instead.

No, a better fix is to remove the ability to re-bind ALL functions, or at least system calls. How is function-hotswapping-bullshit permissible in an untrusted environment?
That's how Lua works. It would be prudent, but difficult to change.
There isn't really a good way to prevent reassignment of first-class functions to new names in Lua.
> A better fix is to prevent rebinding the 'RunScript' function to some other name, and to prevent rebinding the 'RemoveExtraSpaces' function by anything else.

Or maybe forbid rebinding any system-provided global symbols at all?

This completely misses the point. Incoming chat messages from other players should simply be incapable of reaching a context in which it is interpreted as script. Inbound text chat should be treated as such - text. If the player types in commands that directly have an effect, that is their problem. If a single command provides remote code execution of anything another player types in their chat... that is simply ridiculous.
The very existence of RunScript combined with the ability to rebind functions makes this impossible, I think. Unfortunately, I'd guess that, at this point, those features are too tangled into the game to be easily cut out.
I did quite a bit of Lua WoW programming back when I was playing in WoW tournaments. The community really wanted to change a lot of the UI / UX of the default interface to be more friendly for high level play. Tournament rules did not allow usage of addons that pre-packaged such changes, but the admins of the tournaments did have permission to allow usage of light UI changing scripts. Some people took it really far and used automated cooldown trackers etc from macros that you would paste one line at a time, but the admins in tournaments would not allow that.

There's still somewhat of an active community: http://www.arenajunkies.com/topic/222642-default-ui-scripts/

Unbelievable. Why give players the ability to override arbitrary functions like that?
Why are you.. outraged? Clearly allowing this attack was a mistake. Overriding functions is a language feature, so you'd have to think of the risk to think to block it.
Outraged? C'mon now. Shocked with disbelief maybe?

Because that is such an obvious attack vector that it is hard to believe Bnet allowed it. It's very hard to enforce language-level restrictions (like which functions may run when) when they can be circumvented with reflection.

Besides, Bnet's WoW client code has been known to be janky, and their entire security setup seems to only care about protecting the business, and not users. Bnet is the only online gaming service where I have had multiple accounts hacked that I could not trace to any specific doxing/pw dump event... forcing me to conclude that their security infrastructure is absolute garbage

Why not? The user interface being modable is awesome.
(comment deleted)
Because it's useful and it's their fscking computers and it allows them to tweak the interface to better suit their play?

Should people's ability to receive email also be taken from them, because some of them might fall for the prospect of receiving a million bucks from a friendly Nigerian prince?

It's a feature, which Blizzard has invested a significant amount of time and money into, and has definitely contributed to the game's success. It allows players to modify the game's interface, not just arbitrary game code. Think of it as crowd-sourcing UI improvements from the community. Blizzard is known to take great UI mods and implement them into the game directly.

For example, on release I created a mod that let you examine a player's equipped items from any distance. By default, the inspection window would close when a function returned true. This function checked to see if the distance to your target was greater than 5 meters. An easy way to change that behavior was to rebind the function to one that always returned false. It's a natural thing to do in Lua, I think.

I used to run tons of WoW mods back-in-the-day. I get that.

This particular language feature is not something that is solely responsible for WoW's moddable UI. While it might be nice in certain circumstances, you can build flexible UI without having to hook or reassign critical functions

Slightly off topic. Are any of y'all going to be playing the next expansion? I am looking to join a very casual guild :)
I'm sure the method was different, but way back in the day when I was playing Phantasy Star Online on the Sega Dreamcast, "digital mugging" was a common occurrence. The attacker would walk up the the victim, ask them to trade, and the victim's interface would lock up causing them to have to reboot the console. When they logged back in, all of their gear and money was gone. If the player hadn't been to the bank to make a deposit recently, they were screwed out of potentially hours of game-time work.

I never did learn how this was accomplished; it happened to me only once, after that I ignored any player I didn't know in real life, which cut out the MMO part of the game for me.

hahah this brings me back. I can shed some light...at least a little, there were exploits that crashed peoples consoles, this didnt give the thief any items, but cleared inventory or even saves for some players.

http://dcemulation.org/phpBB/viewtopic.php?f=36&t=11941

great game would love to see a rerelease of the original or even PSO2 in america