我的问题是我的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; - 或者在登录窗口中有类似的东西时,它只是显示登录失败它让我疯狂。
感谢您的时间,我希望我的问题很清楚,祝您有个美好的一天。
答案 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>