Task 5 requires you to determine the organization’s leader’s identity and submit his last encrypted message.
Analyzing the OAUTH Verification Python Script
The task provides a compiled python script that the server uses to verify a user’s OAUTH tokens when logging into the XMPP server. I ran file on the pyc file which reported that it was a “python 2.7 byte-compiled” file. I used uncompyle6 to decompile the file to a python script.
The file contains two functions, main and check_token. The important function is check_token, which
- makes a request to a oauth2 server to introspect the token and
- checks if the token is
- active,
- scope contains “chat”, and
- the token type is “access_token”.
The token is comprised of the clientID and a value derived from the client’s secret.
I didn’t see any method to get a token for a different user. Then, I realized that the token is never checked against the user logging in. Remember from task 3 that the database contains an entry for clientID and XMPP name. The token is only based on the clientID and the XMPP name is used to log into the XMPP server. This means that I could leave the clientID unchanged but change the XMPP name to the user I wanted to masquerade as.
The app would
- Request a OAUTH token for Kingsley
- Request to login to the XMPP server as Arianna with OAUTH token for Kingsley
The server would
- Check if the OAUTH token was vaild and for chat
- Allow login
Logcat can pull logs from an android app and print them to the console. The flag pid will limit the output to the app running under that pid and “*:V” means to print all tags with verbose output.
Authentication is not same as authorization. Anum Siddiqui said it well on his blog, “… authentication is the process of verifying oneself, while authorization is the process of verifying what you have access to.” The server only checks for authentication and not authorization, enabling me to authenticate as Kingsley but login as Arianna.
I can now masquerade as different users. I logged in as each user to determine each user’s contacts and map their relationships.
The users are separated into clear groups. Arianna talks to Brian, who only talks with two other users. Zachary and Aliah each have their own groups that are more connected. This implies that Brian is the leader and Arianna, Zachary, and Aliah are cell leaders.
Getting Encrypted Messages
The messages that are not decrypted are silently dropped and not displayed to the user.
There are a few methods I tried to get the messages with varying levels of success.
Burp Suite
I have used Burp Suite in the past to inspect HTTP(S) traffic and decided to try it since the traffic was over port 443. Normally, to use Burp Suite a root certificate needs to be added to the android phone. This enables the android phone to trust certificates signed by Burp Suite. The following steps, from Distributed Compute, will install the root certificate.
- Export Burp CA certificate from Proxy -> Options page in DER format
- Convert DER to PEM format and rename as subject hash
- Copy certificate to Android
- Restart the emulator with system writeable option and remount /system as read/write
- Move file to trusted certificate store
This step was not required since TerrorTime does not check that the certificate is chained to a trusted CA.
The Android’s proxy configuration is under Extended Controls -> Settings -> Proxy.
This setup does not work since Burp only handles HTTP(S) traffic, even though the XMPP traffic is using port 443 which is for secure web traffic. Unfortunately, Burp ignores it since its not HTTP or HTTPS traffic. I did not try it, but there is an extension called NoPE Proxy that handles non-HTTP traffic.
Socat
Socat is a tool that can redirect and manipulate network traffic. I followed a guide by PenTestPartners to setup socat to
- listen on one port,
- strip the SSL,
- send traffic to another port,
- add SSL back and forward to server.
This would enable me to run Wireshark and capture the traffic while it is in plaintext.
There are two methods to redirect traffic to the socat listener
- change the IP address returned by the DNS query, or
- change the domain name in the database.
I probably choose the harder method of changing the DNS response by editing the host file.
socat commands
Unfortunately, the XMPP protocol uses STARTTLS (described in RFC6120 5.4.2) to upgrade a normal connection to a secure connection.
Socat does not handle STARTTLS, but instead expects the connection to start out as a secure connection. I looked at using striptls to stop the upgrade to a TLS connection. This is in reference to CVE-2016-10027, which is a vulnerability in the Smack XMPP library. This tool did not work since the XMPP server is configured to require a TLS connection.
Frida
Frida can inject JavaScript into a running Android app. It enables a user to hook or modify existing functions, along with running new code. Frida requires root access to the Android to run the Frida server. If you do not have root access but the app is marked as debuggable, then frida can be loaded using the debugger. Additionally, I used 11x256’s blog to setup the python script to interact with Frida and the JavaScript to inject.
Below is the normal flow from logging in to the decryptMessage function.
Python code to start TerrorTime and inject JavaScript.
Below is the JavaScript injected into the TerrorTime app; it hooks the decryptMessage to print to the console all messages received. Additionally, it hooks functions called when sending and receiving Stanzas to print them to the console.
New flow after hooking decryptMessage.
By hooking the decryptMessage function, I was able to print out each message the TerrorTime app receives.
Things that should work, but I didn’t try
- xmpp man-in-the-middle,
- NoPE Proxy (Burp-Non-HTTP-Extension),
- building/modifying android app,
- using xmpp python library,
- stunnel, can handle STARTTLS, and
- retrieving the TLS master secret from the Android app.
I was now able to login as Brian and extract his last encrypted message to fulfill the task.