Category: unfinished
Intro
Recently while living with a car enthusiast flatmate, I discovered the world of sim racing while using his Logitech G920 racing wheel. More specifically, I was spending a lot of time in Assetto Corsa playing in servers with AI traffic cars. After buying my own wheel, I started playing a lot on a server called No Hesi, one of the most popular AI servers in Assetto Corsa. On this server, there is a plugin that tracks every car you overtake and gives you points.
This plugin is able to track your car movements as well as upload your scores to a leaderboard which persists across different No Hesi servers. Being the curious person that I am, I wanted to know how they did this without frying their servers.
The Modding Stack
Assetto Corsa is a highly moddable game with custom cars, tracks and plugins which No Hesi heavily takes advantage of. These mods are not completely supported natively and an install process is outlined in the following video:
The first thing that is installed is Content Manager. This is an open-source piece of software that essentially replaces the main menu of Assetto Corsa, and manages custom content like cars and tracks as well as in-game settings such as controller binds. Next, Sol is installed. Sol is a mod that affects weather and lighting to provide a more realistic feel. A dependency of Sol is the Custom Shaders Patch (herein CSP). While providing custom shaders, CSP also implements an extensive Lua API, extends server features and much more. The Lua API is used for UI “apps” like the No Hesi overtake plugin as well as for extending car physics.
When joining AI traffic servers, you will typically see this footer in the chat. AssettoServer describes itself as “a custom game server for Assetto Corsa with freeroam in mind”. It is an open-source mod that extends the original server to add features such as AI traffic and Steam API authentication. Also, parts of CSP’s server features are implemented.
Dumping the Plugins
First, I needed to figure out how the server communicates what plugins to load to the client. While looking through the AssettoServer documentation, I saw the following:
This links to the CSP documentation and outlines extra options a server can send to a client in an INI file. We can see where LUA scripts are defined in the following:
It is important to note the the documentation states the extra options are “a simple INI configuration file hidden in a welcome message”. The welcome message is simply a text message that shows up in chat on a server join. Also, these scripts are said to run on the client machine. This raises some questions as to how they are communicating to their leaderboard as well as suggests I might be able to have the full source code.
The bottom of the documentation page describes how to encode and send the configuration file: Get UTF-8 encoded config bytes. Compress bytes using zlib. Encode bytes using Base64. Append 32 tabs and a header of “$CSP0:” in front of the result. Attach to the welcome message.
Fortunately, AssettoServer does all of this for us with “csp_extra_options.ini”.
To be able to read the INI file, I would most likely need to dump the entire welcome message from memory. CSP is not open-source so this will require some digging.
Eventually, I was able to find what looked to be an INI parser which received the raw UDP data from the welcome message. This called another function that verified the “$CSP0:” header. By breakpointing this function and inspecting the register, I was able to recover the encoded INI file.
Since we know how the encoding is performed on the server, we can simply reverse it in a tool such as CyberChef.
Perfect, we can now read the INI file and even see the scripts that are meant to be loaded. The INI file also has what appears to be variables that will be injected into the script. Downloading this script directly causes a 403 error which can easily be bypassed by spoofing the User Agent header.
Afterword (14/11/2024)
I never finished this article for whatever reason. In the end, I did achieve a bypass of their Lua DRM as demonstrated below.
I did also hack their leaderboards which they were NOT happy about. Since building a new racing rig, I have a renewed interest in the game and should hopefully revisit this topic soon.