[Tools] Visual Recon – A beginners guide

📖Intro 📖

During the process of RECON you often get thousands of domains you have to look at. A suitable way to decrease the time you spend on each website is to take a screenshot of each website. There are several tools available such as EyeWitness (https://github.com/ChrisTruncer/EyeWitness) or ScreenShotter (https://github.com/BladeMight/ScreenShotter). Unfortunately, I had issues setting them up the way I wanted, so I created a little workflow which will use WebScreenshot, Aquatone and express-photo-gallery to quickly identify your attack-surface.

If you are into Recon and automation, you should definitely check out Nahamsec’s tool LazyRecon (https://github.com/nahamsec/lazyrecon/blob/master/lazyrecon.sh)

The way we will do it is to setup a virtual server, gather subdomains using aquatone-discover, scan the subdomains for open ports on 443 and 80 using aquatone-scan take a screenshot using WebScreenshot and finally create thumbnails using epg-prep and display them in a nice way using the node tool express-photo-gallery.

The following GIF shows the actual result, cool right?

💧Setting up a Digitalocean VPS💧:

For the Setup I am using a cheap VPS system from Digitalocean.

The easiest operating system for me was Ubuntu together with a 1GB of memory, one vCPU and 25GB of SSD Disk. This should be more than enough for the task.

For the region I always chose the one thats closest to my physical location to avoid latencies, (in my case Frankfurt is the closest location)


I like to add IPv6 support to my droplets to have a better coverage of IPv4 and IPv6 targets, for the authentication i use my SSH keys (who remembers Passwords anyways?)


So the first step after deploying your machine is to log in using SSH:

ssh root@yourip, after this you want to install all the following necessary tools (see bottom). After you’ve installed all the necessary tools we can go ahead and start our visual recon process. For this example we will be using the domain uber.com you can find their bug bounty program here: https://hackerone.com/uber.

To start we first run aquatone (https://github.com/michenriksen/aquatone/)  to identify potential subdomains, to do so: aquatone-discover -d uber.com , you should see an output similar to this:

once the script has finished enumerating the subdomains, we need to identify whether the subdomains have a web server running, while it is possible that there could be a webserver on a different port, for this blog we will only focus on the ones running on port 443 and 80. To do the actual scan we use the aquatone-scan, with  aquatone-scan -d uber.com -t 30 -p small (where -t is defining the Threads used, and -p is the amount of ports used, small does only look for port 80 and 443.)

Now that we have identified all the open ports of the assets we can now go ahead and run Webscreenshot. It is possible to create screenshots with Aquatone too (using aquatone-gather) however, I wasn’t able to set it up properly on a VPS system, as such I am doing this with WebScreenshot. To do so we use the command webscreenshot -i /root/aquatone/uber.com/urls.txt -o uber.com this command tells webscreenshot to grab the list of urls created by aquatone and take a screenshot of each available domain inside the uber.com folder

This will likely take  some time. If you have a unstable internet connection, I recommend running this in a so called screen session. Screen allows you to run a script in a separate process and lets you detach it and return to it again. To do so run screen -R uber and press str+a+d to detach from the window. To return you simply type screen -r uber.

Once this is done, we use a tool called epg-prep (https://www.npmjs.com/package/epg-prep) to create thumbnails to do so, simply run: epg-prep uber.com

This will allow us to view the created pictures using express-photo-gallery.

In a final step, use the express-gallery-script from the bottom of this blogpost and save it as yourname.js. All you need to do is to change the folder name inside the script: app.use('/photos', Gallery('uber.com', options)); the folder name in this case is set uber.com but depending on which target you look at it may be different. Once you’ve done that you can simply run the script using node yourname.js. This will create a webserver listening on Port 3000 with an endpoint  called /photos. So to access this you simply type: http://yourserverip:3000/photos to get a nice overview of the subdomains you have enumerated. You can easily switch the photos by pressing the left or right arrow on your keyboard. At the bottom you will see a summary of all the screenshots that have been taken.

The next section will include all the necessary tools and software used in this blogpost, it should be enough to simply copy + paste those in your SSH session.

System Tools

Requirements for WebScreenshot

Requirements for express-photo-gallery

Requirements for Aquatone

express-photo-gallery Script


Easy right?

🙂 If you have any problems, feel free to reach out on twitter (@itsecurityguard) or hit me up on Bug Bounty Forum (https://bugbountyforum.com/)

So long,



The Stony Path of Android 🤖 Bug Bounty – Bypassing Certificate Pinning

Dear readers,

Long story short, doing bug bounties for mobile devices is hard. With this article I want to show you a rather simple way to be able to bypass certificate pinning for all some of your Android mobile targets. The method described here is based on research and an awesome blogpost+script written by Piergiovanni Cipolloni. Whenever there was a bypass for certificate pinning it was always involving manipulating the SSLContext of the application. The researcher showed a way to invoke Frida and manipulate the SSLContext to build a script that is able to universally bypass  certificate pinning on Android.

In a nutshell the script works like this:

  1. It loads a rogue certificate from the file system (the CA Certificate of Burpsuite);
  2. It creates a very own KeyStore containing our trusted CA;
  3. In a final step it creates a TrustManager that trusts the CA in our KeyStore.

Whenever the application initializes its SSLContex, the Frida script hijacks the SSLContext.init() method and when it gets called, the 2nd parameter, which is the application TrustManager, with our own TrustManager we previously prepared. On Android the SSLContext function is called as follows:  SSLContext.init(KeyManager, TrustManager, SecuRandom)).

From a beginner’s perspective it is hard to get to the same point as Piergiovanni Cipolloni, therefore this blogpost will include a bit of an introduction to get everything setup properly.

The following blogpost will include:

  • How to install the Burp certificate to your device;
  • How to configure Burpsuite for mobile devices;
  • How to install Frida on your Android device;
  • How to run a remote Frida Server;
  • How to install Frida on your server;
  • How to invoke the script with your application.

Why Certificate Pinning?

With certificate pinning a developer ensures that their application does not accept fake certificates that are actually signed by an official certificate authority. The Android system itself only checks if the hierarchy of the certificate is correct and whether the CA (Certificate Authority) is listed in the so called „certificates of trust store“. But what happens if a malicious person installs a fake CA into the trust store? Well basically that person would be able to intercept the entire HTTPS traffic for the application. For this reason developers go a step further and compile the real certificate in the app and ensure that only this certificate can be used.


  • You’d need an Android Virtual Machine (or real device);
  • Some spare time;
  • ADB / Android Tools installed + configured.

The Setup – Part 1 Installing the Burp Certificate

With Burpsuite running go to your browser (default: and click on CA Certifcate.  

This will download a file called cacert.der, take the file and rename it to cacert.cer. If you are wondering what the difference here is, please visit this link: http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/. The short story is it is just an alternate form.

If you are on a Mac and your default download directory is Downloads you may do the following:

1.) cd /Downloads – This changes your directory to Downloads;

2.) mv cacert.der cacert.cer – This renames the certificate;

3.) adb push cacert.cer /mnt/sdcard/DCIM/ – This copies the certificate to the SD card of your device.

Not too hard right?

On the device itself (whether virtual or real) we have to install the certificate in order to put it into the Android trusted cert store.

To do so:

Click on the Menu Button – Go to Settings – Scroll all the way down to Security – Choose Install from SD card

Tap on the cacert.cer and name the certificate for example Burp.

If everything worked you should see under -> Settings -> Security -> Trusted credentials -> Users, the following entry:

🎉Hurray! 🎉 – You have now installed your own Certificate Authority to your system!

The Setup – Part 2 Configuring Burpsuite

Now that we have installed the PortSwigger (💗)  CA on our system we need to setup the proxy in order to intercept the traffic from the application the server.

Setting up your Android Device

Once again go to Settings -> Click on Wi-Fi -> Hold and Click WiredSSID -> Click on Modify Network -> Click on Proxy  -> Choose Manual.

You will be presented the following form:

What you need to fill out here:

Proxy Hostname – Is the IP Address of your Burp Suite Application (of your PC, your local IP Address).

Port – Is the Port you have Burp Suite running on (default is 8080).

Setting up Burp

Burp, by default opens a local Proxy running on localhost Port 8080, in order to intercept our mobile traffic we have to setup Burp to listen on the external IP address. Start Burpsuite and go to Proxy -> Options select the current configuration (as shown in the picture below) and click on Edit.

Now select the option Specific Address and choose your local IP address (in my case it is For you it can vary depending on how your DHCP server is assigning addresses.

If you are unsure which is your IP address, open up a terminal and type (on OSX) ifconfig en0 | grep inet.

If you’ve followed this tutorial to this point – 💪 You are now able to intercept traffic through the application without Certificate Pinning 💪! The next chapter will be about bypassing certificate pinning.

The Setup – Part 3 installing Frida on your Android Device

In order to bypass certificate pinning using this method we need to have a copy of Frida-Server installed on our Android device.  To do so, we need the latest version of  Frida-Server which can be downloaded from the Frida releases page on Github: https://github.com/frida/frida/releases, you now will wonder which version you need here…🤔 x86? x86_64? arm? – Thank god there is a command for everything! Just do adb shell getprop ro.product.cpu.abi to find out the right version for you, in my case it was x86. So for me the right version to choose was frida-server-10.6.15-android-x86.xz.  The experienced reader will notice that the .xz extension is an archive, before we can use the binary we have to extract it first. For the terminal geeks among you just use tar -xJf frida-server-10.6.15-android-x86 for everyone else, the Unarchiver is your best friend. After extracting the binary we once again need to use the terminal.

1. ) mv frida-server-10.6.15-android-x86 frida-server – To rename it to frida-server;

2.)adb root – To ensure your environment is capable of running commands as root;

3.) adb push frida-server /data/local/tmp/ – To copy the frida-server binary to the device;

4.) adb shell "chmod 755 /data/local/tmp/frida-server" – To give the binary the correct permission on the file system;

5.) adb shell "/data/local/tmp/frida-server &" – To run the frida-server as a service in the background;

5.1) adh shell "/data/local/tmp/frida-server --listen & if you want to have frida-server running on an external IP.

Installing Frida on your Machine

🎉🎉Across all platforms, all you need is sudo pip install frida 🎉🎉

To verify your Frida installation (both remote and local) you need to do a frida-ps. This displays a ps command that produces a list of the currently running processes on your device.

If connected via USB:  frida-ps U.

If you are using frida on an external address frida-ps -H 192.*.*.* whatever the address of your phone is.

If you are seeing a similar output:

You are the chosen one, and ready for bypassing certificate pinning.

For the proof of concept I am going to use a random application here, if you want a real-word scenario have a look at the many mobile bug bounties which can be found on Hackerone, Bugcrowd, Synack or Zerocopter.

To start bypassing certificate pinning, we need the Android SSL Re-pinning Frida script by Piergiovanni Cipolloni, which can be found here, here or at the bottom of this blogpost.

Bypassing Certificate Pinning using Frida

First of all, we need to install our target on the device, this can be done in multiple ways:

1.) Install the application from the Google Store.

2.) Download the application using Apkpure or apk-dl.

After doing so, open your terminal and install the application using adb install com.company.whatever.apk. Done 🐶.

The next step is to choose your target from the applications, as we did before this can be done using: frida-ps -H 192.*.*.* for a remote Frida server, or frida-ps -U if you have your device connected via USB. What you need to do next is create a copy of your previously generated cacert.cer (if you have followed the tutorial until this point it should still be in your Downloads folder).

For the very last time (I promise!) open up your terminal:

1.) cd Downloads – Move to the Downloads folder where your „cacert.cer“ is;

2.) mv cacert.cer burpca-cert-der.crt – Rename it to match the file in the Frida Script;

3.) wget https://techblog.mediaservice.net/wp-content/uploads/2017/07/frida-android-repinning_sa-1.js – Download the Frida script;

4.) adb push burpca-cert-der.crt /data/local/tmp/cert-der.crt – Push the rogue certificate to the device;

5.) frida -U -f it.app.mobile -l frida-android-repinning_sa-1.js --no-pause 🎉 NOW FINALLY 🎉 – WE DID IT!

If you see the following output:



It means you did everything right and you can now finally intercept all the traffic from those juicy bug bounty programs out there.

Thank you very much!

Patrik @itsecurityguard


PPS: A big shoutout to

EdOverflow https://twitter.com/EdOverflow  for 📚 proofreading 📚