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.