孙 梅,郭宇燕,韩 超,余 磊
目前,Web在互联网中得到了最为广泛的应用,Web的功能和交互性也在不断增强,承载的业务也越来越多,大量的数据存储在各种Web系统中.针对Web应用的攻击成为了攻击者的主要目标,Web应用安全成为了目前互联网的主要安全问题[1].当前Web安全威胁主要集中在Web数据处理、Web应用程序、Web业务流程等方面.如果程序员在设计系统、开发系统中没有充分考虑到安全因素,很容易遭到黑客的攻击,如XSS、CSRF、SQL注入等攻击[1-2].这些都是因为Web应用程序或者Web数据处理存在的安全漏洞而导致的.
渗透测试是通过模拟黑客的攻击方法和漏洞发掘技术来评估计算机系统安全的一种评估方法,该方法是从攻击者角度发现分析系统的缺陷及漏洞,进而尝试利用某些漏洞对信息系统实现主动攻击的过程,从而评估系统存在的可能安全风险问题[2].本文主要研究Web中SQL注入、XSS注入、文件上传漏洞、逻辑漏洞等的渗透测试方法.
本文通过在本地搭建一个渗透测试站点DVWA,模拟各种攻击方法对DVWA站点进行渗透,研究Web的渗透测试方法设计分析和防护措施.DVWA是一套集成了常见Web漏洞的php+mysql系统,其中包含了暴力破解、SQL注入、XSS、CSRF、文件上传等一系列的安全漏洞.
SQL注入漏洞是目前针对Web应用危害最大、且攻击成本最低的漏洞.2013年,SQL注入攻击在OWASP TOP10中处于第一名的位置[3].SQL注入形成的根本原因是开发人员在开发代码时,未对用户的输入进行过滤或者过滤不严格,用户输入的内容被后台数据库直接运行,导致Web数据泄露或被篡改等威胁的发生[4].一般,攻击者通过Web应用程序提交一段精心构造的SQL代码,查询数据库中的敏感信息,如管理员的账号密码、用户的个人信息等.当数据库用户的权限比较大时,如mysql的root用户,mssql的sa用户,攻击者还可以通过巧妙地组合SQL语句,向目标服务器写入木马文件,甚至获得目标服务器操作系统的shell,直接执行系统命令.下文通过手工注入和自动注入来研究和分析SQL注入的渗透测试方法.
(1)验证是否存在sql注入点.首先将DVWA的安全等级设置为低,然后打开SQL注入页面,在USER ID位置输入3′and ′3′=′3,如图1所示.如果正常返回了数据,说明输入的内容被数据库执行了,猜测Web程序的sql语句为:select*from 表名 where id=′3′and ′3′=′3′,由于and ′3′=′3′在逻辑上为真,所以返回了id为3的用户信息.输入3′and ′3′=′4,点击提交.由于and ′3′=′4′在逻辑上为假,所以这次没有返回数据.根据以上两种情况,可以判断USER ID位置存在SQL注入.
图1 验证sql注入
图2 判断字段数
(2)判断字段的个数.输入3′order by 2#,如图2所示.在mysql数据库中,#的作用为单行注释符,order by会对查询的结果进行排序,攻击者通常使用order by子句来判断表的字段数.由于此时正常返回了数据,说明查询了2个字段.输入3′order by 3#,点击提交后,返回了字段异常错误.说明表中字段的个数不足3个,即判断字段的个数为2.
(3)获取数据库名.输入3′union select 1,database()#,这里使用union查询,union可以把多个select语句的结果组合到一个集合中,database函数用来查询数据库名,从返回结果可以看出,数据库名为dvwa.如图3所示.
图3 获取数据库名
(4)获取表名.输入 3′union select 1,table_name from information_schema.tables where table_schema=dvwa#,information_schema是MySQL 5.0及其以上版本自带的系统数据库,它提供了对数据库元数据的访问接口,可以将它理解成数据库的字典,mysql的表名、列名、访问权限、索引信息等都存储在内.结合mysql中的关键字可以从information_schema数据库中查询到攻击者想要的信息,如图4所示.根据返回结果判断dvwa数据库下包含了users表和guestbook表.注意使用sql语句查询时,需要将数据库名、表名转换成16进制格式,否则查询不到数据;mysql关键字的信息见表1.
图4 获取表名
表1 mysql关键字
(5)获 取 列 名.输 入 3′union select 1,group_concat (column_name) from information_schema.columns where table_name=users#,如图5所示.其中group_concat函数可以将列进行分组,便于显示和查看.根据返回的列名可以猜测,password列中可能存放着用户的密码信息.
图5 获取列名
(6)获取数据.在用户id位置输入3′union select 1,password from users#,如图6所示,此时后台数据库执行的sql语句为select*from表名where id=′3′union select 1,password from users#′.
图6 获取数据
成功获取到了用户的密码.但密码是被md5加密过的密文,将密文拿到一些在线解密网站上进行解密,如果密码的长度和复杂度比较弱,就很容易获得明文.
sqlmap是一款开源的、使用python编写的跨平台SQL注入工具,它可以自动地发现并利用SQL注入漏洞.另外,sqlmap还集成了许多实用的第三方脚本,当目标网站上安装了WAF或者防火墙设备时,攻击者甚至可以通过这些脚本的帮助绕过防火墙的过滤和拦截.
(1)sqlmap向目标服务器写文件.sqlmap向目标服务器写文件的命令格式是sqlmap-u"url地址"--file-write="本地文件"--file-dest="远程文件",如图7所示.
图7 sqlmap写文件的命令参数
如图8所示,sqlmap成功将本地的1.php写入到目标服务器的C盘根目录下,并命名成了shell.php.在实际的渗透测试过程中,1.php通常是攻击者预备好的木马文件,利用SQL注入上传到目标服务器上以后,可以直接获得目标服务器的控制权.
图8 写文件
(2)获取操作系统的shell.sqlmap获取操作系统shell的命令格式是sqlmap-u"url地址"--os-shell,如图9所示.
图9 sqlmap获取shell的命令参数
图10 执行系统命令
如图10所示,sqlmap已经获取到了操作系统的shell,由于数据库用户的权限比较大,甚至可以直接使用net user命令添加系统用户,至此目标服务器已经完全被控制了.
SQL注入的防御,首先要从代码层面入手,SQL注入产生的根本原因是用户可以输入自定义的SQL语句.程序在处理用户的输入时,必须对输入的内容进行检查,过滤其中包含的特殊字符,或者对特殊字符进行转义.开发人员需要重点关注的关键字和特殊字符如下.
(1)sql语句关键字:and、or、select、from、where等.
(2)sql语句特殊字符:单引号、双引号、分号等.
另一方面可以从应用层防止SQL注入攻击,目前国内主流的安全厂商都有一些专业的Web应用防护设备,例如绿盟科技的WAF with MSS,启明星辰的天清Web应用安全网关等.这些WAF设备自身定义了许多SQL注入过滤规则,攻击者输入的危险字符会先经过应用层的WAF设备,再提交给Web的后端数据库,一定程度地降低了Web应用的安全风险.
最后,Web站点接入的数据库应遵循用户角色最小权限原则[5],针对不同类型的操作,创建对应权限的数据库用户,最大限度地降低SQL注入的危害.
当用户访问网页时,攻击代码在用户的浏览器上被执行,就形成了一次XSS跨站脚本攻击.XSS跨站攻击危害的主要是Web用户,并不会直接危害Web服务器[6].根据XSS漏洞的原理可以将XSS跨站攻击划分成反射性XSS和存储型XSS,对于反射性XSS,攻击者需要欺骗用户点击一个恶意URL才能攻击成功[7].存储型XSS的危害相对来说更大一些,攻击者提交的恶意代码,会被Web服务器端接收并存储,访问该网页的用户,他们的浏览器会执行这段恶意代码.
首先将DVWA的安全等级设置为低,然后打开反射性XSS页面.在输入框中输入一串JavaScript代码,如图11,点击提交后页面的变化如图12所示.在Javascript语言中,alert函数的作用是弹出对话框,因此这里在页面上输出了一个值为3的对话框,说明提交的Javascript脚本代码在浏览器上执行了,以上过程就触发了一次跨站脚本攻击.在实际的渗透测试中,XSS不仅仅是弹出一个对话框这么简单.攻击者往往会精心编写一些攻击代码,或者使用互联网上的XSS攻击平台进行攻击,Javascript的功能越强大,XSS漏洞的危害就越大.
图11 测试语句
图12 弹框
打开存储型XSS页面,看到一个用户留言板,我们在消息框中输入一串Javascript代码,如图13所示,然后点击提交,页面的变化如图14所示.
图13 测试语句
图14 弹出cookie值
这里使用到了Javascript中document对象的cookie属性,结合alert函数将已登录用户的cookie值弹出.从返回结果可以看出,输入的Javascript代码被执行了.而且输入的内容已经被存储到数据库中,每当有人浏览该用户的留言时,都会在他的浏览器上执行攻击者插入的Javascript代码.一些用户量大的论坛或者新闻站点,一旦出现存储型XSS漏洞,很有可能造成大量用户的身份认证信息泄露,危害很大.
burpsuite是Java语言编写的一款web应用攻击平台,它是Web安全测试者最常用的工具.burpsuite自身相当于一个代理服务器,用户通过浏览器访问Web站点时,流量会先经过burpsuite,再由burpsuite将流量发送给目标服务器,因此在流量传递的过程中,攻击者可以对流量进行分析和修改.除此之外,burpsuite中还集成了许多的功能模块,例如中继模块、扫描模块、爬虫模块、编码模块等等,并且各个模块之间是互相联通的.在XSS漏洞的挖掘过程中,黑客通常会使用到burpsuite的中继repeater模块,通过不断地修改需要提交的数据包,来对XSS漏洞进行检测和利用.
(1)XSS绕过DVWA中级安全级别检查.首先打开burpsuite,将代理模块配置成监听本机的8080端口,如图15所示.
图15 burp代理
然后将浏览器的网络代理设置成burpsuite所在的主机,这样用户通过浏览器访问web站点时,流量就会先流经burpsuite.
接下来将DVWA的安全级别设置为中,打开反射性XSS页面,在输入框内随便输入一串字符123a,点击提交后,burpsuite拦截到了本次的请求,将请求包发送到repeater模块,然后点击Go可以发送本次拦截到的数据包,如图16所示.
图16 repeater模块
在repeater模块中,可以不断地更改要发送的数据包,然后在response响应包中查找提交的内容.如果提交的Javascript代码在响应包中能被查找到,则证明此处存在XSS漏洞.经过测试发现,DVWA的中级安全级别过滤了Javascript关键字,但是可以变换大小写绕过检查.最终通过提交<Script>alert(3)</Script>,成功触发了一次XSS攻击,如图17所示.
图17 大小写变换
(2)XSS绕过DVWA高安全级别检查.将DVWA的安全级别设置为高,打开反射性XSS页面,同样将数据包发送到burpsuite的repeater模块下.经过测试发现,高安全级别下script标签的大小写都被过滤了.虽然无法通过javascript插入XSS代码,但是可以使用html中的图片标签img,配合标签的onerror事件成功触发XSS攻击,如图18所示.
图18 图片标签
通过burpsuite对以上三个不同安全级别的DVWA XSS跨站渗透测试,可以看出burpsuite通过不断分析、修改数据包,从而绕过Web应用程序的检测和过滤.
XSS跨站脚本攻击和SQL注入类似,都是因为用户输入了非法字符,所以最根本的防御方法就是对用户的输入进行过滤.在HTML超文本标记语言中,>、<、/、”都是比较有特殊意义的字符,在程序的代码中应该禁止用户提交这些字符.XSS问题产生的关键是输入和输出,有时用户输入的值可能有多个输出点,所以不仅需要在输入点进行过滤,在各个输出点也要进行严格的检查.另外微软公司的IE浏览器在Internet Explorer 6 SP1时引入了一项http-only扩展,可以拦截客户端脚本操作cookie值,目前所有主流的浏览器都支持了http-only,使用浏览器的http-only特性可以有效防御XSS cookie劫持.
上传漏洞也是Web安全测试中经常遇到的一种漏洞类型,在Web技术发展的早期,黑客们非常喜欢利用上传漏洞对Web站点发起攻击.许多网站都会有一些文件上传点,例如上传附件、上传用户头像等.如果开发人员没有对用户上传的文件类型进行校验,攻击者可以上传一些恶意的代码文件,获得Web站点的控制权.针对文件上传漏洞,浏览器端的过滤是没有作用的.攻击者通过修改Javascript代码,或者直接禁用网站的Javascript脚本功能,可以很轻松地绕过浏览器的过滤.
将DVWA的安全级别设置为低,打开文件上传的页面,选择本地的3.php进行上传,由于服务器没有对文件的扩展名进行校验,所以成功上传了php格式的文件,如图19所示.
图19 成功上传
将DVWA的安全级别设置为中,打开文件上传的页面.中级安全级别DVWA的代码对上传点进行过滤,仅允许上传jpeg或png格式的文件,所以3.php无法直接上传成功,如图20所示.
图20 仅允许上传图片
接下来打开burpsuite工具,拦截一次上传请求.发现在html body中有一个Content-Type字段,用于定义文件的MIME类型.当上传php格式的文件时,Content-Type字段的值为application/octet-stream,表示将文件以二进制流的格式上传,我们将其修改为图片格式image/jpeg,如图21所示,这一次成功地上传了3.php.
图21 修改Content-Type
另一种绕过上传过滤的思路——%00截断[8].当程序执行到%00时,会错误地把它当成结束符,所以后面的数据就被忽略了.例如把上传的文件命名成3.php%00.jpg,服务器会误认为上传的是图片文件,但是执行时却是php脚本文件.
通过burpsuite可以很轻松地实现%00截断,首先上传一张图片3.jpg,拦截数据包后修改filename的值,注意这里需要将%00进行URL解码.修改完成后提交数据包,成功绕过了服务器端的检查,如图22所示.%00截断是一种非常经典的攻击手法,在与文件操作相关的地方都可以尝试使用它,例如文件包含、文件上传、文件下载等.
图22 截断上传
在渗透测试中,攻击者通常会利用上传漏洞向目标服务器上传一句话木马,再结合网站管理工具实现对目标服务器的进一步控制.中国菜刀就是一款专业的网站管理工具,它体积小巧且功能强大,支持asp、php、jsp等众多类型的网站.
下面使用中国菜刀,连接脚本文件获得网站的webshell.首先将一句话木马<?php@eval($_POST[‘world’]);?>写入3.php.再利用上传漏洞将3.php上传到目标服务器,打开中国菜刀客户端,连接3.php,连接密码为world,最终可以获得网站的webshell,如图23所示.
图23 获得webshell
中国菜刀还支持许多第三方功能,例如文件管理、数据库管理、虚拟终端等,每种功能都有特定的使用场景,给安全渗透测试带来了很大的便利.
上传漏洞的危害虽然很大,但是只要配置正确,就可以设计出安全的文件上传点,以下提供几种上传漏洞的防御思路[8].
(1)使用白名单的方式,严格判断文件的后缀名以及MIME类型.
(2)将上传后的目录和文件命名成随机数.
(3)服务器端存放文件的目录设置成只读的权限,限制文件的执行.
通过以上几种方法,可以有效地防止上传漏洞的发生.
逻辑漏洞是一种新型Web安全漏洞,自出现以来,迅速成为黑客的主要攻击目标.它是一种业务处理流程设计缺陷,主要发生在Web的业务流程中.传统的安全测试主要依靠漏洞类型的自动化扫描检测,这种方式往往容易忽略业务系统的逻辑漏洞,而且传统的安全设备也很难对逻辑漏洞进行防御.国内很多大型互联网厂商都曾被曝光过逻辑漏洞,例如知乎任意用户登录,新浪任意密码重置,淘宝网支付漏洞等等,企业很可能因为简单的业务逻辑漏洞而蒙受巨大损失.
目前,在线消费和支付已遍布人们生活的各个方面.由于涉及到资金方面的问题,一旦存在漏洞,对个人和企业来说危害非常大.
订单金额篡改是一种常见的支付漏洞.购买商品一般分为三个步骤:填写信息、提交订单、付款.在最后一步付款时进行抓包尝试修改订单的金额,如果程序没有对支付的金额做校验,那么就可以低价买到高价的商品.
不仅订单金额,订单数量也是可以篡改的.在支付的过程中,最终的价格是由商品的数量决定的,比如:数量为1时价格为5元,数量为2时价格为10元,那么当攻击者修改商品的数量为负数时,最终的金额也会变为负数,账户里的钱不但没有减少反而增加了.
还有一种支付漏洞是订单请求重放,攻击者通过拦截商品购买成功时的数据包,对数据包进行请求重放.如果程序没有对订单多次重复提交进行限制,那么就会导致购买商品一直增加.
越权漏洞指攻击者请求操作某条数据时,Web应用程序没有对该数据的所有者进行判断,导致攻击者可以自行修改参数,操作不属于自己的数据.越权漏洞在增、删、改、查的位置都有可能发生,一般分为水平越权和垂直越权.水平越权是相同权限用户之间的越权,比如使用A学生的账号操作B学生的账号就属于水平越权.而垂直越权是不同权限级别用户之间的越权,比如使用学生账号操作教师账号,或者普通用户访问管理员用户的资源,都属于垂直越权.
为了防止用户因忘记密码而无法登录,大部分网站都提供了找回密码的功能.常见的找回密码方式有:手机验证码、邮箱、密保问题等.以上这些方式如果在逻辑设计上存在缺陷,就有可能存在密码重置漏洞.
使用手机验证码找回密码时,如果用户的请求页面不是直接提交到后台服务器,而是先经中间节点再到达后台服务器,并且后台服务器未对用户的手机号进行校验,中间节点就可以通过修改手机号,给指定的手机号发送验证码,进而实现对任意用户的密码重置.有时候即便验证了用户的手机号,但是由于验证码的位数较短,攻击者通过暴力穷举也能很容易获取到正确的验证码,如一个4位纯数字的验证码可以在几分钟之内枚举一遍.
使用邮箱找回密码时,大部分网站是向邮箱发送一个找回密码的链接,用户在浏览器上访问该链接就可以进入重置密码的页面.找回密码的链接中通常会加入校验参数,我们称之为token.通过对比token值与服务器端生成的值是否匹配来判断当前找回密码的链接是否有效,但是如果这个token值不是随机生成的就会造成安全问题.类似于这种弱token的现象有很多,例如使用用户名的md5值或base64编码作为token值,攻击者可以很容易地构造token值重置任意用户的密码.
逻辑漏洞与公司的业务是紧密相关的,要想防御逻辑漏洞,必须关注业务系统中每一个环节可能存在的安全风险.
支付环节中,把与金钱、数量有关的参数做数字签名,可以有效地避免数据被篡改.在找回密码环节,如果需要客户端输入手机号,应该严格校验手机号是否和登录者的身份一致,还需要考虑验证码是否能被暴力破解,一般建议验证码的长度为6位,并且设置验证码的有效时间和失败尝试的次数.另外对于邮箱找回密码的情况,token值不能使用时间戳或者有规律可寻的数字字符,应当使用复杂的token生成机制,让攻击者无法推测出具体的值.最后,对于越权漏洞,应该验证一切来自客户端的参数,尤其是和用户权限相关的参数.
随着信息安全知识的普及,越来越多的企业逐渐认识到信息安全的重要性.Web安全是信息安全领域的一个重要分支,目前也是一个相对热门的就业方向.由于安全事件的发生是不可预期的,许多企业都配备了专职的Web安全技术人员,在不影响业务系统正常运行的前提下,定期对公司的Web应用系统进行渗透测试,发现被测系统中可被利用的安全隐患.
本文从一个渗透测试者的角度出发,在个人电脑上搭建了一个Web站点,然后对其进行了漏洞的测试和利用.这些测试方法不仅可以作为Web安全评估的方法,也可以作为Web安全课程教学的实践教学方法,引导学生通过个人搭建环境,完成Web安全的研究和分析.