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.