1.第一步看源码
2.看source.php
观察源码逻辑,首先可以发现白名单是只有source.php和hint.php,通过访问hint.php我们可以知道flag在ffffllllaaaagggg文件中
但很明显我们无法直接访问,所以当然是继续分析逻辑
3.审计source.php文件
if (! empty(
R
E
Q
U
E
S
T
[
′
f
i
l
e
′
]
)
/
/
_REQUEST['file']) //
REQUEST[′file′])//_REQUEST[‘file’]值非空
&& is_string(
R
E
Q
U
E
S
T
[
′
f
i
l
e
′
]
)
/
/
_REQUEST['file']) //
REQUEST[′file′])//_REQUEST[‘file’]值为字符串
&& emmm::checkFile($_REQUEST[‘file’]) //能够通过checkFile函数校验
) {
include
R
E
Q
U
E
S
T
[
′
f
i
l
e
′
]
;
/
/
包
含
_REQUEST['file']; //包含
REQUEST[′file′];//包含_REQUEST[‘file’]文件
exit;
} else {
echo “
<img src=“https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg” />”;
//打印滑稽表情
}
这段代码告诉们需要满足三个条件
1.值为非空
2.值为字符串
3.能够通过checkFile()函数校验
否则打印滑稽
4.查看checkfile
highlight_file(FILE); //打印代码
class emmm //定义emmm类
{
public static function checkFile(&
p
a
g
e
)
/
/
将
传
入
的
参
数
赋
给
page)//将传入的参数赋给
page)//将传入的参数赋给page
{
w
h
i
t
e
l
i
s
t
=
[
"
s
o
u
r
c
e
"
=
>
"
s
o
u
r
c
e
.
p
h
p
"
,
"
h
i
n
t
"
=
>
"
h
i
n
t
.
p
h
p
"
]
;
/
/
声
明
whitelist = ["source"=>"source.php","hint"=>"hint.php"];//声明
whitelist=["source"=>"source.php","hint"=>"hint.php"];//声明whitelist(白名单)数组
if (! isset(
p
a
g
e
)
∣
∣
!
i
s
s
t
r
i
n
g
(
page) || !is_string(
page)∣∣!isstring(page)) {//若$page变量不存在或非字符串
echo “you can’t see it”;//打印"you can’t see it"
return false;//返回false
}
if (in_array($page, $whitelist)) {//若$page变量存在于$whitelist数组中
return true;//返回true
}
$_page = mb_substr(//该代码表示截取$page中'?'前部分,若无则截取整个$page
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//url解码$page
$_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为字符串,否则返回false2.第二个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,第二个语句直接判断$page,不可用
第三个语句截取’?‘前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,
checkFile函数中解码一次,仍会解码为’?’,仍可通过第四个if语句校验。(’?‘两次编码值为’%253f’),构造url:
5.所以就能执行包含文件
payload:
http://175.24.184.228:10011/?file=source.php?../…/…/…/…/ffffllllaaaagggg
这边ffffllllaaaagggg文件前面的路径加…/是因为他和index.php不在同一个目录下,所以读取的是上级目录。