Bypassing The Client Side Encryption To Read Internal Windows Server Files
Hey, once again it's me abhishekmorla,
This blog is about how one can break the client-side encryption with source code analysis and can able to read internal windows server files ie LFI, but after bypassing a layer of encryption.
So, I came up with a program let's say sub.domain.com and the credentials are provided in the scope.
During the login, I found that it was encrypting the username and password
and later on, decrypting the username to show into the front end.
after some googling, I got this beautiful blog by Sameer Bhatt “https://bhattsameer.github.io/2021/01/01/client-side-encryption-bypass-part-1.html", after going through it.
Firstly capture the login request into the burp and I started to search the variables in the sources, if the application uses any client-side javascript function for encrypting the username and password, after searching for a few keywords, I came up with a function called encryptData() which uses CryptoJS.
and the application not just using plain encryption, they have implemented a key, iv, mode and padding according to the documentation of https://cryptojs.gitbook.io/
Now my main goal is to find the key, iv values so to successfully encrypt/decrypt our values, I started to dig more into the sources and then came up with another variable called keyframe, which was used in the decryption part. and that is the hardcoded secret key used for key and iv values
I was finally able to find that the key and iv values are nothing but CryptoJS.enc.Utf8.parse(“secret_key”).
I locally installed the npm package and build the same function used as in the source code,
const key = CryptoJS.enc.Utf8.parse("secret_key");
const iv1 = CryptoJS.enc.Utf8.parse("secret_key");
const encrypted = CryptoJS.AES.encrypt("C://Windows//System32//drivers//etc//hosts", key, {
keySize: 16,
iv: iv1,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(encrypted+""); // will give the encrypted value
console.log("For decryption : ");
var cipher = "KSxIfH6RWYGA==";
const plainText = CryptoJS.AES.decrypt(cipher, key, {
keySize: 16,
iv: iv1,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(plainText.toString(CryptoJS.enc.Utf8)); // will give the decrypted value
In this way, we can able to decrypt and encrypt the values which are happening in the application.
and now the interesting part, One of my friend named “Akinlabi Omoogun” whom i was hunting in many different projects came up with an endpoint called “ViewDocumentFile” which has a path parameter that takes an encrypted value, after decrypting with our above JS file, it was found that it is a path of a png that is D:\\website\\logo.png,
We googled for some windows based LFI payloads and got C://Windows//System32//drivers//etc//hosts, did the encryption and passed it into the path parameter and boom we can able to read internal files just by breaking some encryption.
and that's how reading JS files are an important part of the testing. (a lesson I got from a security conference).
thanks for reading!
LinkedIn: https://www.linkedin.com/in/abhishekmorla/
twitter : https://twitter.com/abhishekmorla