CategoriesSecurity

Crimediggers | Decrypting Base64 messages using RSA private keys – Encrypted Data: (chuckles) I’m in danger.

A friend of mine was doing an online interactive puzzle/game called Crimediggers developed by the Dutch law enforcement agency, and he asked if I could help him with decrypting some encoded messages.. Hmm, interesting!

He already collected the encoded messages and has obtained the private keys. We are not sure which private key belongs to which encoded message.

Encoded Messages

These are the encoded messages in question:

mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ==
W1hkk4XxKglKgRo96MQw0glw+O3WpH2OwSy2I+NbWdQ+dYtdJzR1shwCbacCdzF+DNPa07FWhHUE+An6CD8sRPLRyuXR/p8goehgLG3iPma1gyut0VjHyNDIJsJSu4gvnrEcfiWdEYGUKw+NFeYsvDniyOnH/d3BAli8lM8PDxgZjJ6lQ5EZnjQOGS4l2DZWU1lVXfMukK9/5nAO4h41pSCK8ultYFdEk8sdrf3Td2XVp/EIGI9XCwTAZ8H2+XP/eCO4ecgN3GRjttkdQYUhqvlnCaHpsQyNCGzJQpAOycAj/GDTtQ+EoSfVtEAnmOCZRFk12fy8PL+XnUEI/SwIQg==
UdMsi/STSeUBkVUucCBJWwbUzzF0v8bay0suQg9WvBglwZFoGgAVK48d8AWIhEa1euqkF8O2lv4Sprihlzt+HFNEcf1QADyOTZpK+O9PrtEie9o48TbEaFbxSUImepBzLF2/YxSbKhfGYUNb+4MfOn7r0mLmFeslCNQoH/ZfNW76QZ5/0z0HPZOWCCfAEM6n/L7ERh77h4pemGz8UYLTw12TsBNaNeA4vzqNVTtLnzUpcrFrwJrnBOPjw78Ce/jN/8BNhc+PKwvSQw2yqdAUly6+dUq2W/VEuCK3Q+/ilqtRgu5KZBDlarHgMVeS+Sn0dNleiqB0sPUV5O/PPjGE2A==
UxWL9nhlgZUxdbQDMYs6rDcoqHpSKOPN9c32I2+F4pv3FcxNtUh8TcoF0TBe2MoitglYRsRXIKdVl1MmVQUnb9L+QWSaNlgI/GkI9gXrtUIpS6ZluyJzTzKwwh47BKW7d/3YlrenbL0f8PYy7y2JcZK7gJLcp2AJVNkFAlgKZWdcjjvqdY2GoB7GDtztMSqjM27Zs0DgSv3p6QIqJuWMe3eCQhdMGASBcShItd+wQd1z/3nNvmY5Mk5xC7RahIMi4UZitSgLb6cLKfNmIrre9mDZwnHJxpCtLmgh54pW8ACEpo2qfW/dcAa4dtQebwo7HcpixMzcj7rGon0l+pg5HQ==

From these four messages we can establish a couple of things:

  1. Modern encryption algorithms usually outputs into random bytes and yet this message seems to be formatted in a plain text format. This suggests that some kind of binary-to-text encoding have been applied.
  2. The messages seems to be formatted in Base64 because the content resembles a ASCII string and ends with two == symbols.

Let’s check if the messages are indeed Base64. Using regular expression (RegEx) we can determine that the text could have been a Base64 value. However, even if the message passes the RegEx, this does not mean that the decoded content is valid encrypted content. That’s the beauty of encryption! If we assume that it’s encrypted using modern algorithms, we can’t really know for sure that the file is encrypted because it should look randomized.

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

We can confirm that each of the four messages are a full match with the RegEx above. Now we need to convert those Base64 encoded messages back to file.

Why? Because we need the original encrypted file to decrypt using the private keys. We can’t apply the private key directly to the Base64 encoded messages. You’ll get a error like:

RSA operation error
19200:error:0406506C:rsa routines:rsa_ossl_private_decrypt:data greater than mod len:crypto\rsa\rsa_ossl.c:401:

The private key should be applied to the output that was generated during the encryption process and not on the Base64 encoded version of it.

Just some additional information…

There’s a lot of ways to do this but since I’m primarily on Windows, I’ll do this with PowerShell. The following script need two variables: $path and $message. The $path variable is where the output of the file will be exported. The $message variable contains the Base64 encoded message. Both variables will be passed into a FromBase64String function.

The FromBase64String method is designed to process a single string that contains all the data to be decoded. Converts the specified string, which encodes binary data as base-64 digits, to an equivalent 8-bit unsigned integer array.

Just some additional information…
$path = 'C:\Temp\encrypted1.bin'
$message = 'mLkcoaOGPIdIDUnoWdKd0rca66fMWE/bs0YUJWS9waiPrxJQr6KMbL2le/DYtDDKy+cl8EKj0Q1LL9duUpdhszFGYjC98j2tu38lnb3Im5aevhqqo7mds+ZuE2XNtzEJ2dXdSYzhZvzkT6bKKHfFnMr9+WQzUKG9IQiHxg0eBZRvQJFViTY/3aADE11GDs6S4dbvv4sT8MwQva1rGD/Q+d/kAU+av8pRaTlI1fRdESPtHHljkBev7s5fZRJGki1gtwNiInhmajA23x/oSPBTBPzMIR4K5/OIJ2tRCRDmAUvTETNloh6EpOz+vJR+RkbFv6rZIVaxV3yq1dIKYg54hQ=='
$bytes = [Convert]::FromBase64String($message)
[IO.File]::WriteAllBytes($path, $bytes)

We will execute this script four times, each time with a different encoded message. In the end, we will have 4 encrypted files that needs to be decrypted.

Private Keys

Now that we have our encoded messages sorted out, let’s go and take a look at the private keys. The private keys are bundled up in a single file looking like this:

-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----
-----BEGIN RSA PRIVATE KEY-----
***
-----END RSA PRIVATE KEY-----

This tells us that we are dealing with an RSA private key. We can confirm this by performing the following command in OpenSSL.

openssl rsa –noout –check –in $privateKey | openssl md5

The $privateKey variable is used in the “-in” parameter for the input of the private key. It expects a path to the private key file.

If OpenSSL outputs anything else than “RSA key ok” then the key is invalid. In this specific scenario, the private keys are all valid RSA private keys. I will post the private keys in the second page of this post since there are 10 private keys in the bundle. Now I am going to split up each segment into separate files.

Be sure to include —-BEGIN RSA PRIVATE KEY—- and —–END RSA PRIVATE KEY—– in the text when separating the private keys from the bundle.

Important!

This means that I end up with 10 files looking like this:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3qyBdDzhyyftmxd/FjRHbgtlRnMh8pcBHJVhUe9FNTRsftrF
+9sX2kSoGKSDpmbD0TMckwj8dpWRfVvA5f7xNcPzVlG7HX8FQeIcQjnTFhkWwuNa
LfGD4IXswc82vyYLdW6B5njEKi4I35CkGuOGRqohUuSeiXTlZ6ZaO5HYXZGJ7yCI
1/UGTl5IFuvdqpymqe55egSXN/XrH3Uym5p5Sqh/xtls51ZRl0hMIJZsMVQLb0nf
TrdXWCLfnlmElso5aA02+gi41Ax9c6AreRltXATDQGgFJR9qNs4SE4olJ95shJra
kBnQayNFGrNkDEX4uW48vJ4c2KzRQF1Ujr2irwIDAQABAoIBAGzPjT7Y1Vlp/IDy
HWcjSthqdyXS8v7RbXijQnhAXOhf4rimfWLSMDi3nhDUq4Rv6TZcLJVpKb1k30CL
yppZV1N3mnxO2gnS3SXRsQ9npE/DGM1JPfL/dvsLVqNqd402sRjEVHPkBa+66Rke
XCLLlf0H+9q+3v26grOApc1AOqOVppbYFez7m06RtFWJ2pz3jwk7t0gHYEaBf710
IVwWcLw9OnkX/xo/dwHoBOHfp+0UJ0W83F11Pp4GiE5DoFoS7FYIKa++RrRonJOB
UpgCzr+8yarlZaztCZk0cUS/ck1G9KkDQ4qE1ZG2Cnsd6TS2JlxEEGavQyjy4/Q1
U2IBk9ECgYEA85pb4NqiuCcM8E0ReRRX1yR9yoURJPsbFo2FTz4GNydefqzIovrN
uE5p47E44Y4dtiemcJ+sAntNiXDXriZkOE0QZe90ynHIdOcGpuvWK5A2LnMc82iS
sMv5vd8bzeWX0I/z9C3A/hzjJVSuKbysU9PHE4jhSjPKR+yVHcaY+CcCgYEA6gF7
3e5MByK6r3ZI7enDHrN4XoqtPh6PbmkGq/22LWFw2SeKD3nFTSIXQt+LopjR2Uwt
hAIwv+mvpLfQz59ud2fFhqkBokcf2pF179E9CCQLtM2vNeG3B/It6UE9QkDmGeGs
5hkfBJkXVJhRJl6aAuJjXE7lIvaxTb20gTFpzjkCgYAX0KRg1B8KT88FAxPNOX7o
6oldriqh6eaZCtbYi2DCLZggXDX1MP3BofDaMK415tXiw/eSlRmU2IcZA64iOWCc
3HPY81MAo6UMQLW2xeGXOq8BVYGkDjohDJ/qvxARzftMiXY5DewLK7nNIX0xWV+j
hlW1BDG6Nlv1MhzV319/CwKBgA+dO7uqS+5p9dUBaopdf8SLqyt7y2WKun1eirBt
RHuwtcv3pHG16WFlNfIjYnjeA5qhR6Q4VTJpEGxIS6me9MsI5JhArLg8ULbP3/O5
nX3ukc1lsBxDTGg+U6vty32hQPlXIqdT48r1wCXH6BpMU7B/lKuzI/z6Qwhx8Rpx
xqKZAoGBAJxwngBgwHMuDToAuypPgVx2Vpt5xbuY+Vwed+iiiV85OD4LzkO+yK08
C7mXTOAMzGWYpcEwx7JoxuV/SW45L5pMvoxVEtrVbwF3qAv/FiDivPW8Y8HNOQQb
/qjtTvKFOlajksvYvfZCZJo7nW/MVJE8qYBbNHtJOhMAHVXzZfeh
-----END RSA PRIVATE KEY-----

Solution

We have established that the messages are Base64 encoded and that they need to be converted back to their original encrypted files. Now we can perform decryption using one of the private keys. The following command is used to perform decryption using OpenSSL and RSA and it requires 3 variables.

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

The $encrypted variable is used in the “-in” parameter for the input of the encrypted file. It expects a path to the encrypted file.

The $output variable is used in the “-out” parameter for the output for the decrypted file. It expects a path to a decrypted file that will be generated.

The $privateKey variable is used in the “-inkey” parameter for the input of the private key. It expects a path to the private key file.

Remember that we had 4 encrypted files and 10 private keys in total? We have to match the corresponding private key to the encrypted file. If we are dealing with a large amount of encrypted files and private keys I would create a for-loop to try each key with each encrypted file. OpenSSL will generate an error when I use an incorrect private key such as:

Attempting to decrypt an encrypted file with an invalid private key with OpenSSL
RSA operation error
7640:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:crypto\rsa\rsa_pk1.c:251:
7640:error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed:crypto\rsa\rsa_ossl.c:491:

When OpenSSL doesn’t generate any errors then it managed to decrypt the encrypted file with the private key.

Successfully decrypted an encrypted file with the corresponding private key with OpenSSL
$encrypted = 'C:\Temp\encrypted1.bin'
$output = 'C:\Temp\output.file'
$privateKey = 'C:\Temp\key6.key'

openssl rsautl -decrypt -in $encrypted -out $output -inkey $privateKey

Upon checking the output.file as specified in the $output variable we can find that it contains a message upon opening in Notepad.

Opening the decrypted file in Notepad results in a message for the player

We got lucky that it’s a text file! Since we don’t have any information regarding the file extension we would have to perform some kind of content analysis or reading the file header to determine what kind of file we are dealing with. And there we have it! There are many different ways to go about this. I just like the simplicity of OpenSSL and PowerShell.

Leave a Reply

Your email address will not be published.