banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

Record of an autodecode AES decryption penetration test

Recently tested several sites, starting with a login box. After capturing packets, the username and password were encrypted, formatted as follows:

Pasted image 20241129200536

AES is commonly used for front-end encryption, and I have also encountered cases where the AES key is first encrypted using RSA, and then AES is used to encrypt the transmitted data.

The above image is a case of directly using AES encryption.

We can find the encrypted JS file through the browser, usually located in the source code/source under the JS directory. This website is relatively simple and directly uses the crypto-js.js file, which can be opened to see the AES key and encryption method.

Pasted image 20241129200734

As shown in the image above, we can see that the key is provided, the mode is ECB, and the pad is Pkcs7. With these elements, we can proceed to decrypt the data.

Using the autodecoder plugin from Burp Suite, this decryption also utilized this plugin.

Pasted image 20241129201305

AutoDecoder has four tabs.

Pasted image 20241129201504

The first options tab contains some settings.

  • Module Control: Specify which Burp modules to run autodecoder encryption/decryption on.
  • Encryption/Decryption Options: Control the method of encryption/decryption, whether to use built-in algorithms or interface-based encryption/decryption.

Pasted image 20241129201749

The subsequent options pertain to the first option. For example, if I choose interface-based encryption/decryption, I can set options for processing the data header or different encryption/decryption for request and response.

  • Encryption/Decryption Settings: It is important to fill in the encryption/decryption domain; otherwise, the autodecoder tab will not display. The other settings can be left as default.
  • After setting, be sure to save.

The second tab is for built-in algorithm encryption/decryption.

Pasted image 20241129202124

The third tab is for interface-based encryption/decryption.

You need to set the interface, and you can refer to the author's provided interface. If you need to customize some request parameters, most of the time you will need to use interface-based encryption/decryption.

Pasted image 20241129202150

In this case, there are two parameters, and using the built-in algorithm for encryption/decryption does not quite meet the requirements.

Pasted image 20241129200536

The built-in algorithm for encryption/decryption has a regex pattern match that can only match one encrypted string (name), making it impossible to extract the encrypted string for the pwd parameter.

The fourth tab is for request/response replacement.

It can be used to test some authorization vulnerabilities, and it feels similar to Burp's Autorize plugin, which I have not used.

Pasted image 20241129202217

This is a brief introduction to the autodecoder plugin.

I modified the author's script to adapt it to the current testing site.

from flask import Flask, request
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64
from urllib.parse import parse_qs,quote
import hashlib

def aes_encrypt(key, data):
    cipher = AES.new(key, AES.MODE_ECB)
    padded_data = pad(data.encode(), AES.block_size)
    cipher_text = cipher.encrypt(padded_data)
    return base64.b64encode(cipher_text).decode()

def aes_decrypt(key, data):
    cipher = AES.new(key, AES.MODE_ECB)
    decrypted_data = cipher.decrypt(base64.b64decode(data))
    unpadded_data = unpad(decrypted_data, AES.block_size)
    return unpadded_data.decode()

app = Flask(__name__)

@app.route('/encode', methods=["POST"])
def encrypt():
    key = b'write aes key here'  # 16 bytes key
    str1 = '123'
    param = request.form.get('dataBody')  # Get POST parameter
    md5value = param + str1
    param1 =  quote(aes_encrypt(key,param))
    param2 = hashlib.md5(md5value.encode()).hexdigest()
    return f"Param={param1}&Autograph={param2}"
    '''
    data = json.loads(param)
    encrypted_id = aes_encrypt(key, data["id"])
    encry_param = param.replace(data["id"], encrypted_id)
    return base64.b64decode(encry_param.encode()).decode()
    '''

@app.route('/decode', methods=["POST"])
def decrypt():
    key = b'write aes key here'
    param = request.form.get('dataBody')
    print('param: ',param)
    parsed_params = parse_qs(param)
    print(parsed_params)
    
    # Decrypt two parameters, namely name and pwd
    decrypted_name = aes_decrypt(key, parsed_params["name"][0])
    decrypted_value = aes_decrypt(key, parsed_params["pwd"][0])
    
    # Return a JSON response containing both parameters
    return f"name={decrypted_name}&pwd={decrypted_value}"

if __name__ == '__main__':
    app.debug = True  # Set debug mode, remember to turn it off in production
    app.run(host="0.0.0.0", port=8888)

After writing the script, run it, and the program will listen on 127.0.0.1:8888.

python3 aed_decode.py

You can first capture a packet for testing and see that it successfully decrypted.

Pasted image 20241129203021

Current settings are as follows:

Pasted image 20241129203246

Pasted image 20241129203422

Once the settings are complete, you can see that each request will automatically decrypt, and the decrypted content can be viewed in the autoDecoder tab.

Pasted image 20241129203459

You can also start using Burp's intruder module for login brute-forcing.

Here, I also recommend a front-end encryption practice target, which includes testing scenarios for asymmetric encryption, symmetric encryption, signing, and replay prevention, such as AES, DES, RSA, for penetration testing practice.

Target address: https://github.com/SwagXz/encrypt-labs/tree/main

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.