PHP代码审计——Day 10-Anticipation

漏洞解析

extract($_POST);

function goAway() {
    error_log("Hacking attempt.");
    header('Location: /error/');
}

if (!isset($pi) || !is_numeric($pi)) {
    goAway();
}

if (!assert("(int)$pi == 3")) {
    echo "This is not pi.";
} else {
    echo "This might be pi.";
}

问题所在:当检测到攻击时,虽然有相应的防御操作,但是程序未立即停止退出,导致程序继续执行的问题。

extract:(PHP 4, PHP 5, PHP 7)

  • 功能 :将关联数组中的键名作为变量名,对应的值作为变量值,将它们导入到当前的符号表
  • 定义 : int extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] )
    $data = array("name" => "John", "age" => 30, "city" => "New York");
    
    extract($data);
    echo $name; // 输出 "John"
    echo $age; // 输出 30
    echo $city; // 输出 "New York"
    

回到有问题的代码。

程序对 pi 变量进行简单的验证,如果不是数字或者没有设置 pi 变量,程序就会执行 goAway 方法,即记录错误信息并直接重定向到 /error/ 页面。这里是对非法的操作进行了一定的处理。但是关键在于,程序在处理完之后,没有立即退出,没有exit()或die(),这样程序又会按照流程执行下去,也就到了assert语句。由于前面 pi 变量可以被用户控制,所以在这一行存在远程代码执行漏洞。assert()能够执行"中的代码,如assert("(int)phpinfo()");

构造payload:POST提交pi=phpinfo()

实际上,这种案例在真实环境下不少。例如有些CMS通过检查是否存在install.lock文件,从而判断程序是否安装过。如果安装过,就直接将用户重定向到网站首页,却忘记直接退出程序,导致网站重装漏洞的发生。

posted @ 2024-04-11 15:09  smile_2233  阅读(5)  评论(0编辑  收藏  举报