Minecraft is a survival game published by Mojang, owned by Microsoft. When you start playing, you don’t have anything and you must break blocks ("mine") `and build structures and craft objects to progress. We usually call this genre “sandboxing game”, but ironically we can’t say the same when it comes to security.
Minecraft can be played in Singleplayer, Multiplayer and on Realms. Realms is the multiplayer version hosted by Mojang. The flaw we describe only targets Multiplayer, where servers are controlled by third parties.
The 1.8 version, released on September 2, 2014, introduces Resource
packs, custom images and sounds to use when rendering the world. Two packets
were introduced in the Minecraft protocol: Resource Pack Send and Resource
Pack Status.
The associated code looks like this:
public void handle(S48PacketResourcePackSend packet) {
String url = packet.getUrl();
String hash = packet.getHash();
if (url.startsWith("level://")) {
String urlWithoutPrefix = url.substring("level://".length());
File savesDirectory = new File(gameController.mcDataDir, "saves");
File resourceFile = new File(savesDirectory, urlWithoutPrefix);
if (resourceFile.isFile()) {
netManager.sendPacket(new C19PacketResourcePackStatus(hash, Action.ACCEPTED));
// snip, loading the resource.
} else {
this.netManager.sendPacket(new C19PacketResourcePackStatus(hash, Action.FAILED_DOWNLOAD));
}
} else {
// snip, handling URLs.
}
}
To trigger the exploit, servers simply need to send a Resource Pack Send packet
using a URL that starts with level://
. The game will try to load that file from
the saves
directory. If the file exists, a packet with status ACCEPTED is
sent. If not, a packet FAILED_DOWNLOAD is sent instead.
Traversing directories is also possible using ../
, putting user data at
risk. Servers can check if a file exists on the player’s computer, enumerate user
names … but maybe even worse. See PHP’s issue with file_exists
and phar files.
This exploit is invisible from the player’s perspective and can be triggered at
any time while playing on a server. This exploit can be automated and accelerated
by sending the packet in batch, the server knows that the responses will follow
the same order. Even better, the client is generous enough to send back the hash
– which is conveniently sent by the server, and can just be the checked path itself.
As pointed out by SirUnkn0wn, the launcher_log.txt contains the successful exploit attempts:
[0913/140810:INFO:GameCallbacks.cpp(199)] game/bns (Client thread) warn Unableto parse metadata section of resourcepack: servers.dat java.util.zip.ZipException: error in opening zip file
In the 1.9 version, released on February 29 (2016), a condition was added
to make sure this exploit is prevented: the level://
protocol can’t use ..
to go up in directories, and the /resources.zip
suffix must be used. The status
packet was also evolved to only send the status, and not the hash, making it a
bit harder to parallelize the attack.
private boolean validateResourcePackUrl(String url) {
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
boolean isLevelProtocol = "level".equals(scheme);
boolean isHttpProtocol = "http".equals(scheme);
boolean isHttpsProtocol = "https".equals(scheme);
if (!isHttpProtocol && !isHttpsProtocol && !isLevelProtocol) {
throw new URISyntaxException(url, "Wrong protocol");
}
if (isLevelProtocol && (url.contains("..") || !url.endsWith("/resources.zip"))) {
throw new URISyntaxException(url, "Invalid levelstorage resourcepack path");
}
return true;
} catch (URISyntaxException e) {
netManager.sendPacket(new CPacketResourcePackStatus(Action.FAILED_DOWNLOAD));
return false;
}
}
This security issue was fixed silently by Mojang, and no patches were made to the 1.8 version of the game. 4 years later, thousands of players still use the 1.8 version of the game - or a fork of it - and could suffer from this exploit. I haven’t seen any publicly available code taking advantage of this.
Mojang once replied to the Minecraft Java Edition Skins Issue outlined by Avast, but missed the chance to communicate about the Resource Pack flaw, sadly.
PS: This also allows servers to check if cheats or mods are installed on the player’s computer, but I advise you not to. Doing so would be illegal!
Summary
Affected product: Minecraft by Mojang.
Affected platforms: Windows, Linux, macOS.
Affected versions: 1.8 - 1.8.9, 1.9 and above are not affected.
Security issue: In multiplayer mode, servers can check if given files exist on the player’s computer without their consent.
Solutions:
Update Minecraft.
If you really want to play 1.8, only play on servers you trust, or
install the Forge mod made by Sk1er (thanks!):
download it and place it in your mods/
directory.
The source code is available here.
Source for the protocol: wiki.vg