WeChall_PHP-0817
题目:
核心代码:
<?php
if (isset($_GET['which']))
{
$which = $_GET['which'];
switch ($which) {
case 0:
case 1:
case 2:
require_once $which.'.php'; break;
default:
echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
break;
}}
?>
php关键语法分析:
Switch 语句
如果您希望有选择地执行若干代码块之一,请使用 Switch 语句。
使用 Switch 语句可以避免冗长的 if..elseif..else 代码块。
语法
switch (expression)
{
case label1:
expression == label1 时执行的代码 ;
break;
case label2:
expression == label2 时执行的代码 ;
break;
default:
表达式的值不等于 label1 及 label2 时执行的代码;
}
工作原理:
对表达式(通常是变量)进行一次计算
把表达式的值与结构中 case 的值进行比较
如果存在匹配,则执行与 case 关联的代码
代码执行后,break 语句阻止代码跳入下一个 case 中继续执行,这里需要注意!!!如果没有break语句,那么会默认执行下一个case语句
如果没有 case 为真,则使用 default 语句
注:这里需要加强注意的是,php中switch/case是使用松散比较,也就是弱类型比较的,并不是=,是==
代码详解:
<?php
if (isset($_GET['which'])) //检测变量which是否设置,并且不是 NULL
{
$which = $_GET['which']; //get请求参数which
switch ($which) { //switch用法见上面的php关键语法分析,要记住这里的switch是使用的松散比较!!!下面实际测试时会写到
case 0: //还有一点很重要的,这里的case语句后面如果没有break,他会继续执行下面case语句的代码段,并不会再比较下面表达式值与case值是否相等,而是直接执行代码段
case 1:
case 2:
require_once $which.'.php'; break; //包含文件$which'.php'
default: //如果表达式的值与case的值没有一个相等的,那么就执行default语句段
echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
break;
}}
?>
这里希望我们使用文件包含,包含solution.php文件,因此,我们尝试包含0
http://www.wechall.net/challenge/php0817/index.php?which=0
发现可以包含,那么这是我们可以将0改为solution
http://www.wechall.net/challenge/php0817/index.php?which=solution
有人就要说了,这里代码显示,只能是$which=0或1或2时,才能执行对应case里的代码段。
因此,这里我就要说一说我之前提到的switch/case使用的是松散类型比较,就是当你输入solution时,它会进行
$which==0,$which==1,$which==2的比较,$which=solution时,也就是判断solution==0与solution==1与solution==2,只要有一个匹配就执行改代码段,没有匹配就执行default
这里的松散比较,也就是弱类型比较,先判断solution==0
是否为true
注:使用==
进行比较时,如果是数字与字符串进行比较(或者字符串与数字),会先将字符串类型转化成数值型再比较,字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。这里的solution因为是字母开头,最后0==0
,于是执行case 0下面的代码段,但是case 0 下面没有代码段,又没有break语句,但此时case 0 是为true的,在它代码段中没有遇到break的情况下,继续执行case 1下的代码段,又因为case 1下又没有break语句,再执行case 2下的代码段,包含文件solution.php,这时,有一个break语句,代码执行结束。
注:如果第一个case匹配成功,执行下面代码段时都没有break语句,那么再执行完所有的代码段后,再执行default下的代码段才会退出代码执行,也就是从匹配成功开始,后面的代码段只要没有break,全部执行一遍,直到遇到break为止,就不再执行后面的代码段了。
例:
<?php
$color="red";
switch ($color)
{
case "red":
echo "red";
case "blue":
echo "blue";
case "green":
echo "green";
default:
echo "all no";
}
?>
执行结果:
redbluegreenall no
参考链接:
https://www.tuziang.com/combat/1542.html
http://ju.outofmemory.cn/entry/345804