I have been doing the pentest of mobile and web applications and recently I found that many applications are implementing client-side encryption in both mobile and web applications. Earlier I hosted a simple Javascript-based AES encryption and decryption script on GitHub. The script allows me to encrypt and decrypt the parameter to continue testing. The script was created after I found that many applications use the CryptoJS library with AES CBC 256 or 128-bit encryption.
The same method could be applied by writing the same encryption logic as your application. As or alternative method we can use the browser console and breakpoint in web applications and JavaScript-based mobile applications.
The problem with the above method is you need to perform the encryption and decryption for each parameter or request again and again. This approach slows down the testing process and the time taken to complete the pentesting. Another problem is many time application is vulnerable and requires any type of automation to exploit it like OTP brute-force. If encryption is there it's not possible to perform any kind of automation.
A few months back I was pentesting a web application vulnerable to OTP brute force and due to encryption, I was not able to perform the brute force. I came up with the solution of writing a simple python script that will go through the text file with 4-digit OTP and will create a new text file with an encrypted version of the OTP. I could use the encrypted OTP to bypass the OTP. I create several burp extensions to perform the encryption especially to run automation like an intruder or SQLMAP.
The major problem was modifying the burp suite extension based on the parameter and encryption logic used by the application. Also, the one problem with manually decrypting and encrypting parameters is it takes a lot of time.
I came up with the idea of creating a new burp suite extension that works on all the applications and allows you to just provide the encryption and decryption logic and the extension will take care of everything whether is manual pentesting or automation.
I created an extension named PyCript that solves all the problems. The extension decrypts the encrypted parameters on the fly and allows you to modify the value in the plain text directly inside the burp suite. This solves the problem of manually encrypting and decrypting each parameter and request again and again and we can test the application as there is no encryption.
I also added functionality that allows running automation on plain text requests and the extension will take care of encryption. This solves the challenge of running the tools like SQLMAP, Intruder or Burp Scanner.
I have one of the applications I am working on and by intercepting the traffic I can confirm that the request is using some kind of client-side encryption.
The post body seems to have some kind of encryption and won’t allow us to perform any attacks on parameters. At this stage, I try to find out the encryption logic including key and iv from the Javascript code.
Using the browser dev tool and searching for some strings like aes,encrypt,cryptojs,secretkey,iv,padding
I can see the encryption logic.
The search result shows that it uses AES encryption using the CryptoJS library. The result shows that it has two different encryption codes. By clicking on both files I can verify that the encryption logic is the same for both.
As mentioned I have hosted the Cryptojs-based encryption decryption script on GitHub. Using the provided key and IV from the above code I can decrypt the request parameters.
Now I am able to confirm that I can decrypt the encrypted strings. Now I can use the same encryption logic to write the encryption and decryption script in PyCript format.
//Decryption
var CryptoJS = require("crypto-js");
const program = require("commander");
const {
Buffer
} = require('buffer');
program.option("-d, --data <data>", "Data to process").parse(process.argv);
const options = program.opts();
const requestbody = Buffer.from(options.data, 'base64').toString('utf8');
var key = CryptoJS.enc.Utf8.parse('8080808080808080');
var iv = CryptoJS.enc.Utf8.parse('8080808080808080');
var plainText = CryptoJS.AES.decrypt(requestbody, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(plainText.toString(CryptoJS.enc.Utf8))
//Encryption
var CryptoJS = require("crypto-js");
const program = require("commander");
const {
Buffer
} = require('buffer');
program.option("-d, --data <data>", "Data to process").parse(process.argv);
const options = program.opts();
const requestbody = Buffer.from(options.data, 'base64').toString('utf8');
var key = CryptoJS.enc.Utf8.parse('8080808080808080');
var iv = CryptoJS.enc.Utf8.parse('8080808080808080');
var encryptedclientDetail = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(requestbody), key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(encryptedclientDetail.toString())
Now I have the encryption and decryption script ready and I can use the script inside the PyCript extension to modify the traffic same as a normal application. In my case, the body is in JSON format and only the value is encrypted I can select the appropriate request type in the extension.
Now the setup is completed I can go back to the request in my burp suite and can see a new tab in the request section named PyCript and it shows the decrypted data. I can modify the data directly inside the tab and can send the modified request and the extension will take care of encryption for modified data.
The problem with the tab is in many cases you need to see the complete request, not just the body and also want to test the application like there is no encryption at all.
For the same, I can right-click on the request and select the Decrypt Request
from the PyCript.
Once I do that extension will store the decrypted request inside the table. I can send that request to the repeater intruder scanner etc to test the request the same as a normal app and it won't require me to edit the request from the PyCript tab. I can directly edit the request in the Raw or the pretty tab.
But since the extension will only encrypt the request if I modify the data from PyCript, not from Raw or Pretty tab. I can go back to the config tab within the PyCript extension.
I can turn on Auto Encrypt and select the tool in my case repeater I will select the repeater. This will allow the extension to encrypt the request and then send it to the server. I can now use the plain text request for scanners or intruders etc and the extension will handle the encryption in the background.
If I go back to the repeater tab. I can use the plain text request like there is no encryption at all and the extension will handle everything for me. If I want to run the SQLMAP I can give this plain text request to the SQLMAP. and can use the proxy option īnsde the SQLMAP to send all the requests to the burp proxy from the PyCript I can select the proxy for Auto Encrypt.
All the tools can be found below.
Twitter — https://twitter.com/ano_f_
GitHub — https://github.com/Anof-cyber/
Linkedin — https://www.linkedin.com/in/sourav-kalal/