攻防世界-web-新手练习区(5)-simple_php

题目

[外链图片转存失败(img-vYmE1yhe-1562376306635)(E:\CTF\小白学习总结\攻防世界\web\picture\12.ti.PNG)]

[外链图片转存失败(img-xwutjZKZ-1562376306637)(E:\CTF\小白学习总结\攻防世界\web\picture\12.1.PNG)]

writeup

分析代码:

<?php
show_source(__FILE__);
include("config.php");
$a=@$_GET['a'];
$b=@$_GET['b'];
if($a==0 and $a){
    echo $flag1;
}
if(is_numeric($b)){
    exit();
}
if($b>1234){
    echo $flag2;
}
?> 

可知:

若想得到flag1,则必须使得a==0且a不为0。

故有:

a=0a   //详情见知识点1-php弱类型

若想得到flag2,则必须使得b不为数字或数字字符串(详情见知识点2-is_numeric() 函数),且b>1234

故有:

b=12345%00   //详情见知识点3-%00截断

综上所述,有:

?a=0a&b=12345%00   //a与b用&连接

得到flag

[外链图片转存失败(img-WDGw5AOV-1562376306638)(E:\CTF\小白学习总结\攻防世界\web\picture\12.flag.PNG)]

知识点

1、php弱类型之“”与“=”

<?php
$a == $b ;
$a === $b ;
?>

== 在进行比较的时候,会先将字符串类型转化成相同,再比较

如果一个数值和字符串进行比较的时候,会将字符串转换成数值

=== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较

<?php
2 var_dump("admin"==0);  //true
3 var_dump("1admin"==1); //true
4 var_dump("admin1"==1) //false
5 var_dump("admin1"==0) //true
6 var_dump("0e123456"=="0e4456789"); //true 
7 ?> 

观察上述代码,

“admin”==0 比较的时候,会将admin转化成数值,强制转化,由于admin是字符串,转化的结果是0自然和0相等;

“1admin”==1 比较的时候会将1admin转化成数值,结果为1;

而“admin1“==1 却等于错误,也就是"admin1"被转化成了0;

“0e123456”=="0e456789"相互比较的时候,会将0e这类字符串识别为科学技术法的数字,0的无论多少次方都是零,所以相等。

所以题目中,

if($a==0 and $a)

若满足,则需向上面例子中的

var_dump("admin"==0);  //true
var_dump("1admin"==1); //true

相类似,故我选择了

a=0a

也可以有其他的构造方法。

2、is_numeric() 函数

is_numeric() 函数用于检测变量是否为数字或数字字符串。


<?php
$var_name1=678;
$var_name2="a678";
$var_name3="678";
$var_name4="runoob.com";
$var_name5=698.99;
$var_name6=array("a1","a2");
$var_name7=+125689.66;
if (is_numeric($var_name1))
{
    echo "$var_name1 是数字" . PHP_EOL;
}
else
{
    echo "$var_name1 不是数字" . PHP_EOL ;
}
if (is_numeric($var_name2))
{
    echo "$var_name2 是数字" . PHP_EOL ;
}
else
{
    echo "$var_name2 不是数字" . PHP_EOL ;
}
 
$result=is_numeric($var_name3);
echo "[ $var_name3 是数字吗? ]" .var_dump($result) . PHP_EOL;
$result=is_numeric($var_name4);
echo "[ $var_name4 是数字吗? ]" .var_dump($result) . PHP_EOL;
$result=is_numeric($var_name5);
echo "[ $var_name5 是数字吗? ]" .var_dump($result) . PHP_EOL;
$result=is_numeric($var_name6);
echo "[ $var_name6 是数字吗? ]" .var_dump($result) . PHP_EOL;
$result=is_numeric($var_name7);
echo "[ $var_name7 是数字吗? ]" .var_dump($result);
?>

输出结果为:

678 是数字
a678 不是数字
bool(true)
[ 678 是数字吗? ]
bool(false)
[ runoob.com 是数字吗? ]
bool(true)
[ 698.99 是数字吗? ]
bool(false)
[ Array 是数字吗? ]
bool(true)
[ 125689.66 是数字吗? ]

即:

若变量为数字或数字字符串,则if()语句为真。

题目中,

if(is_numeric($b)){
    exit();
}

当b为数字或数字字符串,则执行exit()

当b不为数字或数字字符串,则执行下一步。

为了得到flag2,则b应不为数字或数字字符串。

3、%00截断

%00是空格的意思

具有截断作用

为使b不为数字或数字字符串,且b>1234

故使用%00的截断

即:

b=12345%00
发布了54 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wyj_1216/article/details/94831394