0

I have set up MitmProxy with a Python script to intercept network responses from one domain, used by a Desktop App. However, when I start up the App, I get the following series of transactions

{
    "code": 200,
    "message": "Success",
    "data": {
        "key1": "<redacted>",
        "key2": "<redacted>",
        "key3": "<redacted>",
        "key4": "<redacted>",
        "key5": "<redacted>",
        "key6": true,
        "key7": "<redacted>",
        "key8": false,
        "defaultDesktopClient": "ngx",
        "rsaKey": "-----BEGIN PRIVATE KEY-----\nMIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQCgYbO2jeRzeQKE\n3+7zOQD3//oetD5KdXhaDqhg1tjBbgoRlRBaPMHjXn6KBAKNaQWw6Z3jcJKSVyNw\nOuJYYZv4Tl7+vfmV7Q8gycSLZF874KLgNOPxSBXBxVQ0npqcrlmxoRcj0Lq1ofUe\nc4t7zvmyFVtzpFAZxPprFDTAo8EzdKTkP8ECOPqG/EULexBwhu+WdgqfDoJbfsoP\nE1dGRDVLqFicEIDYsF5Jl3jT9x5gAD5DvLBcl4MPXlXvTDkNhtp/JeiAkZp6eCcJ\nAkK1+sP+LreJhqXT87MEr3ttjK3Ge+UbknSoagIhgKZGMAnt7kvnjp5XP8yuaraE\n021EWgW9AgMBAAECggEBAInNKNKz/BRTZxywI+mLkw+DO29iQxtK74vBiF8cesVI\nPRJ6V8CQ767ipCsF4wOJt0AYmnavZOCkSmjFz3FM/OxOukR7CpYNR7BObLewGDuk\neY3XI/tOipMhb4Z+uC3jiGGdHfrB/4rMi4YMlU5duiGPRDKKfeCGZPvYMrNKgFgq\nhfqlR0Vj5eXfnDdb0/mIihT02kUQSYAHWC0dedr0XBFsf828iLFvvhINa5Vk2q83\nnT7yJrDCqEZ4ibzMC3jamA/kVx+Mf7o9AbmNrZnsSa9vFTO42OuW1Gs251bab/p0\n0vq96ebO1d4pdE+pq+4OKZUfWNFMu7Toshg8KCmFegECgYEA2NMgpZz5VJtzbuLv\nGBlu51hT3pgpS/b4Q6MYokd9R4B0BN/rA4+/Y7qjez2iVB7vVcJ47HSCCROUrY69\nIx1KrA6ect74QpZjbvBRGQaNjBh/oFFZpEqYAYtZBKT72yqV4Ot5SQaV2zKZIesd\nkFeT/eUzeReorNggxn4yee2YPkECgYEAvVvkiIoDcyOsiuCBqYUgghgKaFswip2D\nemiSOsDddu/x2JgFMywBxl5GJvtWi2gEXhY/mj/ksxID50qXpk4wFY0WQMI72SNH\nnDKzCiwhj619GNyM20FKvqhuVqR6fywC5+csFsxCmuBlUatAB8SyabVR6GOimDSc\n4lZgyrlboH0CgYEAk07VNk8wgc/fG+3nvLrCw0AaMvezzt1qjCFJgi8JqUNXD1zF\nwTSvNeU+XmNgXsBpoB0wpIz/L4VzFHsOesXSzpRcB/T+O9cKlPuGTXdLQWv/gX7j\nZSAcp6fxgZtJVPxYuWehjgCAXVzB9u5StpcZf3xxfQqa2Vs44UIprvbB4UECgYEA\nriwtDC4uOCTzGxagDUZHfYIRaKWgA5AYlGpFPseRrUnNIVXLSqNKyqSCUG7UzwuR\nIN3ECOSGPvPuJTumO7ElZ11Lv6spE3Pw9UppBo1LHXYNX+XVpgLrdm1EeGt3xSu9\nTIOFOT8OcJjAeRtUnRCerr66JVAoCWozd7jN9QoDrp0CgYEAqGZp5uaX5lEhGtHi\nTEZBirY0XxI7EGyaI9urdwY2MKz8blfoULCWHYa3oygoSaaVEzG+GngL+gOCUMMr\nKvIrZ8N06jBgcdlR/leky/M4C97UNtkbF0yJ9TOXUIEWgC4H5LK4dfhchLX/vhAh\nyD49OggM1dOaT+XuTiN4D+4ypP4=\n-----END PRIVATE KEY-----",
        "aesKey": "NNl0wdhaQyuKtd/je17rCQbM3VWW2FEW9dHc5h6NVLR66V+ZpyXLYxbs2ZEVXrb7Xb79AifM+BZUG9LykNwRVlpMjBdWMyR6C7TZ5NM/nBxhtgWVlRFHVwnouj9/c3+iLIk6GUJQYzh3bXAlO7PNXWguuxZWc8VxnhZKaYWLhz3zByWCJ8LpckXCBupO7OUtR8kchBm689gUPrCzWb7xK4C5nzbxhotecXrL1WzFdZEZ39hNEWlRl9QIdnPpT8PuxiwDMXcVTCLmW8KxowNZMsGCVIBdLj72kurFKy+E47v8Nroy5rSEanMXYBxcxAPGc0+jGEmwKgu/D80vqYGBmA=="
    }
}

Now, subsequent responses are of the following form

{
    "code": 200,
    "message": "Success",
    "data": "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At5ADFB6EWqL5I4hWoMJSQ==",
    "encryptionEnabled": true
}

Now, I'm fairly certain that the value for data in second response is encrypted using AES, and that the AES key itself is encrypted using RSA key. I'm using the following snippet of code to decrypt the key, and then the data.

from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP, PKCS1_v1_5
import random
import json


with open('key_data.json') as f:
    js = json.load(f)


with open("data.json") as f:
    data_js = json.load(f)


raw_aes_key = bytes(js.get("data").get("aesKey"), "utf8")


rsa_key = RSA.importKey(bytes(js.get("data").get("rsaKey"), "utf8"))

cipher_rsa = PKCS1_OAEP.new(rsa_key)
session_key = cipher_rsa.decrypt(raw_aes_key)

But I'm getting the following error

Traceback (most recent call last):
  File ".\rsa_enc.py", line 21, in <module>
    session_key = cipher_rsa.decrypt(raw_aes_key)
  File "C:\Users\<username>\Desktop\Projects\mitm\venv\lib\site-packages\Crypto\Cipher\PKCS1_OAEP.py", line 167, in decrypt
    raise ValueError("Ciphertext with incorrect length.")
ValueError: Ciphertext with incorrect length.

I'm guessing this is because of incorrectly decrypted response. I have the following queries I need help with

  1. I've read this section in documentation of PyCryptoDome, and according to this, the Private Key itself encloses the session AES key. But I don't think that's the case with my code, because mitmproxy already decrypts the https packets. Is my hypothesis correct?

  2. What's the point of sending Private key as a response? Does it not go defeat the purpose of being Private?

  3. I've tried decrypting the data with AES key itself, but it gives the following error

ValueError: Incorrect AES key length (344 bytes)
  1. Is there a way to decrypt the aesKey with rsaKey in the response and verify if it has been decrypted correctly?

1 Answer 1

1

So, the first and most obvious problem here: the keys and data are all base64-encoded, and unless that's an artifact of the way you're displaying them, you'll need to base64-decode them rather than just treating the text as UTF-8-encoded data.

Now, that doesn't explain everything. For example, the AES key is way too long; even base64-decoded, it's 256 bytes, which is eight times the expected length of 256 bits (32 bytes). However, if you're correct that aesKey is itself encrypted using RSA, that makes sense; that's the expected ciphertext length for a 2048-bit RSA key. Indeed, we can decrypt aesKey with rsaKey, yielding 64 bytes of data. That's still too long to be an AES key by itself, but it might be an AES key + HMAC key, or similar...

EDIT: As @dave_thompson_085 points out, the 64 bytes - if interpreted as ASCII or UTF-8 - represent hex digits. Treating them as a string and hex-decoding that gives a 32-byte array, the correct size for AES-256.

The data you provided in your example is also base64 encoded, but it's actually two base64-encoded values concatenated (you can tell by the = signs, which are padding that only occur at the end of a base64 string): a long one, and a quite short one. The latter (16 bytes, after decoding) is probably either an IV (especially since it matches the AES block size), or a message authentication code.

Without knowing the purposes of the different data parts (the 64 bytes of decrypted aesKey) and the details of the cipher suite used (mode of operation, style of padding, etc.), it's difficult to say how the message is supposed to be decrypted. However, I think it's safe to say that it can be. After all, the proxy appears to be successfully reading the HTTP response codes (200). Additionally, it doesn't make any sense for the proxy to supply an RSA private key unless it was using that for the MitM, which implies the ability to read the message.

EDIT: Using the hex-decoded AES key from above as an AES-256 key, in CBC mode, with the 16-byte base64 decode from the end of data acting as the IV, and using PKCS #7 padding, it's possible to successfully decrypt the rest of the base64-decoded data. Without a message authentication code of some sort, we can't be sure that the data hasn't been tampered with, but it decrypts to syntactically-valid and human-readable JSON, and the padding validates, so it's probably correct unless it was modified by a very motivated attacker.

Perhaps you want to review the mitmproxy docs, and especially the Python API, to see what the expected format of all that JSON you're printing is. I'll be honest, it's not clear to me either, though.

4
  • Thank you for your prompt response. I have decoded the aesKey with base64 before decrypting it, and I have gotten a hexadecimal bytes object as an output. However, you are right still, it still raises an error saying ValueError: Incorrect AES key length (64 bytes) I've read that there is a mode in PyCryptoDome - Syntethic Initialization Vector (SIV) which takes in 64 bit keys. But that's raising a problem of its own, - missing MAC tag. How should I approach this now? Sep 22, 2021 at 15:44
  • 1
    RSA-OAEP decrypt using rsakey of aeskey gives 64 bytes all of which are hex digits, and treating that as an AES-256-CBC key in hex and the small final block of the data as IV in base64 applied to the large block of data in base64 gives plausible (at least syntactically correct) JSON that appears to be about some kind of gambling or casino operation. Sep 23, 2021 at 3:40
  • So it does. Wow, first encoding the key as hex, and then encrypting the hex string as UTF-8, and then encoding the ciphertext as base64... I guess I should have thought of that. Given that the padding (PKCS #7) is correct and the result appears both human- and machine-readable, I'm going to say that's the correct decryption.
    – CBHacking
    Sep 23, 2021 at 4:31
  • Thank you @dave_thompson_085 and CBHacking. :) You both helped me out a lot Sep 23, 2021 at 15:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .