Sitemap

šŸ“ [Writeup] Proving Grounds: BitForge (Linux)

Git Dumps, Database Hacking, and the Python Library Hijack

--

šŸš€ TL;DR

Box: BitForge (Linux)

Vulnerability: Exposed .git directory, SOPlanning RCE (CVE-2024–27115), Python Library Hijacking.

Entry: Git Dump MySQL Creds Modify Admin Password in DB RCE via File Upload.

Lateral Movement: Using pspy64 to catch a root cron job exposing user credentials.

Privilege Escalation: Hijacking a Python library in a sudo-enabled script (flask_password_changer).

Introduction:

In this lab, I tackled several security problems. I started by finding an exposed .git directory. After that, I bypassed authentication by editing the database, used a known RCE in SOPlanning, and finally used PSPY to find credentials used by privileged processes.

Phase 1: Recon & The Git Leak

Nmap scan revealing the exposed .git directory

I began by running a standard Nmap scan.
Command:

nmap -sV -sC -O -T4 -n -Pn 192.168.61.186

The scan showed the web server had an exposed .git directory. At first, I browsed the directory manually. Later, I dumped the entire repository to rebuild the source code.

The Git Dump:

wget -r -np -nc -l inf http://bitforge.lab/.git/
# OR better yet
git-dumper http://bitforge.lab/.git/ bitforge_git_2

After restoring the repo with ā€˜git checkout .’, I used ā€˜git log’ to check the history and found a commit containing credential data.

Recovering database credentials from git history

Phase 2: Database Takeover & Authentication Bypass

Using the credentials I found in the git history, I connected to the remote MySQL server.

Connecting to the remote MySQL instance

Issue: I hit an SSL error (ERROR 2026).
Fix: Use the — skip-ssl flag.

mysql -h 192.168.61.186 -u BitForgeAdmin -p --skip-ssl

I listed the databases and found one named soplanning. Inside, the planning_user table contained the Admin password hash.

The Pivot:
I couldn’t crack the SHA1 hash, and updating it with a new one didn’t work, probably because of extra logic or a salt.
Solution: I found a rip version of SOPlanning that mentioned the default admin password hash.

Press enter or click to view image in full size
Updating the admin password hash directly in the database

I changed the database directly to reset the admin password to ā€œadminā€.

UPDATE planning_user SET password= 'df5b909019c9b1659e86e0d6bf8da81d6fa3499e' WHERE user_id = 'ADM';

After this, I could log in to the web portal at http://plan.bitforge.lab/www.

Phase 3: RCE (CVE-2024–27115)

I identified that the software was Simple Online Planning v1.52.01. A quick search showed it was vulnerable to CVE-2024–27115 (Unrestricted File Upload / RCE).

I used a public Python exploit, but I needed to change the URL in the script because my target was in the /www subdirectory.

Get Ekemini Bassey’s stories inĀ yourĀ inbox

Join Medium for free to get updates fromĀ thisĀ writer.

Command:

python3 exp1.py -t http://plan.bitforge.lab/www -u admin -p admin

The script gave me a web shell. I upgraded it to a full reverse shell using a PHP payload on Port 80.

Executing the Python exploit for CVE-2024–27115

Phase 4: Lateral Movement (PSPY)

I was limited to the www-data user. I noticed a directory, /opt/password_change_app, owned by the user jack.
The web page hinted that an automated password change system was being set up, which often means a cron job is running.

Press enter or click to view image in full size
PSPY64 capturing the root cron job with cleartext credentials

Since I couldn’t read the root crontab, I uploaded pspy64 to watch running processes live.

The Catch:

CMD: UID=0    PID=36476    /bin/sh -c mysqldump -u jack -p'j4cKF0rg3@445' soplanning ...

Root was running a backup script every minute and passing Jack’s password in plain text as an argument.

Credentials: jack: j4cKF0rg3@544
I switched to the user jack (su jack) and grabbed local.txt.

local.txt found

Phase 5: Privilege Escalation (Python Library Hijack)

Next, I checked which sudo privileges jack had:

sudo -l
# (root) NOPASSWD: /usr/bin/flask_password_changer

The script was a Python Flask app. I looked for ways to hijack a Python library, using GTFOBins as a guide.
If I could write to a file the script imports, I could run code as root with sudo.

Sudo -l revealing the vulnerable Flask script

The Exploit:
I found a file, app.py, in the same directory that I could modify. I added a payload to open a shell.

import os
os.system("/bin/bash")

Execution:

sudo /usr/bin/flask_password_changer

This exploit gave me root access.

Root shell achieved via Python library hijacking

The Fix

Never expose .git directories to the public web.

Disable remote root/admin login, or require strict SSL certificate validation for MySQL.

Never pass passwords as command-line arguments in cron jobs (mysqldump -pPassword). Use a .my.cnf config file instead.

Avoid giving sudo rights to custom scripts that import libraries from directories users can write to.

Lessons Learned

Git history is permanent. Even if you delete a file, it stays in the commit log.

If you can’t crack a password hash but have write access to the database, overwrite it with a hash you know.

If you think automation is running but can’t view the cron file, pspy can show you what’s happening.

--

--

Ekemini Bassey
Ekemini Bassey

Bridging the Gap Between Security & Development