Recently tested several sites, starting with a login box. After capturing the packets, the username and password were encrypted, formatted as follows:
AES is commonly used for front-end encryption. I have also encountered cases where the AES key is first encrypted using RSA, and then the data is encrypted for transmission using AES.
The above image is a case of direct AES encryption.
We can find the encrypted JS file through the browser, usually located in the source code/source under the JS directory. This site is relatively simple and directly uses the crypto-js.js file, which can be opened to see the AES key and encryption method.
From the above image, we can see that the key is provided, the mode is ECB, and the padding is Pkcs7. With these elements, we can proceed to decrypt the data.
Using the autodecoder plugin from Burp Suite, this decryption also utilizes this plugin.
AutoDecoder has four tabs.
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.
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 domain; otherwise, the autodecoder tab will not display. The others can be left as default.
- After setting, be sure to
save
.
The second tab is for built-in algorithm encryption/decryption.
The third tab is for interface-based encryption/decryption.
You need to set the interface, and the interface can refer to what the author provided. If you need to customize some request parameters, most of the time, you will need to use interface-based encryption/decryption.
In this case, there are two parameters, and using the built-in algorithm for encryption/decryption does not quite meet the requirements.
The built-in algorithm for encryption/decryption has a regex pattern match that can only match one encrypted string (name), so it cannot extract the encrypted string for the pwd parameter.
The fourth tab is for request/response replacement.
This can be used to test some authorization vulnerabilities, similar to Burp's Autorize plugin, which I have not used.
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, 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)
Once the script is ready, run it, and the program will listen on 127.0.0.1:8888.
python3 aed_decode.py
You can capture a packet for testing, and you will see that it successfully decrypted.
Current settings are as follows:
After completing the settings, you can see that each request will automatically decrypt, and the decrypted content can be viewed in the autoDecoder tab.
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 test scenarios for asymmetric encryption, symmetric encryption, signing, and replay prevention, such as AES, DES, and RSA, for penetration testing practice.
Target address: https://github.com/SwagXz/encrypt-labs/tree/main