Committed – CTF Writeup

Platform: TryHackMe
Instructions:
Oh no, not again! One of our developers accidentally committed some sensitive code to our GitHub repository. Well, at least, that is what they told us… the problem is, we don’t remember what or where! Can you track down what we accidentally committed?
Access this challenge by deploying the machine attached to this task by pressing the green “Start Machine” button. You will need to use the in-browser view to complete this room. Don’t see anything? Press the “Show Split Screen” button at the top of the page.
The files you need are located in /home/ubuntu/commited on the VM attached to this task.
Upon opening the task file we are greeted with the following structure of the directory:
The Readme file holds no information of value, simply stating that the project is to be used for database management. The main.py simple consists of some commands to simply mySQL queries.
The real item we want to look at here is the .git file. Which is the necessary directory in any git project in order to manage changes and keep track of any changes as well as any deleted files that we have.
The structure of the git folder is as follows:
This matches the usual structure of a github directory:
- branches – Contains references to local branches in the repository (This is really an outdated repository, and all branch references in modern git are located inside of refs/)
- hooks – Stores scripts that automatically execute at specific Git events like commits or pushes
- info – Contains repository metadata including local exclusion rules and reference information
- logs – Maintains history of all reference changes (reflog) for branches and HEAD movements
- objects – Stores all Git data as compressed objects including commits, trees, blobs, and tags using SHA-1 hashes
- refs – Contains pointers to commit objects for branches, tags, and remote references
- COMMIT_EDITMSG – Temporary file that stores the commit message being edited during a commit operation
- HEAD – Points to the currently checked out branch or commit
- config – Contains repository-specific configuration settings including remotes and branch tracking
- description – Holds a text description of the repository used by web interfaces like GitWeb
- index – Binary file representing the staging area with files prepared for the next commit
The COMMIT_EDITMSG really stands out the most to me, immediately as it is a temporary file. However, inside of it we just have the string finished
Looking at the HEAD file, we see that the currently checked branch (or the section of last commit) is the master branch.
ref: refs/heads/master
Heading over to the file for that inside of the refs directory, we get the pointer, which Git encodes as a SHA256 hash:
28c36211be8187d4be04530e340206b856198a84
Thats not really all the important but just a cool fact, so now I decided to head over to the /logs
what I found was that there was an another branch besides the master branch called dbint
Inside of the /logs
folder we have the HEAD
file, which is a collection of all of the commit messages and other logs for all branches. There is also a /refs
directory, which contains those logs but for individual branches.
Looking at the HEAD
file I notice the following:
3a8cc16f919b8ac43651d68dceacbb28ebb9b625 c56c470a2a9dfb5cfbd54cd614a9fdb1644412b5 fumenoid <fumenoid@gmail.com> 1644741999 -0800 commit: Oops
This might be the commit message we are looking for!
Breaking this commit down, bit by bit:
- 3a8cc16f919b8ac43651d68dceacbb28ebb9b625 – SHA-1 hash of the previous commit (where HEAD was before)
- c56c470a2a9dfb5cfbd54cd614a9fdb1644412b5 – SHA-1 hash of the new commit (where HEAD moved to)
- fumenoid fumenoid@gmail.com – Name and email of the person who made the commit
- 1644741999-0800– Unix timestamp
- commit: Oops – The action type and commit message
Now knowing this we have the two hashes of the commits that we might be interested in! We can go ahead and access these hashes inside of theobjects
directory
At first the object directory looks like it has an lot of folders! But in reality each folder is title with the first two characters of a given SHA-1 hash. So for instance our previous commit 3a8cc16f919b8ac43651d68dceacbb28ebb9b625 is located in 3a. Looking inside 3a we have a massive file, but using the git command line utility show, we can actually just reference the commits using the files themselves. So say goodbye to those files!
Unzip the file if you have not already and go into the directory for it so that we can call git commands
We call:
git show 3a8cc16f919b8ac43651d68dceacbb28ebb9b625
and we get the following output:
Author: fumenoid <fumenoid@gmail.com>
Date: Sun Feb 13 00:45:14 2022 -0800
DB check
diff --git a/main.py b/main.py
index 161979c..54d0271 100644
--- a/main.py
+++ b/main.py
@@ -3,8 +3,8 @@ import mysql.connector
def create_db():
mydb = mysql.connector.connect(
host="localhost",
- user="", # Username Goes Here
- password="" # Password Goes Here
+ user="root", # Username Goes Here
+ password="flag{REDACTED_GO_DO_THE_CTF}" # Password Goes Here
)
mycursor = mydb.cursor()
@@ -15,8 +15,8 @@ def create_db():
def create_tables():
That looks like a flag to me!
Fundamentally here though, what has the security error that this flag was trying to show us? It seems that the author of this repo fuemnoid. Thought it would be a good idea to hardcode the credentials needed to access the SQL server and committed that to the repository. This is horrible practice for obvious reasons. So whats the work around? ENVIRONMENT VARIABLES In python specifically (which is what this repo is programmed in) you can use an external file to load these environment variables with the OS module.
For example we could have a simple .env file like this:
# .env (DO NOT commit this file!)
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=flag{REDACTED_GO_DO_THE_CTF}
And then, our function could instead look like this:
try:
mydb = mysql.connector.connect( host=os.environ.get('DB_HOST', 'localhost'),
user=os.environ.get('DB_USER'),
password=os.environ.get('DB_PASSWORD') )