Practical Use of Burpy Plugin – Cracking the Encryption Algorithm of a WeChat Mini Program

Author: 0pening

1. Introduction

Testing a certain WeChat mini program, without further ado, let’s start using BurpSuite to capture packets. However, upon capturing the packets, I noticed something was off 🤨.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

This application encrypts the parameters into bizContent and uses a signature parameter sign to prevent man-in-the-middle attacks on the data packets… not very honorable.

2. Analyzing the Data Packet

Let’s bravely analyze it and see if the signature parameter sign is validated. By reducing the parameters, it turns out to be a paper tiger. The parameters were simplified as follows, and the data packet could be sent normally.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

It turns out that sign is just a paper tiger, as there is no validation on the backend. So, is user identity verification done through openId? 🤔️

By modifying the openId parameter, I discovered a logical flaw.

Incorrect openId, verification failed.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

openId is empty, successfully returned data.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Deleted openId parameter, successfully returned data.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Since this is an interface requesting personal information, deleting or leaving openId empty still retrieves personal information. Therefore, there exists a parameter in bizContent that determines the user identity. If this identifier is predictable, it is highly likely that one can modify this identifier to gain unauthorized access to others’ identity information.

3. Cracking the Signature Algorithm

After the above analysis, the next step is to find a way to obtain the plaintext data of the bizContent parameter.

By checking the history records of BurpSuite’s data packets

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Searching the context yielded no relevant JS requests, so the encryption algorithm’s source code should be in the WeChat mini program’s source code.

  • The source files of WeChat mini programs are stored on WeChat’s servers after developers publish them. When users first load the mini program, it downloads the mini program to the user’s local device (****in *.wxapkg format as a binary file).

Extracting the .wxapkg file: (Android will place it in the following directory)

/data/data/com.tencent.mm/MicroMsg/{number_string}/appbrand/pkg/

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Decompiling the .wxapkg file to obtain the mini program’s source code (https://github.com/Cherrison/CrackMinApp)

This tool is used mainly because it does not require an additional node.js environment and can be used directly.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

By globally searching for the keyword bizContent, I found it in the app-service.js file. Beautifying the app-service.js makes it easier to read. I found the encryption and decryption algorithms.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Testing the AES decryption, it was successful, with two parameters being passed: one idcard and one desc for the request interface.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Then, by replacing the idcard parameter with someone else’s ID card, I called the interface to query and returned someone else’s information, proving unauthorized access.

4. Using the Burpy Plugin

After figuring out the encryption algorithm, testing can commence, but a problem arises: do I have to copy and paste the bizContent parameter and returned data every time to decrypt for testing? Is there a more elegant testing method?

I turned my attention to m0nst3r’s https://github.com/mr-m0nst3r/Burpy. It supports Python 3.

The usage tutorial is available in the blog:

https://m0nst3r.me/burpsuite/打通BurpSuite与Python之间的任督二脉.html

After loading the plugin, configure it as follows: (the plugin requires Pyro4 to be installed -> pip3 install Pyro4)

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

The collected AES-related encryption configurations are as follows:

783a2274472d5928 
iv = 0102030405060708 
Mode = ECB 
padding = Pkcs7

Write the AES encryption and decryption script. Just implement the encrypt and decrypt functions as required by the project.

import json 
import base64 
from Crypto.Cipher import AES 



class Burpy: 
    def __init__(self): 
        self.key = "783a2274472d5928" 
        self.iv = "0102030405060708" 
        self.apicode = "" 

    def encrypt(self, header, body): 
        # Get the encryption parameter bizContent 
        body_json = json.loads(body) 
        bizContent = json.dumps(body_json["bizContent"]).replace(' ', '') 

        # AES encryption 
        while len(bizContent) % 16 != 0:  # Pad the string length to a multiple of 16 
            bizContent += (16 - len(bizContent) % 16) * chr(16 - len(bizContent) % 16) 
        bizContent = str.encode(bizContent) 
        aes = AES.new(self.key, AES.MODE_ECB)  # Initialize the encryptor 
        bizContent  = str(base64.encodebytes(aes.encrypt(bizContent)), encoding='utf8').replace('\n', '') 

        # Replace parameters, set openId to empty to bypass 
        body_json["bizContent"] = bizContent 
        body_json["openId"] = '' 

        body = json.dumps(body_json) 
        return header, body 

    def decrypt(self, header, body): 
        cipher = AES.new(self.key, AES.MODE_ECB, self.iv) 
        # Get the encryption parameter bizContent 
        body_json = json.loads(body) 
        bizContent = body_json.get("bizContent") 

        # AES decryption 
        content = cipher.decrypt(base64.decodebytes(bytes(bizContent, encoding='utf8'))).decode("utf8") 
        content = content[:-ord(content[-1])] 
        body_json["bizContent"] = json.loads(content) 

        body = json.dumps(body_json) 
        return header, body

After loading the plugin, configure it as follows, checking the automatic encryption and decryption option.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Testing as follows, perfectly retrieving data, testing is much more elegant now!

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

In the Repeater, modify the data packet and send it in plaintext, the returned packet is automatically decrypted.

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Practical Use of Burpy Plugin - Cracking the Encryption Algorithm of a WeChat Mini Program

Leave a Comment