DVWA总结


Brute Force,即暴力(破解),是指黑客利用密码字典,使用穷举法猜解出用户口令,是现在最为广泛使用的攻击手法之一,如2014年轰动全国的12306“撞库”事件,实质就是暴力破解攻击。 初级:服务器只是验证了参数Login是否被设置(isset函数在php中用来检测变量是否设置,该函数返回的是布尔类型的值,即true/false),没有任何的防爆破机制,且对参数username、password没有做任何过滤,存在明显的sql注入漏洞。所以可以采用万能密码的方式进行登录   1.Username:admin' or '1'='1   Password:(空) 2.Username :admin' # Password :(空)(手工注入) 同时也可以采用BP进行爆破,将抓到的包复制到intruder模块,因为要对password参数进行爆破,所以在password参数的内容两边加$($password&)。选中Payloads模块,载入字典,点击Start attack进行爆破,成功后响应的密码长度是不同的。   中级:主要增加了mysql_real_escape_string函数,这个函数会对字符串中的特殊符号(x00,n,r,,',",x1a)进行转义,基本上能够抵御sql注入攻击,说基本上是因为查到说 MySQL5.5.37以下版本如果设置编码为GBK,能够构造编码绕过mysql_real_escape_string 对单引号的转义(因实验环境的MySQL版本较新,所以并未做相应验证);同时,$pass做了MD5校验,杜绝了通过参数password进行sql注入的可能性。但是,依然没有加入有效的防爆破机制(sleep(2)实在算不上)。虽然sql注入不再有效,但依然可以使用Burpsuite进行爆破,与Low级别的爆破方法基本一样。   高级:High级别的代码加入了Token,可以抵御CSRF攻击,同时也增加了爆破的难度,登录验证时提交了四个参数:username、password、Login以及user_token。每次服务器返回的登陆页面中都会包含一个随机的user_token的值,用户每次登录时都要将user_token一起提交。服务器收到请求后,会优先做token的检查,再进行sql查询。同时,使用了stripslashes(去除字符串中的反斜线字符,如果有两个连续的反斜线,则只去掉一个)、 mysql_real_escape_string对参数username、password进行过滤、转义,进一步抵御sql注入。  可以采用py的方式进行爆破       Command Injection,即命令注入,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一,国内著名的Web应用程序Discuz!、DedeCMS等都曾经存在过该类型漏洞。   初级: // Determine OS and execute the ping command.       if( stristr( php_uname( 's' ), 'Windows NT' ) ) { stristr(string,search,before_search) stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE。参数string规定被搜索的字符串,参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符),可选参数before_true为布尔型,默认为"false" ,如果设置为 "true",函数将返回 search 参数第一次出现之前的字符串部分。   php_uname(mode) 这个函数会返回运行php的操作系统的相关描述,参数mode可取值”a” (此为默认,包含序列”s n r v m”里的所有模式),”s ”(返回操作系统名称),”n”(返回主机名),” r”(返回版本名称),”v”(返回版本信息), ”m”(返回机器类型)。 服务器通过判断操作系统执行不同ping命令,但是对ip参数并未做任何的过滤,导致了严重的命令注入漏洞。   window和linux系统都可以用&&来执行多条命令 127.0.0.1&&net user      查看所有用户 Linux下输入127.0.0.1&&cat /etc/shadow甚至可以读取shadow文件     中级:相比Low级别的代码,服务器端对ip参数做了一定过滤,即把”&&” 、”;”删除,本质上采用的是黑名单机制,因此依旧存在安全问题。  // Set blacklist       $substitutions = array(           '&&' => '',           ';'  => '',       );   127.0.0.1&net user   因为被过滤的只有”&&”与” ;”,所以”&”不会受影响。 这里需要注意的是”&&”与” &”的区别:   Command 1&&Command 2   先执行Command 1,执行成功后执行Command 2,否则不执行Command 2 Command 1&Command 2   先执行Command 1,不管是否成功,都会执行Command 2   由于使用的是str_replace把”&&” 、”;”替换为空字符,因此可以采用以下方式绕过:   127.0.0.1&;&ipconfig 因为”127.0.0.1&;&ipconfig”中的” ;”会被替换为空字符,这样一来就变成了”127.0.0.1&& ipconfig” ,会成功执行。     高级: $substitutions = array(           '&'  => '',           ';'  => '',           '|  ' => '',           '-'  => '',           '$'  => '',           '('  => '',           ')'  => '',           '`'  => '',           '||' => '',       ); High级别的代码进一步完善了黑名单,但由于黑名单机制的局限性,我们依然可以绕过。 黑名单看似过滤了所有的非法字符,但仔细观察到是把”| ”(注意这里|后有一个空格)替换为空字符,于是 ”|”成了“漏网之鱼”。 127.0.0.1|net user   Command 1 | Command 2   “|”是管道符,表示将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果。     CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用。   初级:服务器收到修改密码的请求后,会检查参数password_new与password_conf是否相同,如果相同,就会修改密码,并没有任何的防CSRF机制(当然服务器对请求的发送者是做了身份验证的,是检查的cookie,只是这里的代码没有体现)。 if( isset( $_GET[ 'Change' ] ) ) {     // Get input     $pass_new  = $_GET[ 'password_new' ];     $pass_conf = $_GET[ 'password_conf' ];   1.构造链接 最基础的: http://192.168.153.130/dvwa/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change# 当受害者点击了这个链接,他的密码就会被改成password(这种攻击显得有些拙劣,链接一眼就能看出来是改密码的,而且受害者点了链接之后看到这个页面就会知道自己的密码被篡改了)   需要注意的是,CSRF最关键的是利用受害者的cookie向服务器发送伪造请求,所以如果受害者之前用Chrome浏览器登录的这个系统,而用搜狗浏览器点击这个链接,攻击是不会触发的,因为搜狗浏览器并不能利用Chrome浏览器的cookie,所以会自动跳转到登录界面。   2.上面的链接太过于明显,所以我们可以使用短链接来隐藏URL(点击短链接,会自动跳转到真实网站):   如http://dwz.cn/****(可以搜索在线短链接制作)   本地搭的环境,服务器域名是ip所以无法生成相应的短链接,实际攻击场景下只要目标服务器的域名不是ip,是可以生成相应短链接的。   3.构造攻击页面   现实攻击场景下,这种方法需要事先在公网上传一个攻击页面,诱骗受害者去访问,真正能够在受害者不知情的情况下完成CSRF攻击。这里为了方便演示,就在本地写一个test.html,下面是具体代码。  

404

 

file not found.

当受害者访问test.html时,会误认为是自己点击的是一个失效的url,但实际上已经遭受了CSRF攻击,密码已经被修改为了hack。       中级:int eregi(string pattern, string string)   检查string中是否含有pattern(不区分大小写),如果有返回True,反之False。   代码检查了保留变量 HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名,这里是192.168.153.130),希望通过这种机制抵御CSRF攻击。   if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) {         // Get input         $pass_new  = $_GET[ 'password_new' ];         $pass_conf = $_GET[ 'password_conf' ]; 过滤规则是http包头的Referer参数的值中必须包含主机名(这里是192.168.153.130)   我们可以将攻击页面命名为192.168.153.130.html(页面被放置在攻击者的服务器里,这里是10.4.253.2)就可以绕过了 同时也可以用抓包进行修改,将Referer中的数,修改与Host一致的主机名     高级:代码加入了Anti-CSRF token机制,用户每次访问改密页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。   要绕过High级别的反CSRF机制,关键是要获取token,要利用受害者的cookie去修改密码的页面获取关键的token。 试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击,下面是代码。           
                             
  攻击思路是当受害者点击进入这个页面,脚本会通过一个看不见框架偷偷访问修改密码的页面,获取页面中的token,并向服务器发送改密请求,以完成CSRF攻击。   然而理想与现实的差距是巨大的,这里牵扯到了跨域问题,而现在的浏览器是不允许跨域请求的。这里简单解释下跨域,我们的框架iframe访问的地址是http://192.168.153.130/dvwa/vulnerabilities/csrf,位于服务器192.168.153.130上,而我们的攻击页面位于黑客服务器10.4.253.2上,两者的域名不同,域名B下的所有页面都不允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。   由于跨域是不能实现的,所以我们要将攻击代码注入到目标服务器192.168.153.130中,才有可能完成攻击。下面利用High级别的XSS漏洞协助获取Anti-CSRF token(因为这里的XSS注入有长度限制,不能够注入完整的攻击脚本,所以只获取Anti-CSRF token)。   Name存在XSS漏洞,于是抓包,改参数,成功弹出token 在抓包中将name的代码修改为: