Textfree - Sat, Jul 20, 2019
Download link: Textfree
[Part 1, Web Client & Account Creation]
In this exploit I will be showing how I was able to make oauth signatures that work with textfree’s API’s, and how I was able to programmatically create accounts. Before reading the rest of this page I would suggest you read about OAuth. First, let’s look at all interfaces we have with Textfree. Textfree offers a Web client, and an Android/IOS app. I started by looking at the webclient, but soon found that making an account requires you to fill out a captcha, and provide an email/phone number. Programmatically creating an account via the web client isn’t going to happen.
Let’s turn our focus to the Android/IOS applications. I first setup an Android emulator running Android 5.1.1 since my physical Android runs Nougat. (You can’t successfully man in the middle Nougat due to the fact that apps will not trust user approved ssl certs, more on here.) After setting up the Android emulator I started the MITM session and simply recorded all HTTP/HTTPS network traffic while I created an account inside of the app. The results show us that the packets are authenticated using OAuth.
Usually this would stop any sort of spoofed packet, repeating packet, or packet produced via a bot, but for some reason I was able to resend the same packet, and create an account. Later on I discovered that oauth_signatures are not hashed with a token before login. The consumer secret and base string are the only things used to create oauth_signatures before login.
Still, usually this doesn’t matter due to the fact that oauth uses nonces and timestamps to prevent people from just resending the same packet over and over, but for some reason textfree doesn’t check timestamps or nonces, the only thing they check is the oauth_signature. This means we can just copy and paste the Authentication header value and use it until the consumer key changes. So, to be clear we have the ability to send as many login packets although we don’t know the consumer key though.
But wait, I said I was able to create oauth_signatures, not just copy and paste header values. Well remember how textfree has a web client? Well the webclient also uses oauth, this means that in order for the webclient to have authenticated packets it has to have the consumer secret. So let’s look for it.
[Part 2, Decompiling & More OAuth]
OAuth is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords. You can read more about OAuth here: OAuth V1.0a. Textfree uses OAuth for its Android, IOS, and Webclients. Although OAuth is normally used to secure logins without needing to provide an actual password, Pinger is using it to secure their API endpoints. When I first started this project a few months back I was only using an HTTP(s) proxy to reverse engineer the application. This only got me so far considering that I didn’t know the OAuth consumer Secret. This meant that I could only interact with Pinger’s API’s prior to creating an account. This was because after you create an account you are provided a token which is used in conjunction with the consumer secret to create a unique OAuth signature. The first thing I did was download and unpack the Textfree APK which took about 15 minutes in all. I downloaded the apk here and then I unpacked it using apktool.
We are left with the three smali code folders corresponding to the three DEX files that the APK has. If you don’t know about multiDEX you can read about it here, and if you don’t know about smali code you can read about it here. With the application completely unpacked it’s time to enable debuggability. This allows us to run the application with a debugger attached to it. We can set breakpoints later on and check the registers/locals variables.
Now we just have to pack the application backup and sign it. I used uber apk signer. After installing the app onto a VM and ensuring that it still worked I opened the unpacked application inside of android studio and set breakpoints. After a few hours of reverse engineering the obfuscated code I was able to find where the code was for constructing HTTP(s) packets.
I knew I was close when I started seeing HTTP headers pop up inside of the registers. After a few more minutes of stepping I found what i was looking for… The OAuth Consumer Secret.
It was interesting to see that textfree didnt url encode their oauth base string like you are supposed to.
The base string is supposed to look like this: POST&https%3A%2F%2Fapi.pinger.com%2F1.0%2Fbatch&oauth_consumer_key%3Dtextfree-android%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1563332403%26oauth_nonce%3Diwqupeokgoeqrmbt
With the new OAuth secret I found I am able to sign requests as though I am the app. Here is an example:
As you can see in the photo above, I was able to sign a request with OAuth as though I was the application. This means anything the application does I can do. I.E make accounts, send texts, get texts, and possibly even make phone calls.