Reverse-Engineering Private APIs with MITM Proxy

Disclaimer: This is for educational purposes, do not abuse this method.

Developers can often struggle to find the data they need for their personal projects due to certain services locking down their API’s.

So I wanted to show you a way you can get the data you need.

What is MITM Proxy and how does it work?

MITM stands for Man-in-the-Middle and mitmproxy is exactly that. It allows you to send data through a proxy that acts as a man-in-the-middle so you can read the request and responses being sent to and from the server.

MITM Diagram

Before we begin

We’ll be installing this on a Macbook and capturing the data sent from an iPhone. However mitmproxy supports multiple platforms and devices. You can find out more in their documentation.

Installation

Head on over to mitmproxy.org and follow their installation instructions. You should be able to open mitmproxy from the terminal with:

$ mitmweb

mitmweb is the GUI version that should open up in a new tab once it’s running.

With mitmweb running we can configure our device

You are going to need the local IP address of the computer running mitmproxy. You can Google how to find this on your computer.

On your device follow these instructions: (Detailed tutorial in video above)

  1. Enable the proxy setting on your devices connection sections.
  2. Point the IP address to the local IP address of your computer
  3. Set the port number to 8080
  4. Authentication is not needed
  5. Open your mobile browser (iPhone must be Safari)
  6. Go to mitm.it
  7. Click to download the certificate for your device type
  8. On iPhone you then need to visit the setting page. You will be prompted about the recently downloaded certificate. Confirm the installation of the certificate there.

Bypassing iPhone’s extra security

  1. Go to Settings -> General -> About -> Certificate Trust Settings
  2. Enable full trust of root certificates.

Setup is done, on to the fun stuff

Now you should be able to open up apps on your device and you will start seeing traffic popup in mitmweb

img1

In our example we are capturing the data being sent to Thingivese from the mobile app. If you look closely on the right hand side you will find the authentication header. In this header you will find the token being used to validate you as a user.

img2

This is the token we can now use to query the API ourselves in our own personal application.

Now try query the API yourself.

Here we are pulling the latest listings using Axios and sending the bearer token along with it.

const http = require("http");
const Axios = require("axios");

http
  .createServer(function (req, res) {
    const url = "https://api.thingiverse.com/featured?page=1&per_page=10&return=complete";
    const token = "5a2d072366d7039776e4c35c5f32efaf";

    Axios.get(url, {
      headers: {
        Authorization: `token ${token}`,
      },
    })
      .then((result) => {
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify(result.data));
      })
      .catch((error) => {
        console.error(error);
      });
  })
  .listen(3000); //the server object listens on port 3000

Worth noting

This may will not work for all applications as they may use ‘Certificate Pinning’ to which you’ll need an Android or Jailbroken iOS device.

You can read more about Certificate Pinning in the docs: Certificate Pinning