将“DVWA Security”设置为medium中等级别,首先点击右下角的“View Source”查看此时的网页源码,主要观察与low级别的区别。
可以发现,这里对用户输入的id参数进行了过滤,主要方法是使用了mysql_real_escape_string()函数,这个函数可以将$id变量中的单引号’、双引号”、斜杠\等字符进行转义,因而我们再输入之前的“’or 1=1 #”就会报错了,从错误提示中可以发现单引号’已经被转义成了\’,因而注入语句无法发挥作用。
需要说明的是,在PHP中还有一个与mysql_real_escape_string()功能类似的函数:addslashes(),这两个函数的功能都是对特殊字符进行转义,那么到底用哪个函数更好一些呢?百度了一下,发现大家也是各执一词。有人说mysql_real_escape_string()函数需要事先连接数据库,可能会报错,所以推荐使用addslashes();也有的人说addslashes()过滤不够严格,推荐使用mysql_real_escape_string()。在DVWA中很明显是推荐使用mysql_real_escape_string(),那么我们就相信DVWA好了。
下面我们分析一下这里该如何绕过过滤,继续进行注入呢?我们再仔细观察一下源码,可以发现参数id已经被改为了数字型,第三行语句中“user_id = $id”,而之前的low级别是“user_id = ‘$id’”,其实这就是DVWA故意留下的一个漏洞。
我们可以进一步进行确认,在文本框中输入3以及1+2,发现两者显示的结果都是一样的,因而可以断定参数是数字型,这里就应该采用数字型的注入方法。
数字型注入与文本型的最大区别就是不需要考虑引号闭合,下面我们来进行注入。
首先输入“1 and 1=1”,显示正常;输入“1 and 1=2”,显示不正常。判断存在注入点。
分别输入“1 order by 1”、“1 order by 2”,显示正常;输入“1 order by 3”,显示错误,判断存在2个字段。
输入“1 union select 1,2”判断出两个字段都可以代入参数进行查询。
再接下来的操作就与之前相同了。