Nov 2, 2025

Case Analysis of Encryption and Decryption Data Packets: Practical Implementation of AES Encryption and Signature Verification (Part 1)

Simple AES Encryption + Signature

Simple AES encryption, where the IV, key, and mode are directly written on the frontend, is the easiest approach. You can export the mini-program source code using the tools mentioned above and easily open and search using vscode. Both Yakit's hot-loading function or webuffz functions can elegantly handle encryption and decryption.

I’d like to share some recent cases I've encountered that involve built-in signature verification.

Below is a classic example of privilege escalation. The issue lies in the ID, but there is a timestamp and signature validation in place.

The key function for generating the signature is as follows:

The encryption function is as follows:

The signature format is essentially parameter + value + key + timestamp, and the decryption format is the same as above: key: e1c3xxxxxxd41666, iv: 0000000000000000, and AES in CBC mode.

Now that the format is known, what would be your next step in testing? Python script? Burp plugin? Or something else? I’d also like to learn your approach.

Here, let's demonstrate how convenient Yakit is.

Yakit’s hot-loading function, as detailed in the documentation, allows you to process the data packets before sending and reprocess the returned packets. Additionally, its powerful tag function can significantly help when constructing parameters, making the process more efficient.

Let's look at the effect: the key parameter for privilege escalation, id, is passed in directly using the default tag ({{int}}, which automatically fills in integers to brute-force). The timestamp can also be generated easily using the default fuzztag function with just one click. The key part here is the signature. Let's take a look at how the hot-loading function is constructed.

Here are two key functions: handle_sign and afterRequest.

handle_sign is a function that returns the hash value of a tag to generate the signature. It is a custom function we wrote. Initially, many might think the approach is to pass all the parameters into this function to generate the signature and then return it, but in fact, this hot-loading function can only take one input.

However, the good news is that its fuzzing capabilities are strong, and it can construct the signature when passing the parameters. The format for the hot-loading function is yak(handle|param). It works like a function, processing the data before sending the packet, which is perfect for handling the signature before sending the request.

afterRequest is an official function that allows you to process each response to a request. The official documentation actually recommends using mirrorHTTPFlow for this purpose, but in the interest of time, we’ll keep things simple. The rsp here refers to the HTTP response packet, which needs to extract the body, decrypt it, and then reassemble it. The poc and codec libraries can be found in the official documentation. The main goal here is to decrypt the encrypted data from the response, making it clear without needing to decrypt it manually.

// mirrorHTTPFlow allows processing each response, defined as func(req []byte, rsp []byte, params map[string]any) map[string]any
// The return value can be used as the parameters for the next request or extracted data. If you need to decrypt the response, this is the best place to do it.

This is how the hot-loading function is constructed. The button for writing the function appears at the top right of the data packet.

After debugging the hot-loading function, the effect is as follows: the Webfuzz page allows you to easily handle the signature and data decryption with just one click, successfully achieving privilege escalation and information leakage.

NPM Software Supply Chain Security Incident