由于程序没有过滤$a_query变量,所以攻击者可以用分号来追加执行命令。
攻击者输入如下请求可以执行cat /etc/passwd命令:
www.example.com>http://victim/test_6.php?a_querywww.example.com;cat /etc/passwd
PHP的命令执行函数还有system(), passthru(), popen()和``等。命令执行函数非常危险,慎用。如果要使用一定要严格检查用户输入。
http://www.acnow.net/ 4JX
解决方法:
http://www.acnow.net/ 4JX
要求程序员使用escapeshellcmd()函数过滤用户输入的shell命令。
http://www.acnow.net/ 4JX
启用safe_mode可以杜绝很多执行命令的问题,不过要注意PHP的版本一定要是最新的,小于PHP-
http://www.acnow.net/ 4JX
5、sql_inject
http://www.acnow.net/ 4JX
如下的SQL语句如果未对变量进行处理就会存在问题:
select * from login where user='$user' and pass='$pass'
攻击者可以用户名和口令都输入1' or 1='1绕过验证。
http://www.acnow.net/ 4JX
不过幸亏PHP有一个默认的选项magic_quotes_gpc = On,该选项使得从GET, POST, COOKIE来的变量自动加了addslashes()操作。上面SQL语句变成了:
select * from login where user='1\' or 1=\'1' and pass='1\' or 1=\'1'
http://www.acnow.net/ 4JX
从而避免了此类sql_inject攻击。
http://www.acnow.net/ 4JX
对于数字类型的字段,很多程序员会这样写:
http://www.acnow.net/ 4JX
select * from test where id=$id
http://www.acnow.net/ 4JX
由于变量没有用单引号扩起来,就会造成sql_inject攻击。幸亏MySQL功能简单,没有sqlserver等数据库有执行命令的SQL语句,而且PHP的mysql_query()函数也只允许执行一条SQL语句,所以用分号隔开多条SQL语句的攻击也不能奏效。但是攻击者起码还可以让查询语句出错,泄漏系统的一些信息,或者一些意想不到的情况。
解决方法:
要求程序员对所有用户提交的要放到SQL语句的变量进行过滤。 http://www.acnow.net/ y
即使是数字类型的字段,变量也要用单引号扩起来,MySQL自己会把字串处理成数字。
在MySQL里不要给PHP程序高级别权限的用户,只允许对自己的库进行操作,这也避免了程序出现问题被 SELECT INTO OUTFILE ... 这种攻击。
6、利用好open_basedir来解决一些安全问题
http://www.acnow.net/ 4JX
利用open_basedir可以对脚本操作路径进行限制,这里再介绍一下它的特性。用open_basedir指定的限制实际上是前缀,不是目录名。也就是说 "open_basedir = /dir/incl" 也会允许访问 "/dir/include" 和 "/dir/incls",如果它们存在的话。如果要将访问限制在仅为指定的目录,用斜线结束路径名。例如:"open_basedir = /dir/incl/"。 http://www.acnow.net/ y
可以设置多个目录,在Windows中,用分号分隔目录。在任何其它系统中用冒号分隔目录。作为Apache模块时,父目录中的open_basedir路径自动被继承。