Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

When WebSockets Lead to RCE in CurseForge - 1854

Elliott.diyPosted 2 Months Ago
  • The author of this post had recently found an RCE in a VPN client called SuperShy. After finding this bug, they were curious about other services that exposed WebSockets locally on their system. They noticed that CurseForge was doing this, a widely used video game modding platform.
  • To actually find the websocket, they used something like Wireshark to see what was going on. Every time CurseForge was launched, they would see a payload for a typical launch message. Notably, it had AdditionalJavaArguments inside of it, a type and a Name that looked like Java functions.
  • Websockets are not bound to the Same Origin Policy (SOP) as HTTP requests are. As long as the server allows requests from any origin, it's allowed. The message contained no origin check, no authorization mechanism, or anything else. So, they tried connecting from a Websocket with a bogus origin header, and it worked. This means the application can be accessed from any website the user visits. Neat!
  • There were several actions but a single one stood out: minecraftTaskLaunchInstance. It contains a parameter for arbitrary additional Java arguments that is used to start the game. Another interesting one is createModpack. This is creating a modpack on the user's system. This is required because we need a valid modpack to call minecraftTaskLaunchInstance with.
  • The author used a clever trick to trigger arbitrary code. First, they pass -XX:MaxMetaspaceSize=16m; this limits the JVM's memory space. Since the JVM crashes, it will call an out-of-memory handler, which can be anything. The second flag is -XX:OnOutOfMemoryError="cmd.exe /c calc", that gets triggered on crash.
  • The CurseAgent doesn't bind its WebSocket server to a fixed port. It listens to a randomly assigned local port whenever the launcher starts. So they wrote a JavaScript scanner that scans 16K ports to find this.
  • Good write-up! To fix the bug, CurseForge no longer exposes the WebSocket server; I don't know what they use for this functionality instead.