2012-10-18 33 views
4

所以我一直在嘗試複製二次SQL注入。這是我準備的兩個基於php的網站的示例模板。我們把它稱爲選民登記表。用戶可以註冊,然後你可以檢查你是否是註冊選民。如何演示二階SQL注入?

insert.php

<?php 

$db_selected = mysql_select_db('canada',$conn); 
if (!db_selected) 
    die("can't use mysql: ". mysql_error()); 

$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town) 
        values ('".mysql_real_escape_string($_REQUEST["UserID"])."', 
        '".mysql_real_escape_string($_REQUEST["FirstName"])."', 
        '".mysql_real_escape_string($_REQUEST["LastName"])."', 
        ".intval($_REQUEST["Age"]).", 
        '".mysql_real_escape_string($_REQUEST["State"])."', 
        '".mysql_real_escape_string($_REQUEST["Town"])."')"; 

echo "You ran the sql query=".$sql_statement."<br/>"; 
$qry = mysql_query($sql_statement,$conn) || die (mysql_error()); 
mysql_close($conn); 
Echo "Data inserted successfully"; 
} 
?> 

select.php

<?php 


$db_selected = mysql_select_db('canada', $conn); 
if(!db_selected) 
    die('Can\'t use mysql:' . mysql_error()); 
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'"; 
echo "You ran the sql query=".$sql."<br/>"; 
$result = mysql_query($sql,$conn); 
$row=mysql_fetch_row($result); 

$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'"; 
echo "The web application ran the sql query internally=" .$sql1. "<br/>"; 
$result1 = mysql_query($sql1, $conn); 
$row1 = mysql_fetch_row($result1); 

mysql_close($conn); 
echo "<br><b><center>Database Output</center></b><br><br>"; 

echo "<br>$row1[1] $row1[2] , you are a voter! <br>"; 

echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2] 
    <br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>"; 
} 
?> 

所以我特意讓這個脆弱的顯示順序SQL注入怎樣的第二部作品,用戶可以在輸入一個代碼到的第一個名字部分(我目前卡住了,我嘗試了很多不同的方式,但似乎我無法做到)。 然後,當一個人想要激活他已經插入名字部分的代碼時,他所需要做的只是鍵入userID並插入代碼。

例如: 我會鍵入到insert.php頁面: 用戶id = 17

姓=(我需要注入的東西在這裏)

姓氏= ..

年齡= ..

鎮= ..

狀態= ..

然後,當我檢查我的詳細信息並輸入17時,注入的SQL腳本將被激活。 我能舉幾個例子說明我可以通過這個漏洞發現哪些類型的漏洞嗎?

+3

3.僅發佈相關代碼 –

+0

試用本演示,如果您不理解或無法應用,請與我們聯繫。 http://www.esecforte.com/blog/second-order-sql-injection/ – PyQL

+0

我基於我的示例從該網站。但它並沒有爲我工作,因爲我無法得到輸出顯示爲如何出現在該示例 – yoshifish

回答

3

使用的第一名稱:

' OR 1 OR ' 

這將在

WHERE姓= '' OR 1 OR ''

第二SQL產生where子句因此結果將成爲表格中的第一條記錄。 -

顯然只會提取

'OR 1 ORDER BY用戶名ASC LIMIT 0,1:

通過增加一個LIMIT子句,您可以提取從表中的所有行每次1行,因此您需要重複該操作並在LIMIT中增加0。本示例使用註釋--來終止剩餘的SQL,否則會導致查詢失敗,因爲它會在您的LIMIT之後添加單引號。

上面是一個簡單的例子,更復雜的攻擊是使用UNION SELECT,它會讓您通過使用information_schema訪問整個數據庫。

另外您在其中一個查詢中使用了addslashes()。這並不像mysql_real_escape_string()那樣安全,反過來:使用兩者之一來轉義引號並不像使用預處理語句或參數化查詢那樣安全,例如在PDO或MySQLi中。

+0

謝謝,這只是爲了顯示網站的脆弱一面。我也一直試圖刪除表,但它似乎並沒有工作。如何將該命令添加到名稱部分的'drop database/drop table'中? – yoshifish

+0

你不能因爲'mysql_query()'不支持多個查詢,所以不可能添加一個DROP查詢。請參閱:http://php.net/manual/en/function.mysql-query.php – MrCode

+0

那麼,我可以顯示哪些其他漏洞? – yoshifish

3

那裏有什麼證明?

二階SQL注入只不過是SQL注入,但不安全的代碼不是第一行。

因此,證明:

1)創建一個SQL注入字符串時,不逃避執行的,會做一些不必要的。

2)將該字符串安全地存儲在數據庫中(有轉義)。

3)讓你的代碼的其他部分FETCH那個字符串,並在別處使用而不會轉義。

編輯:添加一些examplecode:

一個表:

CREATE TABLE tblUsers (
    userId serial PRIMARY KEY, 
    firstName TEXT 
) 

假設你有一些安全的代碼是這樣,從形式接收姓:

$firstname = someEscapeFunction($_POST["firstname"]); 

$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');"; 
someConnection->execute($SQL); 

到目前爲止,好,假設someEscapeFunction()做得很好。注入SQL是不可能的。

如果我會爲姓以下行發送值,你不會介意:

喇嘛');從tblUsers刪除; //

現在,假設在同一系統上有人想從向tblUsers到tblWhatever運輸名字,以及這是否是這樣的:

$userid = 42; 
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})"; 
$RS = con->fetchAll($SQL); 
$firstName = $RS[0]["firstName"]; 

然後將其插入到tblWhatever沒有逃脫:

$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');"; 

現在,如果firstname包含一些deletecommand,它仍然會被執行。

+0

多數民衆贊成在問題......我不知道我怎麼能存儲和獲取代碼。單一的例子,如存儲數據庫中的重複條目或任何東西。使用單擊命令獲取數據庫條目更復雜一些? – yoshifish

+1

我添加了一個更具體的例子。 –