网站地图    收藏   

主页 > 后端 > 网站安全 >

sql注入解析(二)执行注入 - 网站安全 - 自学p

来源:自学PHP网    时间:2015-04-17 11:59 作者: 阅读:

[导读] 上一篇:http://www.2cto.com/Article/201209/153277.html探查程序是否存在sql注入漏洞:利用字符串数据:1、提交一个单引号,观察是否处理出错。2、提交两个单引号,两个单引号在数据库中会被...

上一篇:http://www.2cto.com/Article/201209/153277.html
探查程序是否存在sql注入漏洞

利用字符串数据:

1、提交一个单引号,观察是否处理出错。

2、提交两个单引号,两个单引号在数据库中会被转义,当做字符单引号处理,如果错误消息,则说明程序可能存在sql注入漏洞。

3、 提交良性数据,oracle中’| |’keyword,ms-sql中’+'keyword,mysql中’ ‘keyword,上面这三种输入都等同于keyword字符串,根据数据库类型选择输入,查看和输入keyword结果是否相同。

利用数字数据:

1、 假如原始URL为http://www.2cto.com /select.jsp?id=4

可以把4改成(1+3),查看输出是否一样。如果一样,说明可能存在sql注入漏洞。

2、 如果上面验证输出一样,可以利用复杂些的sql语句,进一步验证。ASCII命令返回指定字符的ASCII码,如ASCII(‘A’)等同于65,A的ASCII码为65。上面的4就可以用(ASCII(‘A’)-61)替换。

3、 如果单引号被过滤上面的URL就无效了,但是可以利用数字,如数字1的ascii码为49, 可以修改为(ASCII(1)-45)。

PS:如果是直接在URL中附带有效载荷,就必须对上面这些字符URL编码,&:%26, =:%3d,  查询字符串中不允许有空格,空格要编码为+或者%20;由于空格编码为+,所以想使用+,就要编码成%2b,分号编码成%3b。 如1+1,经过URL编码就成为1%2b1。在线编码解码工具:http://www.baidu.com/baidu?word=url%B1%E0%C2%EB&sg=123

 

利用不同的语句注入:

1.  select是最常见的可利用的语句,如上面的登陆绕过密码,就是select语句。select语句一般是利用where子句,利用注释字符注释掉。

2. insert语句,也可以成为sql注入的对象。假设一个web程序用户注册的语句是这样写的 insert into user (username, password, Id, privs) value(‘youthflies’, ‘passwd’, 1234, 2), 如果存在sql注入漏洞,我们就可以任意指定自己的Id和privs了,前提是我们构造出来的语句没有语法错误,即其他字段的的个数和类型必须正确。我们在注册一个username为 youthflies’, ‘passwd’, 11111, 1)– 的用户,这样我们就成功注册了一个Id为11111,权限为1的用户。当我们无法得知其他字段的个数和类型时,可以这样试,username分别输入 youthflies’,1)– ;    youthflies’, 1,1)– ;    youthflies’,1,1,1)– ;    youthflies’, 1,1,1,1)– 。如果1不行,换做2000试试。很多数据库都将数字隐式地转化为字符串,会将2000隐式地转化为基于数据的数据类型。

3、 update语句。update语句与insert语句类似,只不过多了一个where语句进行范围的判断。加入用户修改密码的功能,在后台的sql体现为 update users set password=’newpasswd’ where username=’youthflies’ and password=’passwd’, 修改密码要先判断以前的密码是否正确。我们在username里输入 admin– 就可以绕过密码验证,修改admin的密码,或者更具破坏性的输入 admin’ or 1=1– ,这样可以修改全部用户的密码,一旦发生就会造成严重破坏。

4. delete语句。与update语句类似,不再赘述。

5.  union操作符。sql使用union操作符将两个或几个查询结果组合到一个结果中。如果一个web程序的select语句产生sql注入,我们可以使用union操作符执行另外一次独立的查询并将结果合并在第一次查询结果中输入。例如:有个select 语句,select username, age, email from user where username=’youthflies’ ,我们username输入 youthflies’ union select username ,age,password from user where username=’youthflies’– ,这样最终的sql语句变成select username,age,email from user where username=’youthflies’ union select username, age, password from user where username=’youthflies’–’ ,这样我们手动构造了一次查询,返回了用户密码。

但是实施这样的注入需要两个条件,1 我们必须保证两次查询的结果可以正常融合,个数和类型必须兼容;2 我们必须知道数据库的表名和有关列名。如果以上两点不满足,我们构造的union语句产生的结果可能有误,而错误有可能被后台友好处理,无法进一步获取信息。 但是数据库会默认将数字转化为字符串,也会将NULL转化为任意类型的数据,我们可以利用这一点。所以如果不知道某一列的数据类型,我们可以select NULL。

我们可以利用NULL来探测结果的列数,依次输入 youthflies’ union select NULL–  ;youthflies’ union select NULL, NULL– ;youthflies’ union select NULL,NULL,NULL– 当语句正常执行了,就说明列数正确了;也可以利用order by子句来判断列数,依次输入 youthflies’ order by 1– ; youthflies’ order by 2–; youthflies’ order by 3–(order by 3指按第三个参数排序) 直到发生错误,也可以判断出列数。

确定了列数,下一步就是确定类型了。假设列数为3依次输入youthflies’ union select ‘a’, NULL,NULL– ,youthflies’ union select NULL, ‘a’, NULL– ;youthflies’ union select NULL,NULL ,’a'– ,哪一行执行正确,就说明那一列的类型是字符串。PS:oracle数据库要求每个select语句必须有where子句,我们可以再全局表中select,youthflies’ union select NULL from DUAL– ,DUAL表示数据库中全部的表。

确定了列数和类型,我们就可以提取数据库中的数据了,但是必须知道表中的列名。也可以提取数据库的版本,根据该版本的已知漏洞进行攻击。ms-sql数据库:youthflies’ union select @@version,NULL,NULL– ;oracle数据库: youthflies’ union select banner,NULL,NULL– 。

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论