关于shell中的eval 对于命令注入后,一条命令可能需要的字符大概有这几个吧

$ ' " ; && || [ ] ` > <; 

可以看到是很多的,所以黑名单过滤的方法肯定是有问题的,因为是肯可能绕过去的。 加入对所有GET, POST的参数都用了htmlspecialchars做了处理,那么所有的< > 都会被转义成html字符 那么就没办法使用重定向符号了吗? 参考下下面的利用eval来使用管道符号 The shell takes care of pipes and I/O redirection before variable substitution, so it never recognizes the pipe symbol inside pipe. The result is that the three arguments |, wc, and -l are passed to ls as arguments.

742 ~>set -x
742 ~>pipe="|"
+ pipe='|'
743 ~>echo $pipe
+ echo '|'
|
744 ~>ls $pipe wc -l
+ ls --color=auto '|' wc -l
ls: 无法访问 |: 没有该文件或目录
ls: 无法访问 wc: 没有该文件或目录
745 ~>eval ls $pipe wc -l
+ eval ls '|' wc -l
++ wc -l
++ ls --color=auto
26

The first time the shell scans the command line, it substitutes | as the value of pipe. Then eval causes it to rescan the line, at which point the | is recognized by the shell as the pipe symbol. The eval command is frequently used in shell programs that build up command lines inside one or more variables. If the variables contain any characters that must be seen by the shell directly on the command line (that is, not as the result of substitution), eval can be useful. Command terminator (;, |, &), I/O redirection (<, >), and quote characters are among the characters that must appear directly on the command line to have any special meaning to the shell. 也就是说我们只要能够获得这些特殊符号,就可以使用eval来利用字符型形式的符号来执行代码 参考下ascii码表

Binary 	        Oct 	Dec 	Hex 	Glyph
011 1011 	073 	59 	3B 	;
011 1100 	074 	60 	3C 	<
011 1101 	075 	61 	3D 	=
011 1110 	076 	62 	3E 	>
011 1111 	077 	63 	3F 	?

101 1011 	133 	91 	5B 	[
101 1100 	134 	92 	5C 	\
101 1101 	135 	93 	5D 	]
101 1110 	136 	94 	5E 	^
101 1111 	137 	95 	5F 	_

那么

wang@wang-desktop:~$ a=$(php -r 'echo chr(62);')
wang@wang-desktop:~$ echo $a # Output >
>
wang@wang-desktop:~$ eval ls $a ls_out.txt
wang@wang-desktop:~$ cat ls_out.txt 
a.doc
desktop
dj
doc

上面没有出现重定向符号,但是已经实现了它的功能,其它的符号也可以依次处理