Reverse Electron Apps – EverSecMeet at BSidesRDU

During the BSidesRDU CTF, there was a challenge to reverse Electron apps.

Reverse Electron Apps – Introduction

If you haven’t read the rest of my challenge solutions, then you can find them here.

I have never reversed Electron apps before, so I figured that this was a good challenge to cover. This will be the last write-up I have planned for this CTF, but please let me know if you want to see any more.

The Challenge

First, I downloaded the application and opened it up.

Reverse Electron Apps - EverSecMeet

As nothing showed up when I opened the app, I verified that it was a real application.

[email protected]:~/Downloads$ file EversecMeet.app/
EversecMeet.app/: directory

Flags in Files

First, I looked at the Info.plist file. This is a great place to find out the configuration of the application, as well as a flag.

[email protected]:~/Downloads/EversecMeet.app/Contents$ cat Info.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>BuildMachineOSBuild</key>
    <string>16G1314</string>
    <key>CFBundleDisplayName</key>
    <string>EversecMeet</string>
    <key>CFBundleExecutable</key>
    <string>EversecMeet</string>
    <key>CFBundleIconFile</key>
    <string>EversecMeet.icns</string>
    <key>CFBundleIdentifier</key>
    <string>com.example.eversec-meet</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>EversecMeet</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.0</string>
    <key>CFBundleVersion</key>
    <string>1.0.0</string>
    <key>DTSDKBuild</key>
    <string>14D125</string>
    <key>DTSDKName</key>
    <string>macosx10.1010.10</string>
    <key>DTXcode</key>
    <string>0833</string>
    <key>DTXcodeBuild</key>
    <string>8E3004b</string>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.developer-tools</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.9.0</string>
    <key>NSHighResolutionCapable</key>
    <true/>
    <key>NSMainNibFile</key>
    <string>MainMenu</string>
    <key>NSPrincipalClass</key>
    <string>AtomApplication</string>
    <key>NSSupportsAutomaticGraphicsSwitching</key>
    <true/>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright © 2019 L3g10n0fGl00m</string>
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSAllowsLocalNetworking</key>
      <true/>
      <key>NSAllowsArbitraryLoads</key>
      <true/>
      <key>NSExceptionDomains</key>
      <dict>
        <key>localhost</key>
        <dict>
          <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
          <false/>
          <key>NSIncludesSubdomains</key>
          <false/>
          <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
          <true/>
          <key>NSTemporaryExceptionMinimumTLSVersion</key>
          <string>1.0</string>
          <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
          <false/>
        </dict>
        <key>127.0.0.1</key>
        <dict>
          <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
          <false/>
          <key>NSIncludesSubdomains</key>
          <false/>
          <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
          <true/>
          <key>NSTemporaryExceptionMinimumTLSVersion</key>
          <string>1.0</string>
          <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
          <false/>
        </dict>
      </dict>
    </dict>
    <key>AsarIntegrity</key>
    <string>{"checksums":{"app.asar":"9nGtLwk16ZHszrAJ88xeoA7GOre74/tT24MMqtQwIgANzNbwWuF79Kg2Po0YLf7gbtE8tpAkDnPD1hC5YeBJuw==","electron.asar":"cm4p5+pXbc/NRAnZW0jLa81nmCebgLZ9w5dd56x+QStlThDLizHsuP+se3mZ9cYqbCk2FaGLScsEY0Xu9Q495A=="}}</string>
  </dict>
</plist>

Next, I looked at the frameworks in use, and identified that it was Electron.

[email protected]:~/Downloads/EversecMeet.app/Contents$ ls Frameworks/
Electron Framework.framework/ EversecMeet Helper NP.app/    Mantle.framework/             Squirrel.framework/
EversecMeet Helper EH.app/    EversecMeet Helper.app/       ReactiveCocoa.framework/

Reverse Electron Apps – asar

To reverse the application, I first installed asar.

[email protected]:~/Downloads/EversecMeet.app/Contents$ npm install -g asar
/usr/local/bin/asar -> /usr/local/lib/node_modules/asar/bin/asar.js
+ [email protected]
added 21 packages from 9 contributors in 2.174s

For another example of reversing Electron apps, I recommend this post.

Next, I extracted the application into my eversecmeet directory.

[email protected]:~/Downloads/EversecMeet.app/Contents/Resources$ mkdir eversecmeet
[email protected]:~/Downloads/EversecMeet.app/Contents$ asar extract app.asar eversecmeet/

The next flag was in the package.json file.

[email protected]:~/Downloads/EversecMeet.app/Contents/Resources/eversecmeet$ cat package.json 
{
  "name": "eversec-meet",
  "productName": "EversecMeet",
  "description": "Fake Eversec meeting updater",
  "version": "1.0.0",
  "private": true,
  "author": "L3g10n0fGl00m",
  "copyright": "© 2017, Gumby inc.",
  "main": "app/background.js",
  "dependencies": {
    "fs-jetpack": "^2.1.0"
  }
}

When I looked at the application’s resources, I found another flag in the main app.html file, inside of a hidden div that we couldn’t see when we opened it initially.

[email protected]:~/Downloads/EversecMeet.app/Contents/Resources/$ cat app.html 
<html>

<head>


... <snip> ...


<div id="loaded" class="" style="display:none;">
  <center>
    <h3> Success!</h3>
    <p>Eversec Meet has been updated! </p>
    <span style="visibility:hidden;">[email protected]</span>
  </center>
</div>
<script>
  var loader = document.getElementById("loading");
  var loaded = document.getElementById("loaded");
  setTimeout(function () {
    loader.style.display = 'none';
    loaded.style.display = 'block';
  }, 3000)

</script>

</html>

Legion.html

The final interesting file in resources was legion.html, which you can find below.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Legion</title>
  <style>
    body {
      margin: 0;
    }
  </style>
</head>

<body>
<script>
  var a=['fromCharCode','fa4ae513eecd8d3455d328cba83de7b6','VCU5OCVBMyVENyVEOSVBMjclRTIlOTQlRUYlOUUlQTY=','length','charCodeAt','charAt','replace','indexOf'];xyz=console.log;(function(c,d){var e=function(f){while(--f){c['push'](c['shift']());}};e(++d);}(a,0xeb));var b=function(c,d){c=c-0x0;var e=a[c];return e;};var c1;var xPcKu=function(c,d){var e=[],f=0x0,g,h='';for(var i=0x0;i<0x100;i++){e[i]=i;}for(i=0x0;i<0x100;i++){f=(f+e[i]+c['charCodeAt'](i%c[b('0x0')]))%0x100;g=e[i];e[i]=e[f];e[f]=g;}i=0x0;f=0x0;for(var j=0x0;j<d['length'];j++){i=(i+0x1)%0x100;f=(f+e[i])%0x100;g=e[i];e[i]=e[f];e[f]=g;h+=String['fromCharCode'](d[b('0x1')](j)^e[(e[i]+e[f])%0x100]);}return h;};var c3;var c2;var keyStr='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';function encode(k){k=escape(k);var l,m,n,o,p,q='',r='',s='',t=0x0;do{n=(l=k[b('0x1')](t++))>>0x2,o=(0x3&l)<<0x4|(m=k[b('0x1')](t++))>>0x4,p=(0xf&m)<<0x2|(r=k[b('0x1')](t++))>>0x6,s=0x3f&r,isNaN(m)?p=s=0x40:isNaN(r)&&(s=0x40),q=q+keyStr[b('0x2')](n)+keyStr[b('0x2')](o)+keyStr[b('0x2')](p)+keyStr[b('0x2')](s),l=m=r='',n=o=p=s='';}while(t<k[b('0x0')]);return q;}function decode(u){var v,w,x,y,z='',A='',B='',C=0x0;u=u[b('0x3')](/[^A-Za-z0-9\+\/\=]/g,'');do{v=keyStr[b('0x4')](u[b('0x2')](C++))<<0x2|(x=keyStr[b('0x4')](u[b('0x2')](C++)))>>0x4,w=(0xf&x)<<0x4|(y=keyStr[b('0x4')](u[b('0x2')](C++)))>>0x2,A=(0x3&y)<<0x6|(B=keyStr['indexOf'](u[b('0x2')](C++))),z+=String['fromCharCode'](v),0x40!=y&&(z+=String[b('0x5')](w)),0x40!=B&&(z+=String[b('0x5')](A)),v=w=A='',x=y=B='';}while(C<u['length']);return unescape(z);}var gGltY=xPcKu(b('0x6'),decode(b('0x7')));xyz(gGltY);
</script>
</body>

</html>

This looked like a moderately complicated and obfuscated encryption problem.

That said, if you look, it actually performs a console.log (xyz method) at the very end. When you open this file in a browser, the console prints the final flag without any extra work!

Reverse Electron Apps - Legion.html

I am not sure if this was an oversight or indented to be an easier challenge. That said, I submitted the last flag, and was done trying out challenges!

Reverse Electron Apps – Conclusion

This was a fun challenge to solve, and something that I had never done before.

If you know another way to reverse electron apps, then definitely let me know.

I have no more BSidesRDU write-ups to post, but I have some older CTFs that I might go through again soon.

One comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM