题目这里面给了我们提示,是代码审计。 这里面我们访问source.php这样我们可以获得这 <?php highlight_file(FILE); class emmm { public static function checkFile(&$page) //传入了变量page,也就是我们刚刚传进来的file { // 这里定义了白名单
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
"
]
;
i
f
(
!
i
s
s
e
t
(
whitelist = ["source"=>"source.php","hint"=>"hint.php"]; if (! isset(
whitelist=["source"=>"source.php","hint"=>"hint.php"];if(!isset(page) || !is_string(
p
a
g
e
)
)
/
?
为
了
返
回
t
r
u
e
两
个
条
件
必
须
满
足
1
p
a
g
e
存
在
2
p
a
g
e
是
字
符
串
,
这
里
和
外
层
的
判
断
f
i
l
e
一
致
基
本
是
再
次
判
断
了
一
遍
?
/
e
c
h
o
"
y
o
u
c
a
n
′
t
s
e
e
i
t
"
;
r
e
t
u
r
n
f
a
l
s
e
;
i
f
(
i
n
a
r
r
a
y
(
page)) { /*为了返回 true 两个条件必须满足 1 page存在 2 page是字符串 , 这里和外层的判断file 一致基本是再次判断了一遍*/ echo "you can't see it"; return false; } if (in_array(
page))/?为了返回true两个条件必须满足1page存在2page是字符串,这里和外层的判断file一致基本是再次判断了一遍?/echo"youcan′tseeit";returnfalse;if(ina?rray(page, $whitelist)) { return true; } /in_array(search,array,type) 函数搜索数组中是否存在指定的值, 白名单过滤,需要返回了ture 所以这里我们传入的page或者是经过截断之后的page必须是soure.php或hint.php, 这里是正常的访问,我们需要构造文件任意包含,所以这里传入的不满足条件,这里不是注意的点,往下继续看/ $_page = mb_substr(
p
a
g
e
,
0
,
m
b
s
t
r
p
o
s
(
page, 0, mb_strpos(
page,0,mbs?trpos(page . ‘?’, ‘?’) ); /这里mb_sustr 是个截断,返回0到mb_strpos之间的内容,而mb_strps 则是查找第一次出现的位置,所以基本可以理解为获取page 两个?之间的字符串,也就是获取file两个?之间的字符串,放到url中就是http://ip/?file=ddd?中的file=ddd/ if (in_array($_page, $whitelist)) { return true; } //这里和上面类似 查看_page 是否在白名单中
p
a
g
e
=
u
r
l
d
e
c
o
d
e
(
_page = urldecode(
p?age=urldecode(page); // 这里发现对_page进行了一次decode解码, $_page = mb_substr(//获取两个??之间的内容
p
a
g
e
,
0
,
m
b
s
t
r
p
o
s
(
_page, 0, mb_strpos(
p?age,0,mbs?trpos(_page . ‘?’, ‘?’) ); // 这里是我们要绕过的点,从这里往上看 尝试构造 if (in_array($_page, KaTeX parse error: Expected 'EOF', got '}' at position 134: …false; }? } if (…_REQUEST[‘file’]) && is_string(KaTeX parse error: Expected 'EOF', got '&' at position 27: …ile']) &?& emmm::checkFi…_REQUEST[‘file’]) ) { include KaTeX parse error: Expected 'EOF', got '}' at position 37: … exit; }? else { …_REQUEST[‘file’]) 为ture,回到checkFile 函数分析如何返回true*/ ?>
可以看到函数代码中有四个if语句 第一个if语句对变量进行检验,要求
p
a
g
e
为
字
符
串
,
否
则
返
回
f
a
l
s
e
第
二
个
i
f
语
句
判
断
page为字符串,否则返回false 第二个if语句判断
page为字符串,否则返回false第二个if语句判断page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
存
在
则
返
回
t
r
u
e
第
三
个
i
f
语
句
判
断
截
取
后
的
whitelist数组中,存在则返回true 第三个if语句判断截取后的
whitelist数组中,存在则返回true第三个if语句判断截取后的page是否存在于
w
h
i
t
e
l
i
s
t
数
组
中
,
截
取
whitelist数组中,截取
whitelist数组中,截取page中’?‘前部分,存在则返回true 第四个if语句判断url解码并截取后的
p
a
g
e
是
否
存
在
于
page是否存在于
page是否存在于whitelist中,存在则返回true 若以上四个if语句均未返回值,则返回false 有三个if语句可以返回true,第二个语句直接判断$page,不可用 第三个语句截取’?‘前部分,由于?被后部分被解析为get方式提交的参数,也不可利用 第四个if语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为’?’,仍可通过第四个if语句校验。(’?‘两次编码值为’%253f’),构造url: 所以我们的payload 就是 file=source.php?file=source.php%253f…/…/…/…/…/ffffllllaaaagggg ———————————————— 版权声明:本文为CSDN博主「黑仔丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_42404383/article/details/103688509
同时我们也可以看到源码里面有一个hint.php所以我们接着访问这个网站 这里面是一个文件包含所以我们可以自己构建一个url index.php?file=hint.php?../…/…/…/…/ffffllllaaaagggg 这里面的…/为上一级目录。 访问这个网站我们就可以 得到flag了。 flag{9724ee82-8f8b-49a6-ae1c-111265469bde}
|