Reversing an Android app API
Tags: api, reverseengineer, android
Published: 2023-09-26 13:10:40

![Sniffer](https://res.cloudinary.com/djjd0wi5i/image/upload/c_scale,h_338/v1695732808/photo_2023-09-26_14-52-57_porfnq.jpg)

Let's keep reversing stuffs, this time I'll try to guide you on how to start reversing an android app API. Yep, it's possible and quite interesting. Those apps that you normally use, yep you can see in detail what are the HTTP requests they are making. Later if you have enough patience to go and reverse their API it's up to you. Quite awesome(painful actually) process. There are two main reasons of why I in the past **want** to do so:

1. I wanted to interact with a private API of an app I used, quite legit use, not so sure if it's even legal, but many products that brand themselves as **amazing startups the bests in the field blablabla** at the end are just reversing other products 🙂. 
2. As a company, you have a legacy application which engineers you fired or they quit(because you treat them as shit), and now the new engineers(poor guys) have to deal with this app. Analyzing a big source code, and finding which part it's in charge of a given functionality, it's like (in Spanish, the best language in the world), _encontrar una aguja en un pajar_. Instead, a faster approach would be to run the APP, and see which endpoint it's hit when you clicked a given button.

Given this, let's give you easy instructions on how to do this. We will need some requirements to do so, here they are.

## Requirements

1. Android emulator. For this I normally use just the one from [Android studio](https://developer.android.com/studio), but I'm sure there are other alternatives. Honestly working with **Android Studio** it's simple, give it a try.
2. [Frida](https://frida.re/), uff this is just **AMAZING**, yes with uppercase and in bold letters. They also has bindings on different languages that can be found in their [github repository](https://github.com/frida/frida). Spoiler alert...the Go binding it's pure shit...really couldn't run it. Use just the default that it's installed with `pip install frida-tools`.
3. [Frida-server](https://github.com/frida/frida/releases), you can download **frida-server** to your particular architecture. To see what it's your emulator architecture, just run `adb shell uname -m`. In my case it's `x86_64`.
4. [HTTP Toolkit](https://httptoolkit.com/), you will need to install one in your PC and another one in the emulator.


## Setup

**Emulator**

Before starting to intercept HTTP traffic, it's necessary to set up your emulator. Install as well the application you want to intercept in the emulator, in my case I'll install [Amazon audible](https://play.google.com/store/apps/details?id=com.audible.application). Run the emulator, and let's see if we can see it:

```bash
adb devices -l

List of devices attached
emulator-5554          device product:sdk_gphone64_x86_64 model:sdk_gphone64_x86_64 device:emu64xa transport_id:1
```

We have it, all good. Next steps is to run frida server on the emulator.

**Frida server**

Having frida-server binary for your particular emulator architecture, we need to push this binary into the emulator.

```bash
# let's copy the frida-server binary into /data/local/tmp/frida-server
adb push ./frida-server /data/local/tmp/frida-server

```

We need to enable root access to the device

```bash
adb root
```

Let's make the recently copied binary executable

```bash
adb shell "chmod 755 /data/local/tmp/frida-server"
```

Let's run it now as a background job

```bash
adb shell

/data/local/tmp/frida-server &

```

**NOTE: Follow only if you received a permission error**

After running this command, you might encounter yourself with a permission error, to solve that please check the **owner** of the **frida-server** file in the emulator. This is easy to do, let's assume you are already in `adb shell`.

```bash
# let's check the owner of frida-server binary
# look at the frida-server file in the output
ls -lh /data/local/tmp/

[OUTPUT]
...
-rwxr-xr-x 1 shell shell 103M 2023-09-26 11:43 frida-server
...

```

If this is the case, the **owner** and **group** of **frida-server** file, it's **shell**, we need to change that to **root** that is where we are running it.
Let's change the **owner** only, this is easily done running

```bash
chown root frida-server
```

That's it, back to our main task and let's run **frida-server** in the background.

```bash
./data/local/tmp/frida-server &
```

__Small tip__

To list the current background jobs in linux, you can run `jobs`, to get it _out of the background, in the foreground_ run `fg`.

## Listening traffic

In order to listen the HTTP traffic we will need this script, [frida-script.js](https://raw.githubusercontent.com/httptoolkit/frida-android-unpinning/main/frida-script.js), let's open another terminal and get it.

```bash
curl -sLO https://raw.githubusercontent.com/httptoolkit/frida-android-unpinning/main/frida-script.js
```

Now we need the name of the package(android application) we want to sniff the traffic. That's easy to fetch

```adb
adb shell pm list packages | grep audible | cut -d ':' -f2
```

In our case the output is `com.audible.application`, this is the name of our package.

**Sniffing traffic**

Now to sniff the traffic, we should run

```bash
frida -U -l ./frida-script.js -f com.audible.application
```

You should receive an output like the following

```bash
     ____
    / _  |   Frida 16.1.3 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to Android Emulator 5554 (id=emulator-5554)
Spawned `com.audible.application`. Resuming main thread!                
[Android Emulator 5554::com.audible.application ]-> ---
Unpinning Android app...
[+] SSLPeerUnverifiedException auto-patcher
[+] HttpsURLConnection (setDefaultHostnameVerifier)
[+] HttpsURLConnection (setSSLSocketFactory)
[+] HttpsURLConnection (setHostnameVerifier)
[+] SSLContext
[+] TrustManagerImpl
[ ] OkHTTPv3 (list)
[ ] OkHTTPv3 (cert)
[ ] OkHTTPv3 (cert array)
[ ] OkHTTPv3 ($okhttp)
[ ] Trustkit OkHostnameVerifier(SSLSession)
[ ] Trustkit OkHostnameVerifier(cert)
[ ] Trustkit PinningTrustManager
[ ] Appcelerator PinningTrustManager
[ ] OpenSSLSocketImpl Conscrypt
[ ] OpenSSLEngineSocketImpl Conscrypt
[ ] OpenSSLSocketImpl Apache Harmony
[ ] PhoneGap sslCertificateChecker
[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string)
[ ] IBM MobileFirst pinTrustedCertificatePublicKey (string array)
[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSocket)
[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (cert)
[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (string string)
[ ] IBM WorkLight HostNameVerifierWithCertificatePinning (SSLSession)
[ ] Conscrypt CertPinManager
...
```

### Launching HTTP Toolkit

Now in order to see this traffic we can use [HTTP Toolkit](https://httptoolkit.com/docs/guides/android/). Assuming you installed it in your PC and the android emulator, we can now launch it and select this **Android device via Adb**. More on how to use http toolkit on the official documentation.

![Http toolkit](https://res.cloudinary.com/djjd0wi5i/image/upload/v1695731761/photo_2023-09-26_14-35-24_hmgy7s.jpg)

After this you can go to your emulator and use the application you want to use, you should be able to see the traffic on HTTP Toolkit.

![Http toolkit](https://res.cloudinary.com/djjd0wi5i/image/upload/v1695732085/photo_2023-09-26_14-41-04_d8agbd.jpg)

![Android studio](https://res.cloudinary.com/djjd0wi5i/image/upload/v1695732085/photo_2023-09-26_14-41-09_ywxw58.jpg)

## Conclusion

With this, now you can reverse the APIs you are curious about. Or at least to see data that's been transmitted about you on this applications.


## Bibliography

1. [Frida doc](https://frida.re/docs/home/)
2. [Http Toolkit doc](https://httptoolkit.com/docs/guides/android/)