Textfree Reverse Engineered
Code for this project can be found here.
<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, lets 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 isnt going to happen.
Lets 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 cant 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 doesnt 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 doesnt 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 dont 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 lets look for it.
After some testing I found that the web client consumer secret only works for webclient interactions so trying to use the consumer secret that I found to make oauth_signatures from the Android app wont work...
So to conclude, I am able to create textfree accounts and sign web client packets. Due to time contraints this is where my project concludes. Here is the full scale API for creating an account with textfree. Its very slow due to the fact multiple HTTP requests are required to create an account and all of them are made via TOR.
<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 use 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 didnt know the OAuth consumer Secret. This ment 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 conjuntion with the consumer secret to create a unique OAuth signature.
We are left with the three smali code folders corresponding to the three DEX files that the APK has. If you dont know about multiDEX you can read about it here, and if you dont know about smali code you can read about it here. With the application completely unpacked its time to enable debuggability. This allows us to run the application with a debugger attached to it. We can set break points later on and check the registers/locals variables.
Now we just have to pack the application back up 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 obfiscated 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
Not this: POST&https://api.pinger.com/1.0/batch&oauth_consumer_key=textfree-android&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1563332403&oauth_nonce=iwqupeokgoeqrmbt
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.