SQL注入的常见方式汇总

学习路径

原理篇

  • sql注入基本原理
  • mysql注入有关知识点
  • sqli-lab实验环境搭建
  • GET基于报错的sql注入
  • 不再显错的盲注
  • Mysql注入读写文件
  • POST基于错误的注入
  • SQL注入绕过手段
  • POST基于时间与布尔盲注
  • HTTP头中的SQL注入
  • Post Update语句注入
  • Cookie注入
  • Cookie Base64注入
  • 绕过去除注释符的SQL注入
  • 绕过过滤and和or的SQL注入
  • 绕过去除空格的SQL注入
  • 绕过去除(union和select)的SQL注入
  • 宽字节注入
  • 二次注入分析

工具篇

  • Sqlmap工具的使用
  • Sqlmap工具的请求参数
  • Sqlmap工具指定位置的注入
  • Sqlmap工具的注入参数

学习笔记

sql注入基本原理

科普:解释型 or 编译型语言

语言分类:解释型语言编译型语言

解释型语言是一种在运行时由一个运行时组件解释语言代码并执行其中包含的指令的语言。

编译型语言是代码在生成时转换为机器指令,然后在运行时直接由使用该语言的计算机执行这些指令

在解释型语言中,如果程序与用户进行交互。用户就可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行有可能存在恶意行为的代码。

例如:在与用户交互的程序中,用户的输入拼接到SQL语句中,执行了与原定计划不同的行为,从而产生了SQL注入漏洞。

举例:’or 1=1绕过密码输入直接登录

登录业务系统的SQL语句

 
 
 
select* from admin where username=用户输入的用户名 and password=用户输入的密码

用户输入的内容可由用户自行控制,例如可以输入'or1=1-空格

拼接后的SQL语句

 
 
 
select* from admin where username=’or1=1– and password=用户输入的密码

其中or1=1永远为真,-注释后边内容不再执行,因此SQL语句执行会返回 admin表中的所有内容。

危害总结

  • 数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
  • 网页篡改:通过操作数据库对特定网页进行篡改。
  • 网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
  • 数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
  • 服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
  • 破坏硬盘数据,瘫痪全系统。

sqli-labs靶场搭建

可以参考下面文章中的sqli-labs部分

原理分析

通过单引号、双引号、括号、双括号来闭合sql语句,并把后面的语句内容注释掉,从而达到注入的目的

 

不再显错的盲注

 

原理分析

Blind SQL(盲注)是注入攻击的其中一种,向数据库发送truefalse这样的问题,并根据应用程序返回的信息判断结果,这种攻击的出现是因为应用程序配置为只显示常规错误,但并没有解决SQL注入存在的代码问题。

演示盲注问题。当攻击者利用SQL注入漏洞进行攻击时,有时候web应用程序会显示,后端数据库执行SQL查询返回的错误信息。Blind SQL(盲注)常规注入很接近,不同的是数据库返回数据的检索方式,若数据库没有输出数据到web页面,攻击者会询问一些列的truefalse问题,强制从数据库中获取数据。

盲注流程

1.判断是否存在注入,注入是字符型还是数字型(方法同显注的union相同)

2.判断字段数(order by)

3.猜解数据库个数

4.猜解指定数据库名称长度

5.猜解指定数据库名称

6.猜解指定数据库中表的个数

7.猜解指定数据库中表名长度

8.猜解指定数据库中表名

9.猜解指定数据库中指定表的字段数

10.猜解指定数据库中指定表的字段长度

11.猜解指定数据库中指定表的字段名

12.猜解指定数据库中指定表的字段内容个数

13.猜解指定数据库中指定表的字段内容长度

14.猜解指定数据库中指定表的字段内容

原理分析

Get和Post基于报错的注入,区别在于注入的位置不一样。

Get基于报错的注入,可以通过浏览器直接查看URL位置

而Post基于报错的注入需要使用Burpsuite截断表单,在表单中进行注入。

POST基于时间和布尔的盲注

原理分析

原理与Get基于时间和布尔的盲注相同,都是通过sleep等函数对数据库进行逐一猜解。

需要注意的是,此类注入,通常发生在表单数据中,实际操作时,凡是burp截断到的数据交互点,都值得一试。

 

HTTP头中的注入

原理分析

http头部常见参数

 

User-Agent:使得服务器能够识别客户使用的操作系统,浏览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)

20220519071443891

Cookie:网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密).

X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP]).

Clien-IP:同上,不做过多介绍.

Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的.

Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号(这个我本人还没碰到过,不过有真实存在的案例还是写上吧).

POST update语句注入

SQL update()介绍

首先介绍sql中的update():

updatexml(XML_document, XPath_string, new_value)

XML_document是文档对象的名称

XPath_string是XPath格式的字符串(如果XPath_string不是XPath格式,则会报错并显示出XPath_string的值)

new_value替换查找到的数据

注入所用语句

updatexml(1,concat(0x7e,payload,0x7e),1)。

concat()函数用于将多个字符串连接成一个字符串,目的是让拼接后的字符串不符合XPath格式使其报错,显示出要查的对象。

最终的目的是使其报错,至于拼接的值多种多样,并不局限于0x7e(这里是16进制,对应的ascii码,显示出来是:~)。

ASCII码对照表查询:

20220519071649982

 

http://ascii.911cha.com/

常用payload

爆数据库版本信息

?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)

 

链接用户

?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)

 

链接数据库

?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)

爆库

?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select schema_name),0x7e) FROM admin limit 0,1),0x7e),1)

 

爆表

?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select table_name),0x7e) FROM admin limit 0,1),0x7e),1)

 

爆字段

?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select column_name),0x7e) FROM admin limit 0,1),0x7e),1)

 

爆字段内容

?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0

Cookie注入

常见问题

1.什么是cookie注入?

cookie注入的原理是:就要修改cookie的值,

♦cookie注入其原理也和平时的注入一样,只不过说我们是将提交的参数已cookie方式提交了,而一般的注入我们是使用get或者post方式提交,get方式提交就是直接在网址后面加上需要注入的语句,post则是通过表单方式,get和post的不同之处就在于一个我们可以通过IE地址栏处看到我们提交的参数,而另外一个却不能。

♦相对post和get方式注入来说,cookie注入就要稍微繁琐一些了,要进行cookie注入,我们首先就要修改cookie,这里就需要使用到Javascript语言了。另外cookie注入的形

成有两个必须条件

条件1是:程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。

条件2是:在条件1的基础上还需要程序对提交数据获取方式是直接request(“xxx”)的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。

2.为什么要cookie注入?

主要是看看程序员有没有在cookie中做了一些过滤,我们有没有可趁之机。

3.怎样cookie注入?

cookie注入分为以下几个阶段:

1. 判断是不是注入点

2.得到字段总数

3.查选表名

4..查选列名

5.脱裤(就是得到我们想得到列名的值)

绕过waf常见姿势

规则层面的绕过

SQL注释符绕过

union/**/select

union/aaaa%01bbs/select

union/aaaaaaaaaaaaaaaaaaaaaaaaaaaa/select

内连注释:/!xxxx/

空白符号绕过:

MySQL空白符:%90,%0A,%0B,%0D,%20,%0C,%A0,/xxx/

正则的空白符:%09,%0A,%0B,%0D,%20

Example-1:union%250Cselect

Example-1:union%25A0select

每一个点都能找到绕过的方法

以注释绕过为例子,开始Fuzz

注释符绕过:

*先测试最基本的: union/**/select

*再测试中间引入特殊字:union/aaaa%01bbs/select

*最后测试注释长度:union/aaaaaaaaaaaaaaaaaaaaaaa/select

最基本的模式:

union/something/select

大小写绕过

如果程序中设置了过滤关键字,但是过滤过程中并没有对关键字组成进行深入分析过滤,导致只对整体进行过滤。

例如:and过滤。当然这种过滤只是发现关键字出现,并不会对关键字处理。可以通过修改关键字的内字母大小写来绕过过滤措施。

常规绕过手段

双写绕过

如果在程序中设置出现关键字之后替换为空,那么SQl注入攻击也不会发生。对于这样的过滤策略可以使用双写绕过。因为在过滤过程中只进行了一次替换。

例如:过滤了union 只要发现union 无论大小写都会被替换为空。这是就可以通过双写uniunionon的写法来对过滤进行绕过。

编码绕过

可以利用网络中的URl在线编码,绕过SQL注入的过滤机制。

http://tool.chinaz.com/Tools/urlencode.aspx

内联注释绕过

在Mysql中内容注释中的内容可以被当做SQL语句执行。

绕过过滤and和or的SQL注入

Mysql一些特性:

1、Mysql中的大小写不敏感,大写和小写一样。

2、Mysql中的十六进制与URL编码。

3、符号和关键字替换 and –> &&、or –> ||

4、内联注释与多行注释 /!内联注释/ /多行注释/。

5、Mysql中会自动识别URL与Hex编码好的内容。

绕过策略:

1、大小写变形,or,OR,oR,Or,and,And,AND,aND等。

2、在这两个敏感词汇中添加注释,例如:a/**/and 双写:oorr

3、利用符号替代 and–>&&、or–>||

绕过去除空格的SQL注入

编码:hex,urlencode

空格URL编码:

%0a 新建一行

%0c 新的一页

%0d return功能

%0b TAB键(垂直)

Sqlmap安全检测:

sqlmap -u “URL” –hex –dbs –batch

绕过去除(union和select)的SQL注入

编码%0a、加入/**/符,union/select大小写、双写等绕过。

宽字节注入

原理分析

宽字节注入是因为数据库使用了GBK编码,不过现在大都使用unicode国际编码,大多数网站都使用了utf-8的编码,目前比较少见,但是也有学习的价值。

一、宽字节概念

1、单字节字符集:所有的字符都使用一个字节来表示,比如 ASCII 编码(0-127)

2、多字节字符集:在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。

3、宽字节注入时利用mysql的一个特性,使用GBK编码的时候,会认为两个字符是一个汉字

二、addslashes()函数

1、addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

2、预定义字符:单引号(’),双引号(”),反斜杠(\),NULL

3、实例

<?php$ss=addslashes(‘aiyou”bu”cuoo’);echo($ss);?>运行结果:aiyou\”bu\”cuoo

三、数据库创建

1、创建数据库名为jay

create database jay;

2、选择创建好的数据库

use jay;

3、创建表名为zhuanji,字段包括,id,neme,year,zhudage

create table zhuanji(id int primary key auto_increment,name varchar(255) not null,year int not null,zhudage varchar(255) not null);

4、插入数据

insert into zhuanji (name,year,zhudage) values (“七里香”,”2004″,”七里香/外婆/我的地盘”);insert into zhuanji (name,year,zhudage) values (“十一月的萧邦”,”2005″,”夜曲/发如雪/珊瑚海”);insert into zhuanji (name,year,zhudage) values (“我很忙”,”2007″,”青花瓷/我不配/彩虹”);

5、中文编码问题,修改my.ini文件

[mysql]

default-character-set=gbk

[mysqld]

character-set-server=gbk

四、宽字节注入

1、访问该网址:http://192.168.0.104/aiyou/1.php?id=2,返回正常信息

20220519072241430

2、判断是否存在注入,在id=2后面加入’,看是否报错,发现单引号被转义了

20220519072255625

3、替换反斜杠,反斜杠的GBK编码为%5C,根据GBK编码在前面加上%DE,%DF,%E0。。。都可以组成一个汉字,从而把反斜杠给‘吃’了

20220519072308745

4、成功替换了反斜杠

20220519072336695

5、获取数据库列数,order by 4返回正常

 
 
 
192.168.0.104/aiyou/1.php?id=2%E0′ order by 4 –+
20220519072349639

6、获取数据库名称及版本号

 
 
 
192.168.0.104/aiyou/1.php?id=-2%E0′ union select 1,database(),version(),4 –+
20220519072418600

二次注入

原理分析

二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。

二次注入需要具备的两个条件

(1)用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)

(2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户

20220519072547820

20220519072603792-1536x916-1

靶场讲解:

学习SQL注入,必定要刷sql-labs,这里以SQLIlab lesson-24为例,进行实战讲解。

1.打开题目

20220519073233507

2.点击下方new user click here? ,会让你注册新用户如下图。

20220519073243249

3.注册完成后登陆进去会让你修改新的密码:

20220519073253622-1

4.如果直接尝试在登陆处尝试SQL注入,payload: admin’# 发现失败:

20220519073304164

5.看一下源代码:

20220519073316567

登陆处的username和password都经过了mysql_real_escape_string函数的转义,直接执行SQL语句会转义’,所以该处无法造成SQL注入。

6.此时我们注册一个test’#的账号:

20220519073444915

7.注册用户的时候用了mysql_escape_string过滤参数,但是数据库中还是插入了问题数据admin’#。

20220519073459843

也就是说经过mysql_escape_string转义的数据存入数据库后被还原

8.回到题目,此时,admin用户的原来密码为admin,我们以admin’#用户登陆,再进行密码修改,原本admin’#账户的密码为123,我们修改为1314。

20220519073511408

9.在admin’#账户密码修改之前我们看下admin账户的密码是admin

20220519073525670

10.我们点击reset确认修改,然后打开数据库惊奇的发现admin账户的密码变成了1314,而admin’#的密码没有变。我们明明修改的是admin’#账户,而密码改变的却是admin账户,这是为什么呢?

20220519073539595

我们看修改密码的SQL语句

20220519073550229

执行密码修改的语句

20220519073725330-1024x101-1

在SQL语句中 # 是注释符,#后面的语句会被注释掉 ,最终执行的语句是

20220519073735557

这条语句很显然是修改admin账户的密码。

这样我们就在不知道admin密码的情况下修改了admin的密码,然后可以登录,实现注入。

© 版权声明
THE END
喜欢就支持一下吧
点赞13赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容