Intercepting Firefox OS traffic using a proxy

In this part of the Debugging and security testing article we look at intercepting Firefox OS traffic using a proxy tool, including whitelisting the proxy's SSL certificate so Firefox OS doesn't mind someone intercepting and re-encrypting the HTTPS communication. If you use B2G Desktop,  the first part of the tutorial about how to install it and attach the Marionette JavaScript debugging shell is explained in Debugging and security testing with Firefox OS.

Working with apps that are nothing but HTML and JavaScript, you'll find that a lot of the really interesting work involves using APIs that transfer data over the Web. That means it's often useful to look at the HTTP requests that these apps perform. Proxy tools like Burp and ZAP have useful features for monitoring such traffic. They provide manifests containing information on how clients should configure themselves, including root certificates to install for TLS termination, etc.

Combined with the 'debug main Firefox OS process' feature of the app manager, they allow you to install your proxy's root cert onto your device by running some code from a scratchpad.

Debugging the main Firefox OS process

So how do you debug the main Firefox process? Whether you are using the Firefox Simulator or a real device, you can debug certified apps via the App Manager by setting some prefs in your profile. Follow these steps first, then set the pref to true in about:config, before restarting your browser.

Next, connect to your device/simulator using the App Manager, then on the Device screen you'll see a "DEBUG MAIN PROCESS" button; click that and you can debug JSMs and run privileged JavaScript in the scratchpad.

Note: Be careful what you run against the main process: you could accidentally destroy your device!

Introducing ZAP

First, let's continue the process using ZAP. ZAP is an intercepting proxy that intercepts and re-encrypts HTTPS traffic for easy debugging. Click on the big blue button on the ZAP homepage to download it. If you choose to use another proxy feel free to do so as our approach should work with both.

ZAP Certificate

Now, whichever proxy you use, let it export its certificate to a file such as owasp_zap_root_ca.cer (go in Tools > Options > Dynamic SSL Certificates > Save). When ZAP first starts up, it generates a certificate valid during one year. You can also generate a new one from the Dynamic SSL Certificates section.

Local proxy

If you're using B2G desktop, you have to make sure that ZAP does not listen on localhost, but instead on your attributed IP address (ethernet or Wi-Fi). This is because B2G Desktop's localhost does not point to your desktop computer, but something within the b2g binary itself. For our example, we will use my IP address:

If you're working with a real device, you'll have to make sure your phone and your computer are connected to the same network/VLAN and can communicate together (if you have a doubt, try to ping the IP of one device from the other one).

Connecting your device to the proxy

You can then connect to your proxy in multiple ways:

You can pull the default prefs from your device, change them to add the relevant proxy prefs, put them back.

Or, you could configure your tool to proxy HTTP and HTTPS transparently then set up iptables on your device to point to your proxy. E.g, to make HTTPS traffic go through your proxy tool:

adb shell iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination

And, to reset it when you're done:

adb shell iptables -t nat -F

Setting up a proxying LAN

If you find yourself doing this kind of activity a lot, there's a way that's even more conveient; set up a testing LAN where all traffic is proxied by default. This way, you can turn proxying on and off just by changing which wireless LAN you're connected to.

We built one using a raspberry pi and steps similar to these. We changed the iptables rules to look like this:

:INPUT ACCEPT [49:3128]
:OUTPUT ACCEPT [37:3924]
-A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i wlan0 -o eth0 -j ACCEPT
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 80 -j DNAT --to-destination <proxy_host>:<http_port>
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 443 -j DNAT --to-destination <proxy_host>:<https_port>

Creating a certificate database

Accepting certificates happens in settings, which are stored in profiles. Here's a short primer on Firefox profiles:

  1. Start the Firefox profile manager using the -P option on the command line, and make sure that Firefox is not using any existing Firefox sessions (-no-remote):
    • On Linux, you need to do:
      firefox -P -no-remote
    • On Mac OS X:
      /Applications/ -P -no-remote
  2. Now create a new profile called "zapped." Go to the certificate settings — Edit > Preferences > Advanced > Encryption > View Certificates > Import. Now select the owasp_zap_root_ca.cer file created by your proxy and tell Firefox that it should trust this CA to identify web sites (this is really only valid for this profile).
  3. Having used Firefox to create a certificate database for us, we can now use this database for our B2G profile. The name of your Firefox profile directory is a random string that ends with zapped. The location depends on your operating system; see Runtime Directories for details on where it can be found.
  4. For B2G desktop, we only need the cert8.db file, which is the profile's certificate database. Copy it over to your b2g profile directory b2g/gaia/profile/.
  5. On a device, copy the cert9.db on your device profile directory:
    $ adb shell stop b2g
    $ adb push cert9.db /data/b2g/mozilla/*.default

Note: This will overwrite the existing file.

Setting up B2G

The next step is to set ZAP as the default proxy for all network communication. The proxy settings, like the certificate settings, are currently not available from the Firefox OS user interface.

On B2G Desktop

You need to append these custom settings to the preferences file, b2g/gaia/profile/prefs.js:

user_pref("network.proxy.backup.ftp", "");
user_pref("network.proxy.backup.ftp_port", 8080);
user_pref("network.proxy.backup.socks", "");
user_pref("network.proxy.backup.socks_port", 8080);
user_pref("network.proxy.backup.ssl", "");
user_pref("network.proxy.backup.ssl_port", 8080);
user_pref("network.proxy.ftp", "");
user_pref("network.proxy.ftp_port", 8080);
user_pref("network.proxy.http", "");
user_pref("network.proxy.http_port", 8080);
user_pref("network.proxy.no_proxies_on", "");
user_pref("network.proxy.share_proxy_settings", true);
user_pref("network.proxy.socks", "");
user_pref("network.proxy.socks_port", 8080);
user_pref("network.proxy.ssl", "");
user_pref("network.proxy.ssl_port", 8080);
user_pref("network.proxy.type", 1);
user_pref("network.proxy.pac_generator", false);

Note: Remember to replace my IP address with yours, and if your proxy does not listen on port 8080 make sure you change it in this file too.

At this point, you should be ready to go! Start B2G Desktop again, and try some browsing. Network traffic should appear in ZAP.

On a device

To enable this functionality on a device, you'll need to modify the prefs.js file located in your profile on the device. Connect the device to your computer which has previously been set up with the adb tools.

First, you need to know what the name of your profile directory is. You can find it like this:

adb shell ls /data/b2g/mozilla

Among the output, you'll see a directory named with a number of random numbers and letters ending with ".default". This is your profile directory. Use that name where you see "xxxxxxxx" from here on in these instructions.

Next, grab the prefs.js file so you can edit it:

adb pull /data/b2g/mozilla/xxxxxxx.default/prefs.js

Open the resulting file in your favorite text editor; at the end of the file, add the custom settings indicated in the section above and save your changes. Now all you need to do is push the changed file back to the device and restart the b2g process to pick up the changes, as follows (the B2G process should already be stopped if you followed the earlier instructions to push cert9.db):

adb push pref.js /data/b2g/mozilla/xxxxxxxx.default
adb shell start b2g

Charles Proxy

Users looking to use Charles Proxy should see this blog post: