How to get code execution from FFXIV mods in one simple step

A weave of bad ideas, one into another

posted 2023-03-29

Warning

This post was made a long time ago. The information inside of it may be outdated, and the writing may not accurately reflect my current self.

Some bold text to start off with:

This vulnerability is patched in the latest version of Penumbra and TexTools. If you aren’t up to date (Penumbra 0.6.4.0+ and TexTools 2.3.8.5+), do it now. TexTools users will have to switch to the beta branch to get the latest version. Additionally, Mare Synchronos likely was never able to sync/execute this (and now can’t with the Penumbra fix).

Now, let’s explain what the vulnerability is. This vulnerability allows an attacker to build a specially crafted mod that would execute arbitrary code on file load, abusing what is fundamentally a bug in the base engine of FFXIV. By overwriting a certain path in the game’s filesystem, you could load code on game startup.

So, how was it possible?

Never trust your Lua state

Yep! Lua!

FFXIV uses Lua 5.1 to script a lot of things in the game. It doesn’t store just raw .lua files, though - it stores the weirdly-obscure Lua bytecode format (compiled with a 32-bit luac). These are in the game_script category in the game’s virtual filesystem, under the .luab file extension.

By writing custom code, compiling it into bytecode, and replacing files with it, your code can run in FFXIV’s Lua state! Oof.

And, if you modify the event handler Lua script, your code can run on startup! I found this path by replacing every known Lua script in the game (lol) with a script that would write the filename to a text file on my desktop. Just be careful when doing this, as the event handler is used a lot.

…wait a minute, write to a text file? Does that mean they- Oh no.

They left os and io in the Lua global table.

YEP! This means you can read and write files and execute arbitrary programs! It’s literally this easy:

os.execute("calc.exe")
os.exit(0)

Then you create the bytecode, swap the file, and you’re done! Calculator popped.

What you could do with this

There’s a lot of fun to be had with modifying Lua! You could:

Overall I haven’t explored the Lua state as much as I want to. The primary worry, of course, is executing malicious payloads from mod authors. This would have about the same amount of danger as running totally_not_a_virus.mp4.exe off of some shady corner of the Internet (it could do anything you can do).

Some tactics, featuring DLLs

Unfortunately, package.cpath is set to load DLLs from the game folder. This means not only can you run arbitrary code, you can run arbitrary code inside of the FFXIV process! With a little work in Rust (featuring the ctor crate), and storing the DLL as a byte array in the script (then writing it to a temporary file), we get free process access. We’re basically as powerful as a third party Dalamud plugin, which has big red text when installing it for a reason.

With enough effort, we can get the player’s session ID - the value that represents you when you log into the game - and do whatever with it. An attacker with this in their hands can log in as you!

Here’s a little proof of concept showing off viewing the user’s session ID:

How to blend in

While TexTools prompts you with every file, nobody really reads that. Stuff a bunch of unrelated files in there that mask the .luab and you’re good to go. Because sites like XIV Mod Archive don’t host mod files themselves, they can’t automatically scan for malicious files, meaning it has to be done in the modloader. Heliosphere is the only mod site I know of that blocks certain file extensions automatically on upload.

The lowest hanging fruit possible

I’m aware that this “vulnerability” is incredibly low hanging fruit. Sorry to the people that thought I found a vulnerability in file parsing or something.

Some may view me publishing this as immature and stupid, and causing shit for no good reason, but I can’t in good conscience keep this a secret. Just because nobody has exploited this yet doesn’t mean it won’t happen. Get your stuff patched!

Timeline

All times Eastern Time.


Update: 02/29, 7:36 PM: Seeing some people attack the TexTools team for their response time - please don’t! They’re doing this in their free time (volunteer work) and I was informed that most were busy with other stuff. I also (with permission) revealed that my contact wasn’t a moderator but actually PrettyKitty, who informed me my messages were delivered to the developers very quickly.

Closing

Penumbra and TT should’ve been blocking modifying these files for a very long time. I just so happened to be the first skid to put two and two together and break something! Good thing it’s fixed now. Maybe it was good that the first person to shout about this was me, because I’m not a malicious actor - I’m just an idiot.

I haven’t seen this exploited in the wild, but I am concerned that it could be (given that this post is essentially a how-to). Make sure to update your modloaders!

This “fun afternoon project” wouldn’t have been possible without: