Monthly Archives: February 2021

Pentesting Electron Applications

I recently came across my first Electron application as a target. As is the case I try and take notes as I go and here they are so that I am ready for the next time.

When you are targeting an “app” (various thick client or mobile application targets) I always want to:

  • Decompile it if possible – to enable source code review
  • Modify and recompile if possible – to enable me to add additional debugging to code or circumvent any client side controls.
  • Configure middling of communication channels – to enable testing of the server side API.

That is the general process for this kind of task and the blog post covers how to do all of these for Electron applications.

Extracting .asar Files on Windows

When going to the application’s folder I found that it had a “resources” directory containing a couple of “.asar” files. A quick google uncovered that this is a tar like archive format as per the link below:

This is similar to APKs in the Android app testing realm. To get serious we need to extract these to have a proper look.

First get NodeJs:

After installing this open a new command prompt and type “npm” to check that you have the Node Package Manager working right.

Then install “asar”

npm install --engine-strict asar

As a new user of npm I want to just marvel at the pretty colours for a second:

Oh NPM, you are gorgeous

Also an inbuilt check for vulnerabilities? NPM you are crushing it.. Just crushing it. So how come so many apps have outdated dependencies?

Turns out the above command – while gorgeous – did not stick the “asar” command into the windows path as intended. To do that I subsequently ran this command:

npm install -g asar

Then it was found the command in the path:

Oh asar, I found you, I never knew I needed you 10 minutes ago

I was unclear as to the operation of asar. Specifically, would this extract into the folder in a messy way? In the doubt I created a new folder “app” and copied my target “app.asar” file into that before extracting it:

mkdir app
copy app.asar app
asar e app.asar . 
del app.asar 

Note: that del is important because it stops you packing a massive file back into your modified version later.

I was glad I did copy the target into a folder because extraction did this:

Files Extracted to the Current Directory

Had I done the extraction a directory higher then the target application folder would have been messy.

With access to the source you can go looking for vulnerabilities in the code. I cannot really cover that for you since it will depend on your target.

Modifying the app

If you are half way serious about finding vulnerabilities you will need to modify that source and incorporate your changes when running the target. You need to modify the code and then re-pack the “app.asar” file back.

The best place to start is where the code begins its execution. That is in the “main.js” file within the “createWindow” function as shown:

Showing the createWindow function

I modified this to add a new debugging line as shown:

Added console.log debugging line

The point of this was to tell me that my modified version was running instead of the original. I started a command prompt in the “resources” folder and then executed these commands:

move app.asar app-original.asar
asar pack app app.asar

Note: that move command was about ensuring I have the original “app.asar” on tap if I needed to revert back to it. The pack command would otherwise overwrite the original file.

It turns out that “console.log” writes to stdout which means you can see the output if you run the target application from the command prompt. I prefer to create a .bat file for so that I can view stdout, and stderr easily in a temporary cmd window.

The contents of my bat file were:

target.exe
pause

The first line ran the target exe, and the second ensured that the cmd window would stay open in the event of the target being closed or crashing (until a key is pressed). I saved this in the folder with “target.exe” and called it “run.bat”. Instead of clicking on the exe I just double clicked on run.bat and got access to all of the debugging output.

Much success the first line of output when I load the application was now:

[*] Injecting in here

You can now see if there are any client side controls you can disable.

Allow Burp Suite to proxy the application

You will want to be able to see the HTTP/HTTPS requests issued by your target application. To do that you need to add an electron command line argument. If we look again at the “createWindow” function you can see two examples already:

This image has an empty alt attribute; its file name is image-9.png
createWindow function showing commandLine.appendSwitch

At line number 58 I added this switch which configured localhost port 8080 as the HTTP and HTTPS proxy:

electron_1.app.commandLine.appendSwitch('proxy-server', '127.0.0.1:8080');

Again I had to pack the app folder into app.asar as shown in the previous section.

Electron loads chromium and therefore you will need to install burp’s CA certificate as per this URL:

Once you have done that you should see all the juicy HTTP/HTTPS traffic going into burp.

Congratulations you can now go after the server side requests.

I have covered extracting the Electron application to let you see the code, how to modify the code, and how to middle the traffic. That is more than enough to get going with.

Happy hunting

Verifying Insecure SSL/TLS protocols are enabled

If a vulnerability scanner tells you that a website supports an insecure SSL/TLS protocol it is still on you to verify that this is true. While it is becoming rarer, there are HTTPS services which allow a connection over an insecure protocol. However, if you issue an HTTP request it will respond to the user with a message like “Weak cryptography was in use!”.

I think this was an older IIS trait. But I am paranoid and in the habit of making damn sure that a service which offers say SSLv3 will actually handle HTTP requests over it. If there is a warning about poor cryptography then the chances are a user won’t be submitting passwords which will reduce the risk.

This blog post explains how to use openssl to connect using specific SSL/TLS protocols. It also provides a solution to a major gotcha of the process; the version of openssl that ships with your OS cannot issue insecure connections.

Using openssl to connect with an old protocol

The best way to do this, for me, is to use “openssl s_client” to connect to the service. The command supports the flags “-ssl2” “-ssl3” and “-tls1” to enable you to confirm those respectively. Say you want to verify SSL3 is enabled on a target you would do this:

openssl s_client -connect <host>:<port> -ssl3 -quiet

If the server supports the protocol it will now say this the line above where your cursor landed:

verify return:1

Your cursor will be paused there because you have established an SSL/TLS connection and now it is waiting for you to enter data.

Issuing an HTTP request through that connection

Having established your connection you will want to issue an HTTP request. A simple GET request should be sufficient:

GET / HTTP/1.1
Host: <host>

This simple request will return the homepage of any HTTP server. The subtle part is that there are invisible newline characters. In truth the above can be expressed in a single line as:

GET / HTTP/1.1\r\nHost: <host>\r\n\r\n

Here a pair of “\r\n” is representing the newlines. The exchange ends with “\r\n\r\n” because HTTP wants a blank line after all the headers are done to indicate when the server should start responding.

To be easier we can use “printf” to issue the GET request directly through our openssl connection:

printf "GET / HTTP/1.1\r\nHost: <host>\r\n\r\n" | openssl s_client -connect <host>:<port> -ssl3 -quiet

If the server responds without warning the user about insecure cryptography then you have just confirmed it as vulnerable.

Major Caveat

Most operating systems rightly ship with secured versions of “openssl”. This means that they have been compiled to not support these insecure protocols. The reason for doing this is to protect users from exploitation! This is good for us. If fewer clients can even talk SSLv3 then how much more unlikely is it that exploitation will occur?

To solve this problem I suggest you compile a version of openssl which has been compiled to support insecure versions:

wget https://openssl.org/source/openssl-1.0.2k.tar.gz
tar -xvf openssl-1.0.2k.tar.gz
cd openssl-1.0.2k
./config --prefix=`pwd`/local --openssldir=/usr/lib/ssl enable-ssl2 enable-ssl3 enable-tls1 no-shared
make depend
make
make -i install

Doing it this way creates a local binary (in “openssl-1.0.2k/local/bin”) for you which is not then installed over the system’s maintained one. This keeps your every day “openssl” command in your path secure while giving you the opportunity to confirm vulnerable services.

This solution is adapted from the Gist available here:

For ease I choose to then create an alias for the command as shown below:

alias "openssl-insecure"="/<path>/<to>/openssl-1.0.2k/local/bin/openssl"

I can now call the insecure version by using “openssl-<tab>” to complete with insecure.

Happy insecure protocol verifications to you all.