CTFZone Paper: Trust Area — Backend Part

Introduction

We had long aspired to create a task for attack-defense CTF competitions involving the detection and exploitation of vulnerabilities in Android-powered mobile applications. However, we had many doubts concerning the task architecture, since we lacked an understanding of how it was supposed to work. It was only recently — during the preparation for CTFZone Finals 2020 — that we finally decided to implement this idea. In this article, we compile the technical details of what we ended up with :)

Task architecture

Every team that had made it to the attack-defense stage was provided with its own backend hosted on its dedicated game server. The players were granted full access to the server. The teams could not communicate with the backends of other participants directly, which was restricted on the network level. Also, every team had a mobile application deployed on an Android emulator in the task infrastructure. The Android apps could communicate with the other teams’ backends through HTTP and with other applications in the emulator — using the IPC (inter-process communication) mechanisms. The teams had sources of APKs and could modify them. Every round, the emulator extracted a new APK version from the special folder on the team’s backend and deployed it. The backend and APKs contained vulnerabilities that could be exploited by the players for capturing flags. There was also a checker installed on the emulator, which communicated with the teams’ APKs and backends. We will dig deeper into the checker’s functions and APKs in parts 2 and 3 of this article.

Fig. 1. Task infrastructure

Backend

Architecture

We went with Golang as the primary language and used Docker Compose for deployment. Given that the task itself had some novelties, we decided to avoid any ‘exotic’ backend solutions. As a result, we created a typical web application with PostgreSQL and Redis as session storage.

  1. Every player could quickly deploy the task and test it locally.
  2. 2. We, as organisers, could select any bunch of services for the task, having the freedom to add any vulnerabilities and exploitation chains.
Fig. 2. Backend architecture

Vulnerability complexity dilemma

One of the dilemmas was to determine how complex the backend vulnerabilities should be — in terms of detection, mitigation and exploitation. To do this, we had to take into account the specifics of the task and time limitations. Within the allocated time, the participants had to gain an understanding of how this new task worked, find the vulnerabilities, and (the hardest part) add code to their mobile application to exploit these vulnerabilities.

Description of vulnerabilities

1. IDOR

Before describing the IDOR vulnerability, let us provide a brief overview of the main backend logic. Users were allowed to create tasks with a challenge and a reward based on solving this challenge. A challenge represented a string with a SHA1 hash of another random string. The players could receive a reward only after submitting the correct string whose SHA1 hash equalled the challenge string. As the random strings were massive, it was impossible to get them by fair means.

2. Nginx misconfiguration

Nginx had a vulnerability related to the unsafe use of the alias. Nginx configuration snippet:

Fig. 3. Logs reading

3. and 4. SQL injections

The backend contained two classical SQL injection vulnerabilities in different locations:

5. Open Redis port

Docker Compose had two configurations: dev and prod. By default, the service used the prod configuration, which contained only one vulnerability — a forwarded Redis port:

6. Refresh token leakage

The authentication mechanism of our mobile application relied on refresh and access tokens. Generally, refresh tokens carry the information necessary to get a new access token, which serves to make authenticated calls to a secured API. In our case, a refresh token represented the user’s UUID (Universally Unique Identifier). Thus, knowing the UUID, a threat actor could generate an access token and gain access to the user’s information. The code snippet below was used to extract UUIDs by usernames:

Source code:

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
OFFZONE

OFFZONE

15 Followers

International community conference for cybersecurity researchers and professionals. No suits, no business — only hardcore research.