zoukankan      html  css  js  c++  java
  • 代码审计-DVWA-SQL注入

    新手入门篇,不是很深入。

    DVWA代码审计-SQL注入

    low

    <?php
    if( isset( $_REQUEST[ 'Submit' ] ) ) {
        // Get input
        $id = $_REQUEST[ 'id' ];
        // Check database
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
        $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>' );
        // Get results
        while( $row = mysqli_fetch_assoc( $result ) ) {
            // Get values
            $first = $row["first_name"];
            $last  = $row["last_name"];
            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
        mysqli_close($GLOBALS["___mysqli_ston"]);
    }
    ?> 
    

    1、接收从表单中传来的数据,并将name为id的值赋给变量id。
    2、query变量是处理sql语句的方式,可以看到没有进行任何过滤,直接将用户输入的拼接到sql语句中,通过单引号闭合,那么便存在字符型注入。
    3、mysqli_query()函数执行某个针对数据库的查询。$_GLOBALS["__mysqli_ston"]是规定使用的MySQL连接,$query就是查询语句。mysqli_query()针对成功的SELECT、SHOW、DESCRIBE、EXPLAIN查询,将返回一个mysqli_result对象,针对其他成功的查询返回true,失败返回false。or die()即如果前面的返回result对象失败,那么执行后面的die()语句,后面是两个三目运算符的嵌套,现在读起来比价困难
    4、从mysqli_query()中返回的result中,使用mysqli_fetch_assoc()函数从结果集中取得一行作为关联数组。
    5、使用while循环遍历并输出。
    6、mysqli_close()函数关闭先前打开的数据库连接。

    medium

    <?php
    if( isset( $_POST[ 'Submit' ] ) ) {
        // Get input
        $id = $_POST[ 'id' ];
        $id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );
        // Get results
        while( $row = mysqli_fetch_assoc( $result ) ) {
            // Display values
            $first = $row["first_name"];
            $last  = $row["last_name"];
            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
    }
    // This is used later on in the index.php page
    // Setting it here so we can close the database connection in here like in the rest of the source scripts
    $query  = "SELECT COUNT(*) FROM users;";
    $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>' );
    $number_of_rows = mysqli_fetch_row( $result )[0];
    mysqli_close($GLOBALS["___mysqli_ston"]);
    ?> 
    

    1、从mysqli_real_escape_string()函数开始,$GLOBALS["___mysqli_ston"]是必选项,规定使用的MySQL连接(这个地方菜鸟教程和w3cschool冲突了,菜鸟是必选;w3c是可选,如果未规定,则使用上一个连接);$id同样是必选项,它是要转义的字符串,编码的字符是NUL(ASCII 0)、 、 、、'、"和Contol-Z。如果成功,该函数返回被转义的字符串,失败返回false,也就是说这个地方能够过滤单双引号。
    2、但是从下面的sql语句中可以看到,它也是直接拼接在sql语句中,且没有单双引号包裹,虽然上面有转义,但是没什么意义,因为这边是数字型注入。且注意是POST方式传入数据。
    3、后面就不写了,太菜了,读起来太困难了,算是先埋坑吧。

    high

    <?php
    if( isset( $_SESSION [ 'id' ] ) ) {
        // Get input
        $id = $_SESSION[ 'id' ];
        // Check database
        $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
        $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );
        // Get results
        while( $row = mysqli_fetch_assoc( $result ) ) {
            // Get values
            $first = $row["first_name"];
            $last  = $row["last_name"];
            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
        ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);        
    }
    ?> 
    

    1、额,这个的话就是从session中取得用户参数,可能考验的是注入点的位置。像注入点的话凡是直接与数据库交互的话就可能存在。

    imposeable

    <?php
    if( isset( $_GET[ 'Submit' ] ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
        // Get input
        $id = $_GET[ 'id' ];
        // Was a number entered?
        if(is_numeric( $id )) {
            // Check the database
            $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
            $data->bindParam( ':id', $id, PDO::PARAM_INT );
            $data->execute();
            $row = $data->fetch();
            // Make sure only 1 result is returned
            if( $data->rowCount() == 1 ) {
                // Get values
                $first = $row[ 'first_name' ];
                $last  = $row[ 'last_name' ];
                // Feedback for end user
                echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
            }
        }
    }
    // Generate Anti-CSRF token
    generateSessionToken();
    ?> 
    

    1、前面的checkToken()检查token就不说了。
    2、在处理用户输入的时候,首先是判断用户输入的是不是数字类型,is_nummic()函数判断id是否是数字,是返回true,否则返回false。emmm、、这、、效率也太高了,通过这个判断可以将特殊字符或or、xor等都过滤掉,因为限制只能是纯数字。当然,这是因为该功能点只要输入数字,像其他输入字符串的肯定没有这么容易。
    3、再看里面操作,使用的是MySQL预处理语句,参考链接至于这个预处理绑定这个语句,着实不会,不敢乱描述,先这样。


    如果大家发现有什么错误请联系QQ:472668561

  • 相关阅读:
    js面对对象和jQuery的使用
    感知器PLA算法
    MSP430G2系列学习笔记
    数学建模——规划问题
    51单片机学习(一)
    打靶法求解两点边值问题
    GAOT工具箱(遗传算法)的应用
    数学建模方法
    关于mysql 5.7 版本登录时出现错误 1045的随笔
    oracle复习(二)
  • 原文地址:https://www.cnblogs.com/ahtoh/p/12096548.html
Copyright © 2011-2022 走看看