Instrumentalizing Electron: Proxy Injection

29. Feb 2024, #electron #web #reverseengineering 

When analyzing Electron apps, an HTTP proxy can be very helpful. Most apps, however, do not offer a nice GUI option or CLI arguments to specify a proxy. In this case, you need to force the application into the proxy. This page is mainly a dump of stuff which I came across and is not super curated. I don’t know in all cases which ones worked and which ones did not. I’ve you have more detailed feedback or knowledge on those methods, feel free to contact me and I’ll update this list.

Unpack and Repack Asar #

You’ll need to unpack and repack the asar file found in your Electron directory. For this you can use the official asar↗ application or a simple Dockerfile if you don’t want to install npm on your system.

FROM node:21-alpine

RUN npm install --engine-strict -g asar

USER node

ENTRYPOINT ["asar"]
CMD ["-h"]
# build
docker build -t asar .

# bash function as a wrapper for the container
asar() {
    if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
        echo "Usage: \n  asar extract app.asar outdir\n  asar pack indir app.asar"
        return
    fi

    if [ "$1" = "extract" ]; then
        docker run --rm -v $(pwd):/src asar extract "/src/$2" "/src/$3"
        return
    fi

    if [ "$1" = "pack" ]; then
        docker run --rm -v $(pwd):/src asar pack "/src/$2" "/src/$3"
        return
    fi
}

Without Modifications #

The application maybe respects the environment variables http_proxy and http_proxy.

export http_proxy="http://127.0.0.1:8080"
export https_proxy="http://127.0.0.1:8080"
/path/to/app

Using proxychains↗ is sometimes also an option.

# install proxychains
# configure your http proxy in /etc/proxychains4.conf
proxychains -q /path/to/app

There is a Windows version of proxychains called proxychains-windows↗. This app only supports SOCKS5 proxies as a target. Using projectdiscovery/proxify↗ we can tunnel this into Burp. Install the certificate generated by Burp and proxify into the TrustStore before proceeding.

# launch proxify with a upstream http proxy
proxify -http-proxy http://127.0.0.1:8080

# adjust the proxychains config in %USERPROFILE%\.proxychains\proxychains.conf
# launch the app with proxychains
proxychains -q .\path\to\app

Environment Variables #

You can also set environment variables inside the JavaScript that gets launched via Electron. Again, respecting those is up to the app.

process.env.HTTP_PROXY = 'http://yourproxy:port';
process.env.HTTPS_PROXY = 'http://yourproxy:port';
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = '1';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

webContents.session.setProxy() #

Using BrowserWindow() it’s possible to set a proxy before the main loadURL() is called.

//BrowserWindow().loadURL(appUrl);

const proxyRule = "http=http://127.0.0.1:8081;https=http://127.0.0.1:8081";
BrowserWindow().webContents.session.setProxy({ proxyRules: proxyRule }, function () {
    BrowserWindow().loadURL(appUrl);
});

session.defaultSession.setProxy() #

Also, just after imports you can specify a proxy for the session and hook on app.on() to disable certificate checks.

const proxyRule = "http=http://127.0.0.1:8081;https=http://127.0.0.1:8081";
session.defaultSession.setProxy({ proxyRules: proxyRule });

// Ignore SSL certificate errors
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
    event.preventDefault();
    callback(true); 
});

DevTools #

Some programs show you a menu bar when pressing ALT. From there, Chrome DevTools can be enabled. Otherwise, add this to the source code.

// Open Devtools. Requires devTools: true in webPreferences
BrowserWindow().webContents.openDevTools({ mode: 'bottom' });
// Enable the menu bar which can toggle the dev tools
BrowserWindow().setMenuBarVisibility(true);

Inspect/Debug Mode #

Electron apps can be debugged using Google Chrome. For this, the app needs to be launched with --inspect or --inspect-brk. In earlier versions, those flags were called --debug and --debug-brk. Once launched, open a Google Chrome browser and visit chrome://inspect/#devices. There you should be able to connect to the debug instance over a websocket.