Easy and accessible network request analysis
Posted by Eric Scheibler at June 12, 2021
I had to analyse some network requests while I was working on an
Android app project. That turned out to be surprisingly easy, using mitmproxy. This article covers the
proxy installation and usage by wget
and within the source
code of an Android app.
Basically it works like a mitm attack. You have to install a proxy server somewhere in your local network and route client requests through it. I’ve chosen mitmproxy, because it’s available for the Linux console, simple to use and its ui is fairly accessible to screen readers like brltty.
Install: sudo apt install mitmproxy
Run:
mitmproxy --listen-host 192.168.100.100 --listen-port 22222 --save-stream-file +requests.log
Wget
Now try to send a http request through the proxy:
wget -e https_proxy=192.168.100.100:22222 http://example.org
It should appear in the main view of mitmproxy.
If you want to intercept encrypted requests as well, your client must
trust the ssl certificate, which mitmproxy created during its first
launch. You may find it under
~/.mitmproxy/mitmproxy-ca-cert.pem
. Copy the file onto your
client machine and send a second request:
wget -e https_proxy=192.168.100.100:22222 --ca-certificate /path/to/mitmproxy-ca-cert.pem https://example.org
If everything went well, you should see two lines in the mitmproxy main view. Use the arrow keys to select a request and press ENTER to show its details.
Unfortunately the view doesn’t use the hardware console cursor. Therefore screen readers can’t announce the selected list item properly. If you use brltty, you may disable the autom. cursor tracking (CAPSLOCK+ENTER) and follow the selected list item manually. It’s prefixed by “>>”.
The request details view consists of three tabs: request, response and details. Select them with left and right arrow keys or tab through). I was only interested in the request cookie headers, which I found directly in the request tab.
Android app development
First add the same mitmproxy certificate to your apps “res” folder:
mkdir /path/to/android_project/app/src/main/res/raw/
cp ~/.mitmproxy/mitmproxy-ca-cert.pem /path/to/android_project/app/src/main/res/raw/mitm_proxy.pem
Then include the following code into your app to:
- set the proxy
- use the SSL certificate from above for the request
import org.example.project.BuildConfig;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
URL url = new URL("https://example.org");
String proxyHost = "192.168.100.100";
int proxyPort = 22222;
HttpsURLConnection connection = null;
if (BuildConfig.DEBUG) {
Proxy proxy = new Proxy(
Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
= (HttpsURLConnection) url.openConnection(proxy);
connection
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput;
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
.load(null, null);
keyStore// load mitm_proxy certificate
= ApplicationInstance.getContext().getResources().openRawResource(R.raw.mitm_proxy);
caInput try {
.setCertificateEntry("ca1", cf.generateCertificate(caInput));
keyStore} finally {
.close();
caInput}
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
.init(keyStore);
tmf// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
.init(null, tmf.getTrustManagers(), null);
sslContext.setSSLSocketFactory(sslContext.getSocketFactory());
connection} catch (Exception e) {
System.out.println(
String.format("Cert exception: %1$s", e.getMessage()));
}
} else {
= (HttpsURLConnection) url.openConnection();
connection }
Of course it’s also possible to reroute every request from the Android device through your proxy. Then you have to add the certificate to your cert-store (Android settings -> security) and set a system-wide proxy. Unfortunately not every application respects this - for example browsers may define their own proxy settings.
Therefore if you want to debug your own app, go for the direct integration - much easier to implement.