This skill focuses on determining at the source code level whether "a file operation vulnerability holds", with the core being to verify path controllability, content controllability, and execution reachability. Runtime exploitation techniques such as constructing upload bypass payloads and LFI log poisoning belong to the scope of the corresponding black-box exploit skill.
In-depth reference
- Dangerous patterns / secure pattern code comparison / EVID evidence examples for the 5 types of file vulnerabilities → references/file-vuln-patterns.md
Sink classification decision tree
According to the type of Sink function encountered, enter different audit branches:
| Sink function | Branch | Typical severity |
|---|---|---|
move_uploaded_file, copy($_FILES) |
File upload | Critical-High |
include/require/include_once/require_once |
File read + execution | Critical |
file_get_contents/readfile/fread/highlight_file |
File read | High-Medium |
file_put_contents/fwrite/fopen('w') |
File write | Critical-High |
ZipArchive::extractTo/PharData::extractTo |
Archive extraction | High |
file_exists/is_file + subsequent operation |
Race condition | Medium-High |
File upload audit points
The essence of an upload vulnerability is that three elements are satisfied simultaneously: executable extension + Web-reachable storage path + not renamed/content sanitized.
- Extension validation: blacklists easily miss
.phtml/.pht/.php5/.phar/.shtml, whitelists are safer but the case handling logic must be checked - MIME vs Magic bytes:
$_FILES['type']comes entirely from the client and can be forged;finfo_file()/getimagesize()the file header is validated but an image webshell (GIF89a + PHP code) can bypass it - Storage path controllability: whether the user can, through
../in the filename, control the storage location and escape the intended upload directory - Web root reachability: if the file is stored outside the Web root, then even if PHP is uploaded it cannot be executed directly
- Renaming strategy:
md5(time())and other predictable naming can be guessed,random_bytes()is safer
File read/include audit points
include The series both reads and executes, far more dangerous than pure read functions:
- Path concatenation pattern:
include($dir . '/' . $page . '.php')— check whether$pageis user-controllable, whether../traversal is filtered - %00 truncation: PHP < 5.3.4 can use null byte truncation for the
.phpsuffix; higher versions have fixed it but attention is still needed when auditing legacy systems - Wrapper exploitation:
php://filter/convert.base64-encode/resource=to read source code,php://inputto inject code,data://to execute payload - RFI condition:
allow_url_include=Onremote file inclusion holds whenphp.iniconfiguration - Pure read functions:
file_get_contents/readfiledo not execute but can leak sensitive configuration (database passwords, API Keys)
File write audit points
A write vulnerability requires three elements: path controllable + content controllable + the written file can be executed.
- Direct shell write:
file_put_contents($path, $content)when both parameters in - Log injection chain: logging user input → the log file is loaded by
include→ indirect code execution. Review whether the log path is predictable and whether the content is filtered - Configuration File Overwrite: Write to
.htaccess(causing.jpgto be parsed as PHP) or a PHP configuration file (inject code into<?php return [...];) - Session File Exploitation:
session.save_pathThe content of session files under
Archive Extraction Audit Points
- Zip Slip:
ZipArchive::extractTo()Does not validate the../../in entry names, malicious archives can write files to arbitrary directories - PharData: Same as ZipArchive,
extractTo()has path traversal risk - Safe Extraction: Before extraction, iterate over entry names and reject paths containing
..; or extract to a temporary directory and validate each file before moving
Race Condition Audit Points
- TOCTOU:
is_file($path)After the check passes and beforeunlink($path)executes, an attacker replaces the file with a symbolic link → arbitrary file deletion - Upload Race: The file is saved first and then validated and deleted; during the window, send a large number of concurrent requests to access the uploaded PHP file
- Symbolic Link Following:
file_get_contents($userPath)If$userPathis a symbolic link, the link target file is read, bypassing directory restrictions - Atomic Operation:
rename()is an atomic operation and can be used for safe replacement; first write a temporary file and thenrenameto the target location to avoid races
Detection Checklist
- All file-related EVID_* evidence points have been reviewed one by one
- The extension validation method of the upload functionality has been confirmed (whitelist vs blacklist vs no validation)
- Whether the upload storage path is inside the web root and whether it can be accessed directly has been verified
- The sources and filtering logic of include/require path parameters have been traced
- The exploitability of wrappers such as php://filter under the current configuration has been assessed
- The path and content sources of file_put_contents/fwrite have been traced
- The entry name validation of archive extraction functions has been checked
- TOCTOU patterns (check→operation interval) have been identified
- For points with insufficient filtering, bypass ideas have been provided or marked "to be verified"
- Severity scoring uses a unified formula, consistent with the pipeline