Reverse-Engineering Private APIs with MITM Proxy
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.
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)
- Enable the proxy setting on your devices connection sections.
- Point the IP address to the local IP address of your computer
- Set the port number to 8080
- Authentication is not needed
- Open your mobile browser (iPhone must be Safari)
- Go to mitm.it
- Click to download the certificate for your device type
- 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
- Go to Settings -> General -> About -> Certificate Trust Settings
- 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
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.
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