1. extract变量覆盖漏洞
<?php
$flag='xxx';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag));
if($shiyan==$content)
{
echo'ctf{xxx}';
}
else
{
echo'Oh.no';
}
}
?>
当file_get_contents函数里面是一个不可读的路径,那么content的内容就是空,然后我们在初始化的时候将shiyan置空,那么$shiyan==$content就会成立,就会直接输出我们想要的内容。
2. 绕过空白字符
<?php
$info = "";
$req = [];
$flag="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
ini_set("display_error", false); //为一个配置选项设置值
error_reporting(0); //关闭所有PHP错误报告
if(!isset($_GET['number'])){
header("hint:26966dc52e85af40f59b4fe73d8c323a.txt"); //HTTP头显示hint 26966dc52e85af40f59b4fe73d8c323a.txt
die("have a fun!!"); //die — 等同于 exit()
}
foreach([$_GET, $_POST] as $global_var) { //foreach 语法结构提供了遍历数组的简单方式
foreach($global_var as $key => $value) {
$value = trim($value); //trim — 去除字符串首尾处的空白字符(或者其他字符)
is_string($value) && $req[$key] = addslashes($value); // is_string — 检测变量是否是字符串,addslashes — 使用反斜线引用字符串
}
}
function is_palindrome_number($number) {
$number = strval($number); //strval — 获取变量的字符串值
$i = 0;
$j = strlen($number) - 1; //strlen — 获取字符串长度
while($i < $j) {
if($number[$i] !== $number[$j]) {
return false;
}
$i++;
$j--;
}
return true;
}
if(is_numeric($_REQUEST['number'])) //is_numeric — 检测变量是否为数字或数字字符串
{
$info="sorry, you cann't input a number!";
}
elseif($req['number']!=strval(intval($req['number']))) //intval — 获取变量的整数值
{
$info = "number must be equal to it's integer!! ";
}
else
{
$value1 = intval($req["number"]);
$value2 = intval(strrev($req["number"]));
if($value1!=$value2){
$info="no, this is not a palindrome number!";
}
else
{
if(is_palindrome_number($req["number"])){
$info = "nice! {$value1} is a palindrome number!";
}
else
{
$info=$flag;
}
}
}
echo $info;
trim函数会移除空白,然后也会移除
- “\0” - NULL
- “\t” - 制表符
- “\n” - 换行
- “\x0B” - 垂直制表符
- “\r” - 回车
- “ “ - 空格
$value = trim($value)
之后$value为%0c191,四个字符,过滤了%00(NULL)
addslashes
会添加反斜杠
- 单引号(’)
- 双引号(”)
- 反斜杠(\)
- NULL
is_numeric
只是检测的是否是数字,01a就不是数字,0x1十六进制是,我们的是is_numeric($_REQUEST['number'])
这边是通过$_REQUEST[‘number’]进行判断,所以直接是false,然后进入下一个判断,下一个是判断是否是一个191,也就是开头首个数字和最后的数字是否相等,intval($req[‘number’]),$req[‘number’]是一个%0c191,然后intval之后就是191,这边如果是%00%0c191那么转换就是0这个时候是不相等的。他们两个不相等就会跳过去,然后最后得is_palindrome_number,这个函数时候number是%0c191是四个肯定是不对称所以跳过。