Skip to content

Instantly share code, notes, and snippets.

@NtTestAlert
Created March 21, 2023 01:22
Show Gist options
  • Save NtTestAlert/3a9d8ee9f92376651f56f331e0ba052b to your computer and use it in GitHub Desktop.
Save NtTestAlert/3a9d8ee9f92376651f56f331e0ba052b to your computer and use it in GitHub Desktop.
IntelliJ Forgotten master key
// @ts-expect-error
import * as dpapi from 'win-dpapi';
import crypto from 'node:crypto';
import fs from 'node:fs/promises';
function rot13(txt:string) {
return txt.replace(/[a-z]/gi, c =>
"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
[ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".indexOf(c) ] );
}
const builtInEncryptionKey = Buffer.from(rot13('HUWirUxtD29hMzyaVSAyLj=='), 'base64');
function decryptAes(encrypted: Buffer) {
const ivLen = encrypted.readUInt32BE();
const iv = encrypted.slice(4, ivLen + 4);
const data = encrypted.slice(ivLen + 4);
const decipher = crypto.createDecipheriv(
'aes-128-cbc',
builtInEncryptionKey,
iv,
);
return decipher.update(data, undefined, 'utf8') + decipher.final('utf8');
}
function decryptSecret(secret: string) {
const secretBin = Buffer.from(secret, 'base64');
return dpapi.unprotectData(secretBin, null, 'LocalMachine') as Buffer;
}
async function getDirectories(path: string) {
const found = [];
for (const file of await fs.readdir(path)) {
if ((await fs.stat(`${path}${file}`)).isDirectory())
found.push(`${path}${file}`);
}
return found;
}
async function fileExists(filename: string) {
try {
await fs.access(filename);
return true;
} catch (err: any) {
if (err.code === 'ENOENT') {
return 'File does not exist';
}
return `Error reading file: ${err.code}`;
}
}
const appDir = `${process.env.APPDATA}\\JetBrains\\`;
getDirectories(appDir).then(async (apps) => {
for (const app of apps) {
if (app.endsWith('consentOptions')) continue;
const appName = app.slice(appDir.length);
const exists = await fileExists(`${app}\\c.pwd`);
if (exists !== true) {
console.error(`${appName}: c.pwd does not exist : ${exists}`);
continue;
}
let secret = '';
try {
const fileData = await fs.readFile(`${app}\\c.pwd`, 'utf8');
const metaData = Object.fromEntries(
fileData
.split('\n')
.map((line) => line.split(':').map((x) => x.trim())),
);
if (metaData.encryption !== 'CRYPT_32') {
console.error(
`${appName}: unknown encryption type : ${metaData.encryption}`,
);
continue;
}
secret = metaData.value.split(' ')[1];
} catch (err) {
console.error(`${appName}: Error reading c.pwd`, err);
continue;
}
try {
console.log(`${appName} decrypted : ${decryptAes(decryptSecret(secret))}`);
} catch (err) {
console.error(`${appName}: Error decrypting secret`, err);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment