2. File Upload模块
文件上传是很多网站都有的,比如社交网站的上传头像,上传照片,比如资源网站可以上传一个共享软件,上传压缩包等。那么在这种情况下,如果网站对于上传过滤不严格的话,就可以上传木马或恶意程序,这对于服务器危害是非常大的。这里仍然用Burp Suite来演示DVWA中的File Upload模块(设置为Medium级别,因为Low级别可以直接上传)是如何被上传一个木马的。
单击“File Upload”打开上传模块的部分,看到一个可以选择上传文件的文件框和上传文件的提交按钮,选择一个正常的图片文件上传,会提示上传成功,并返回一个上传的地址,地址为“../../hackable/uploads/test.jpg”,用该返回的地址直接贴到当前URL后面就会打开图片,打开后的URL地址为“http://localhost/dvwa/hackable/uploads/test.jpg”。然后选择一个PHP的木马文件上传,会提示不是JPEG或PNG的文件,如图8所示。
图8 cmd.php上传失败
打开Burp启动拦截,然后设置浏览器的代理,然后再次上传PHP木马查看Burp中截取到的HTTP数据,如图9所示。
图9 Burp对木马上传的抓包
在图9中的“Content-Type”中可以看出,这里提交的类型并不是图片的类型。那么将如何修改呢?将本地木马的扩展名修改为“png”或“jpg”的格式,然后再次提交,如图10所示。
图10 Burp对修改扩展名的木马上传抓包
从图10中可以看到“Content-Type”的类型已经改变了,但是注意在“filename”处文件名是“cmd.jpg”,这样上传后文件就是一个jpg的文件,那么在这里修改jpg的扩展名为php,然后单击“Forward”让Burp将数据包提交到Web服务器。返回DVWA中可以看到cmd.php的木马文件已经上传成功了,打开地址“http://localhost/dvwa/hackable/uploads/cmd.php”,可以正常打开上传的木马文件。
之前写过一个通过发包来进行暴力破解的程序,在程序中每次发包时会修正包的长度,而Burp Suite会自动修正包的长度,这一个小的功能就非常“贴心”。从第二个实例中可以体会到Burp Suite存在于浏览器和服务器的中间,可以对浏览器提交的数据包进行截取、修改、发送,因此善于利用Burp Suite的这个功能可以很好地绕过很多Web前端页面的数据校验,也可以通过修改数据包达到欺骗后台的效果,类似于上面的例子,提交的类型是图片类型,但是实际上却是一个PHP的文件。 3. SQL Injection模块
SQL Injection是用来练习SQL注入攻击的模块,SQL注入也是常见的Web攻击方式。SQL是结构化查询语言,是一种针对数据库设计的查询语言,可以完成对数据库的增、删、改、查等操作,最主要的还是进行各种各样的查询,而且可以通过简单的语句构造出来复杂的查询。SQL注入就是通过构造SQL语句从而进行攻击的一种技术。
在使用SQL Injection模块进行练习之前,简单描述什么是SQL注入。在可以交互的Web系统中,通常都会有用来进行输入的输入框,比如输入用户名和密码的输入框,填写注册信息的输入框等都可以向Web系统提交信息。在正常情况下用户会按照提示进行相应的输入,但是不怀好意的人会有意地输入其他有特殊意义的符号,由于特殊符号的作用,就会导致意想不到的情况(不怀好意的人不一定是攻击者,比如注册的时候随便填写可能导致Web页面不正常显示之类,现在这样的系统比以前大大减少,但并不是说已经不存在了)。对于恶意攻击者而言,则会有意地使用SQL语法的关键字或符号来构造一些输入,使得构造的输入在数据库中被执行,从而获得更有价值的信息。
经过上面简单的介绍,大家可能对SQL注入已经有个简单的了解了,现在来看一下DVWA系统中的SQL Injection模块(级别为Low),如图11所示。
图11 DVWA的SQL Injection模块
图11中有一个输入框,从该输入框中就要完成SQL注入的联系。随便输入一个“1”(实际输入没有引号),会返回ID为1的“First name”和“Surname”,接着输入一个“2”,同样会返回ID为2的“First name”和“Surname”。那么再输入一个“a”,就什么都没有返回。输入“1”和“2”有返回结果,而输入“a”没有返回结果,那是因为数据库中并没有ID为“a”的记录,而数据库中存在ID为“1”和“2”的记录,那这能说明什么问题呢?说明有没有该ID对应的数据,是需要在数据库中进行查询的,那么是怎么查询的呢?可能是这样的两种查询语句,第一种查询语句如下:
Select firstname, surname from 表名 where id = '1'
第二种查询语句如下:
Select firstname, surname from 表名 where id = 1
这两种语句的写法如果对于没有SQL语言基础的朋友又不仔细看的情况下可能没有看出差别,第一句和第二句的差别在于第一句的1是被单引号引住的,第二句则直接是1。它们的差别是第一句查的ID是一个字符串类型的,第二句查的ID是一个数值型的。至于是数值型还是字符串型的,对注入攻击有什么差别呢?是有的。因为那个ID的值是输入的,那里是一个变量,实际写程序时可能是进行拼接的,看一下上面的字符串是如何拼接的。
第一种拼接方法:
$sql = "select firstname, surname from 表名 where id = '" . $id . "'";
第二种拼接方法:
$sql = "select firstname, surname from 表名 where id = " . $id;
可以看到,在第一种使用字符串拼接的时候,$id的前后会有引号的存在,而在第二种字符串拼接的时候,$id的前后是没有使用引号的。
在各种语言中都有逻辑运算符,当然在SQL语句中也有,SQL中的“与”用and表示,或用or表示。如果一条逻辑语句是“××× and 1=1”这样写的,是不会影响×××原来逻辑的,因为1=1是永远为真的。来构造一下输入的内容,这里输入“1' and '1' = '1”,如图12所示。
图12 构造的AND语句
点提交以后仍然会看到ID为1的信息,那么上面的输入是如何拼接成SQL语句的呢?大体如下:
$id = "1 and '1'='1";
$sql = "select firstname, surname from 表名 where id = '" . $id . "'";
复制代码
那么拼接后的语句如下:
select firstname, surname from 表名 where id = '1' and '1'='1';
现在知道and '1'='1'是不改变前面的逻辑值的,也就是对id='1'是否存在是不改变的,也就是id='1'是真,id='1' and '1'='1'就是真,如果id='1'是假,那么id='1' and '1'='1'还是假。在输入时,第一个1后面有一个单引号,是用来和代码中的SQL语句中的单引号进行闭合的,而最后一个1的前面有一个单引号,它是用来和SQL语句中的单引号进行配对的。因为在代码中本身就存在单引号的。如果在代码中用的不是字符串,而输入框中构造的有单引号,则会抛出异常。因此,猜测的两种方法这里使用的是第一种。
那么如何让这个语句永真呢,还是利用该等式'1'='1',只是逻辑连接符由and改为or。
那么再次在输入框中提交“1' or '1'='1”,提交后如图13所示。
图13 构造的or语句
从图13中可以看出,由于提交的内容是“1' or '1'='1”,那么构造的SQL语句就成为了如下语句:
Select firstname, surname from 表名 where id = '1' or '1' = '1'
由于查询条件永真,那么将会把所有的记录都列出来。那么该语句还适合于在前面的“Brute Forece”模块中进行测试,在输入用户名的地方输入“admin' or '1'='1”,在输入密码的地方也输入“admin' or '1'='1”,同样可以得到与输入正确密码的一样的效果。
SQL注入是非常灵活的,下面再随便输入几个测试的语句,如“1' union select user(), '1”和“1' union select database(), '1”,可以显示出系统登录数据库的用户名和当前系统所使用的库名,如图14和图15所示。
图14 系统登录数据的用户为root
图15 系统所使用的库名为dvwa
SQL注入的灵活是因为SQL语句本身的灵活,要想更好地掌握SQL注入那么就一定要先掌握SQL语言的使用。
本文演示了DVWA系统的3个模块,分别是Brute Force、File Upload和SQL Injection。Web系统的漏洞基本也是因为对用户提交的数据过滤不严格而造成的,一切用户的输入都应该视为不安全的,因此安全编码就是从开发人员层面来杜绝系统产生漏洞,在系统上线之前还会有代码审计、Web漏洞扫描等上线前的安全检查,针对Web安全防护的系统有ADS、WAF、网页防篡改等。当然了,最关键的还是从编码时就考虑安全的问题,从源头杜绝系统产生漏洞。