Epix-Incorporated/Adonis

Known plaintext vulnerability in datastore encryption

Opened this issue · 3 comments

Version channel

Stable (Default)

Loader version

versions 152 to 259 (current) are affected

What part of Adonis is this related to?

Other

What happened?

Using an encrypted string from the datastore, and a known plaintext of that string, it is possible to obtain the datastore encryption key.

Example

let's we have an encrypted string from the datastore and a corresponding plaintext string:

encrypted string: ZUTaS�^abZL�WSQI
plaintext: hello world aaaa

we can simply modify the encryption scheme to brute force the key, while checking if the result matches the plaintext:

function decrypt_key(str, plaintext)
	local byte = string.byte
	local sub = string.sub
	local char = string.char
	local endStr = {}
	for i = 1, #str do
		test_byte = 1
		while true do
			local test = ((byte(sub(str, i, i)) - test_byte)%126) - 1
			-- verify it's not negative to avoid value out of range exception when converting to char
			if test > 0 then
				if char(test) == sub(plaintext, i, i) then
					endStr[i] = char(test_byte)
					break
				end
			end
			test_byte = test_byte + 1
		end
	end

	endStr = table.concat(endStr)
	return endStr
end

print(decrypt_key("ZUTaS�^abZL�WSQI", "hello world aaaa"))

the resulting output is: omerandomkeysome

the original key was: somerandomkey

How it could be exploited

This vulnerability could be used by an attacker with access to the datastore to obtain the key, allowing them to decrypt or edit entries in the datastore.

The plaintext string required to exploit this could be obtained by finding the user ID of someone who is known to have previously played the game, and identifying their corresponding entry in the datastore to find the encrypted user ID.

Due to this requiring datastore access, the likelyhood of this being exploited is not very large.

How this could be resolved

My recommendation is to switch to an implementation of existing encryption algorithm such as AES rather than using a custom implementation such as the current one.

Device

Windows

Relevant log output

No response

i think you should try pickled coffee

In retrospect, datastore encryption wasn't a smart idea to implement in the first place; if someone or something malicious has serverside access, then your game would be done for anyway.

This is a problem, but back in the days where FilteringEnabled didn't exist, developers didn't do server side checks, and exploiters where stupid, this was a good enough solution. There is no need for encryption anymore, so this doesn't matter.