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

The token is comprised of the clientID and a value derived from the client’s secret.

from base64 import b64decode
b64decode("a2luZ3NsZXktLXZob3N0LTE3NEB0ZXJyb3J0aW1lLmFwcDp6ZENVQ2RubUVLdDB0Ug==") # user's token

# outputs 'kingsley--vhost-174@terrortime.app:zdCUCdnmEKt0tR'

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

The server would

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.

.\adb.exe -e logcat --pid=21576 --format=color *:V

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.

openssl x509 -inform DER -in burp.der -out burp.pem
openssl x509 -inform PEM -subject_hash_old -in burp.pem | head -1
mv burp.pem <previous command output>
emulator.exe -avd <avd_name> -writable-system
adb shell su -c “mount -o rw,remount,rw /”
adb shell
cp /sdcard/Downloads/<subject_hash>.0 /system/etc/security/cacerts
chmod 644 /system/etc/security/cacerts/<subject_hash>.0

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. _config.yml

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 is a tool that can redirect and manipulate network traffic. I followed a guide by PenTestPartners to setup socat to

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

I probably choose the harder method of changing the DNS response by editing the host file.


socat commands

# in one terminal
socat -v openssl-listen:443,cert=cert.pem,verify=0,reuseaddr,fork tcp4:localhost:6500
# in another terminal
socat -v tcp4-listen:6500,reuseaddr,fork ssl:chat.terrortime.app:443,verify=0

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 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. _config.yml

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

I was now able to login as Brian and extract his last encrypted message to fulfill the task.

Back to Overview