关于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
上面没有出现重定向符号,但是已经实现了它的功能,其它的符号也可以依次处理