> ## Documentation Index
> Fetch the complete documentation index at: https://siriusbar.net/llms.txt
> Use this file to discover all available pages before exploring further.

# TryHackMe - Race Conditions

> TryHackMe writeup covering three race-condition challenges in binaries.

Room link: [Race Conditions](https://tryhackme.com/room/raceconditions)

An intermediate TryHackMe room that aims to solve 3 "race condition" problems in 3 binaries. According to the instructions we should be connected to the machine via SSH using the following credentials:

* User: race
* Password: car

<Frame caption="Connect Through SSH">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/1.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=6cb658824ec35c98e36051edc79a3a30" alt="Connect Through SSH" width="754" height="579" data-path="images/racecond/1.PNG" />
</Frame>

## Walk Flag

We see an executable, a C file which the binary is probably compiled from, and the flag that we need to read. At first glance we see that the flag obviously cannot be read with our permissions.

<Frame caption="Home Directory of the user Walk">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/2.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=b2ca6705af5bc2924fea7dafbd8f5859" alt="Home Directory of the user Walk" width="571" height="221" data-path="images/racecond/2.PNG" />
</Frame>

Next, we take a look at the C file and see code that appears to be a simple program that reads and prints the contents of a file. However, it includes some additional checks to prevent the program from reading sensitive information or symbolic links that contain the word "flag" in the file path.

<Frame caption="Contents of the C File">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/3.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=fc19303a438ea424e839ad2ee16b3b7a" alt="Contents of the C File" width="720" height="623" data-path="images/racecond/3.PNG" />
</Frame>

To test this we create a file called test in our own home directory, and try to read the file using the `anti_flag_reader` executable. As expected, we can.

<Frame caption="Reading a dummy file using the executable">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/4.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=4602fe8426269c24926aa65fcd404a59" alt="Reading a dummy file using the executable" width="543" height="291" data-path="images/racecond/4.PNG" />
</Frame>

The main flaw in this code is that the program sleeps and waits for a character input from the user **after** doing the necessary checks. We can bypass this by creating a symbolic link between a dummy file and our flag file **after** the checks are done and **before** we press a key to proceed with the program.

<Frame caption="Creating a Symlink after the checks are done">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/5.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=626e9ce1b411e0bc18bb7cc6c5b55bee" alt="Creating a Symlink after the checks are done" width="1522" height="273" data-path="images/racecond/5.PNG" />
</Frame>

## Run Flag

Same as before, we see an executable, a C file which the binary is probably compiled from, and the flag that we need to read.

<Frame caption="Home Directory of the user Run">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/6.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=ea512c0844f814b63fd3278eaaadf116" alt="Home Directory of the user Run" width="479" height="211" data-path="images/racecond/6.PNG" />
</Frame>

First, we check the C file contents for potential race condition flaws and inside the **check\_security\_context** function we encounter one. The program sleeps for 500 microseconds after checking if the user that executed the binary can really access the inputted file.

<Frame caption="Contents of the C file">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/7.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=e73a5f57150a183a2b394b8989640f82" alt="Contents of the C file" width="1053" height="778" data-path="images/racecond/7.PNG" />
</Frame>

We can bypass this by creating and deleting a dummy file continuously while creating a symlink between our dummy file and the flag file.

<Frame caption="Bash Script for the above purpose">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/8.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=d68b285e10c3cb9898858117266c0ca5" alt="Bash Script for the above purpose" width="360" height="186" data-path="images/racecond/8.PNG" />
</Frame>

While we are executing our script we should try to read the flag at the right time interval (you can do this via writing another automated script, but the time interval is big enough to get the flag without automation so I got it manually).

<Frame caption="Getting the flag in the right time interval">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/9.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=8c627417d7fe19be6ad5f953ea903666" alt="Getting the flag in the right time interval" width="1908" height="406" data-path="images/racecond/9.PNG" />
</Frame>

## Sprint Flag

Finally, our final user has the same files (an executable, a C file, and the flag) as before.

<Frame caption="Home directory of the user Sprint">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/10.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=271f660252f9b088cac125513a920ce7" alt="Home directory of the user Sprint" width="548" height="202" data-path="images/racecond/10.PNG" />
</Frame>

This time before we check the contents of the C file, we first try the executable and we see that it is actually a banking system that serves on port 1337. After we connect to the machine through port 1337 we see that we have 3 available commands in use:

* **withdraw**: Withdraws 10000 units from the balance
* **deposit**: Deposits 10000 units to the balance
* **purchase flag**: Checks if there's enough balance in the account (15000) if so then gives us the flag.

<Frame caption="Using the application on port 1337">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/11.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=273a5f894916c82e356f51abea511158" alt="Using the application on port 1337" width="1291" height="537" data-path="images/racecond/11.PNG" />
</Frame>

One problem here is that, as you can see from the source code, after depositing 10000 units to the account it nearly instantly (after sleeping for a microsecond) sets the balance to 0 again. The key word here is **nearly**.

<Frame caption="Corresponding section of the C code">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/12.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=5c012445ef7137ababf01fd31e458781" alt="Corresponding section of the C code" width="618" height="106" data-path="images/racecond/12.PNG" />
</Frame>

But there is a catch: although every session after you connect to the application is created by a different thread, the balance is kept global and not dependent on the corresponding thread. This means if we create enough threads at the same time and try to deposit money into the account, it should eventually be 20000 units or even 30000 units in the account. We can exploit this :D.

<Frame caption="A script that I wrote, that deposits to the balance infinitely">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/13.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=e0dcb750385dc0dc9e1d243ec0069095" alt="A script that I wrote, that deposits to the balance infinitely" width="511" height="127" data-path="images/racecond/13.PNG" />
</Frame>

We execute the script that we wrote 10 times to make our chance higher to exceed the 15000 limit, and also we write another script to purchase the flag simultaneously with our deposit scripts running.

<Frame caption="The two scripts that we wrote">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/14.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=d83ac2cb0a521b8126001e5a27b838e6" alt="The two scripts that we wrote" width="1699" height="786" data-path="images/racecond/14.PNG" />
</Frame>

After a few seconds of trying, our script successfully purchased the flag.

<Frame caption="Flag of the last challenge">
  <img src="https://mintcdn.com/siriusbar/c8e1wz5GgN3iYmBQ/images/racecond/15.PNG?fit=max&auto=format&n=c8e1wz5GgN3iYmBQ&q=85&s=d4858fcd084ca8186285e3bc031be6c5" alt="Flag of the last challenge" width="675" height="427" data-path="images/racecond/15.PNG" />
</Frame>
