原理:就是构造SQL语句,来实现数据库查询的目的。
最最简单的防御代码,往往对于用户的输入不进行检查,就盲目信任用户输入的内容就是他需要的内容。因此,就给了攻击者构造sql查询语句的机会,让服务器返回相应的、攻击者想要的内容。
比如,服务器系统信息,版本型号。白帽子只要做到这步就够了。因为做到这一步,就意味着可以可以构造相关语句,查到用户信息。
例如:
select user(),database(); 查询当前在线用户,以及他们所在的数据库
union all 与union的区别就在于,union all 联合查询到的数据不会消除重合的部分,而union会把重合的部分只留一个。
常见的最简单的现在基本无法注入的代码:
1' union all select user(),database() #
SQLmap的常用命令:
sqlmap -u "目的url" 查询目的地址是否有sql注入点
例如:
sqlmap -u "http://www.baidu.com"
sqlmap -u "目标地址" --cookie="客户端的cookie"
有些网页,只有正确登录了才能看到url地址。因此,扫描一些登陆后才能看到的网页url,只能先获得相应的cookie值才可以。另外,若得到某个用户的cookie,那么就可以欺骗服务器,我就是这个cookie值的主人,然后,访问该主人有权限访问的内容。
但是,上面这个方法有时候会出现302重定向报错。还有另外一种方法。
sqlmap -r /root/桌面/packet.txt -p id
将一个纯净的get或者post请求包完整复制粘贴下来,然后用sqlmap去读取本地的包文本文件。这时候就可以正常的扫描。(-p 后面是加想修改的参数,用来注入测试)
最后,扫描完会报出目标系统的信息。很强!
有时候,网站的防御水平高一点的时候,是会让用户在一个页面输入,然后返回的数据在另一个页面。若是这种情况,那么sqlmap在只扫一个网页的情况下,是无法发现注入点的。
因此,强大的sqlmap还有一个参数,来解决这类问题。
sqlmap -r /root/桌面/1.txt -p id --second-order="数据返回的页面URL"
目的是在进行测试的时候,还监测着另一个接收服务器效果的页面。只有这样才能成功进行测试,否则无法进行。原理我不清楚。
盲注的逻辑梳理
有时候,不管注入成功还是失败,网站不会返回相应的具体的提示信息,比如像什么sql语句错误啊,等等。网站为了安全只返回两种情况,第一,你是真正的用户,你有ID就返回有的信息。没有就返回没有的信息。第二,你是攻击者,你在尝试注入,你注入成功,我也返回没有的信息,你注入失败,我还是返回没有的信息。
那么,问题来了,攻击者该如何知道自己有没有注入成功呢?
经典的sql语句就诞生了:
1' and 1=1 #
1' and 1=2 #
通过正常输入,与这两个语句的尝试,就可以知道是否注入成功了。
假设,攻击者注入成功了(即这里存在注入点),那么,就会执行and 1=1 #这个后面的部分。实际上and 1=1 #是个废话。因为1=1是肯定的。因此,这里返回的结果和真正的用户直接输入1去查询的效果是一样的。
这时候,再输入 1' and 1=2 #那么返回的结果与and 1=1 不同的时候,就表示注入成功了!为什么?因为1=2明显是错误的。我们判断是否注入成功的依据就在于看1'后面的语句是否被执行!
若是1'后面的语句没有执行,那么可能注入成功,
其他的语句:
1' and select substring('user()',1,5)
从user()返回的字符串中的第一个字符位置开始截取,一直往后截取五位长度。5是可选参数,不加默认截取到最后
若是存在注入点,那么即使是手工测试,不用脚本测试,也可以利用二分法的方法结合等于号来测试出用户名是什么。这个思路非常棒!因为这个思路原理不仅仅局限于SQL注入!其他地方也都可以尝试!