Documentation and proof of concept code for CVE-2022-24125 and CVE-2022-24126.
A new game update, 1.15.1, has been released for Dark Souls III on 2022/08/25, along with the restoration of online services. This update fixed both CVE-2022-24125 and CVE-2022-24126, along with a wide variety of other potential security vulnerabilities present in the game's P2P networking (OOB reads/writes). Furthermore, all known exploits allowing one to corrupt the save of other players have been fixed. Many common petty cheats (e.g. "curse knife") which could be encountered often during online multiplayer have also been patched.
This repository contains proof of concept code and documentation for the most recent RCE exploit affecting FROM SOFTWARE games, CVE-2022-24126. While theoretically possible in other games, focus is on Dark Souls III as this is the game my research has been conducted on. As of now proof of concept code only exists for Dark Souls III, the vulnerability has been confirmed to be present in:
The vulnerable code is also present in Sekiro (credit: LukeYui), although there is no way to trigger it. Presence in Demon's Souls has not been confirmed but is very likely. While the closed network test was affected by this, the release version of Elden Ring is not. In fact, a huge list of network crashes, out-of-bounds reads/writes and exploits allowing players to modify the game data of peers which were present in Dark Souls III have been patched in Elden Ring. Kudos to LukeYui for compiling this list and to FROM SOFTWARE for acting swiftly! I'm happy to say that
Contrary to popular belief, this is NOT a peer-to-peer networking exploit. It is related to the matchmaking server and thus much more severe, since you do not need to partake in any multiplayer activity to be vulnerable due to another matchmaking server vulnerability (CVE-2022-24125).
With the game having an average concurrent playerbase of about 20,000 players in the months preceding the server shutdown, it was clearly an issue that needed fixing immediately, especially with the possibility of it being in Elden Ring. Since FROM SOFTWARE had not yet acted over 40 days after my initial report with proof of concept videos and detailed exploit documentation (which a large part of this readme is based on), I decided to demonstrate the existence of the exploit puclicly in a benign manner in the hopes of raising attention to have it addressed by the developers, and it worked.
See here for more details on these 3 gadgets. If for some other game this virtual call method is not a feasible approach, the arbitrary code redirection may still be used to setup more traditional ROP exploit.
To run the proof of concept code, you must first have a server to connect to. While the official servers have been disabled due to the exploit, you can setup a private one using ds3os. ds3os is designed to mimic the retail server behaviour as close as possible, but security patches have already been deployed to this project to fix this exploit. However you can still setup a testing environment by building the project yourself with the SEND_MESSAGE_TO_PLAYERS_SANITY_CHECKS and NRSSR_SANITY_CHECKS constants set to false in BuildConfig.h. This mimics the unsafe retail server behaviour. Follow the instructions provided by ds3os to start the game and connect to your server.
Once this is done and your game is connected to the servers, build the PoC code and start the Injector.exe executable. It will inject a DLL containing the exploit code in the Dark Souls III process. This DLL will then use the game function that sends FRPG messages to the server in order to deliver the exploit to your own client.
The function 140ca5010 check entry sizes, but 140ca4fa0 is for variable size entries and does not perform sanity checks on the size field (Bug #1). To achieve the arbitrary code redirection exploit described above we need to set it to 14F3B0. This will cause an out-of-bounds read of approx. 1.3MiB but the memory page should be large enough to avoid access violations.
140ca56b0This function is called by the previous one with nrssr_data as an argument. Creates the DLMemoryInputStream object on the stack which is then passed as an argument to the NRSSR parser.
141955f50: ParseNRSessionSeachResultThe NRSessionSearchResult parser. Verifies NRSSR signature and version numbers (14196a0f0), parses the property list (14196a260), host name (14195603a) and some more info (see rce.h)
14195603aLoop in the above function that unsafely copies the host name (Bug #2). Here are some addresses that may help keeping track of what is happening during the buffer overflow:
14F128DLMemoryInputStream stack address: 14F3A0DLMemoryInputStream vtable pointer after the overwrite: 1439e8b30DLMemoryInputStream used by the DLInputStreamReader: 0x181439e8b48MOV RCX,qword ptr [RCX + 0x8]
MOV RAX,qword ptr [RCX]
JMP qword ptr [RAX + 0x40]
Where we end up after the first code redirection caused by the overwritten memory stream vftable. This is where the chain of virtual call redirections begin.
For Dark Souls III Ver. 1.15. The maximum theoretical payload size depends on the stack layout and as such will vary by game and version. ↩