目錄
- 2.5 二次注入攻擊
- 2.6 二次注入代碼分析
2.5 二次注入攻擊
??二次注入攻擊的測驗地址:http://127.0.0.1/sqli/double1.php?username=test 和 http://127.0.0.1/sqli/double2.php?id=1, 其中,double1.php頁面的功能是注冊用戶名,也是插入SQL陳述句的地方;double2.php頁面的功能是通過引數ID讀取用戶名和用戶資訊,
??第一步,訪問double1.php?username=test’,如圖40所示,
圖40 注冊用戶名test'
??從頁面回傳結果可以看到用戶名test’對用的ID為9,訪問double2.PHP?id=9,結果如圖41所示,
圖40 訪問test'的資訊
??從回傳結果可以看到服務端回傳了MySQL的錯誤(多了一個單引號引起的語法錯誤),這時回到第一步,先訪問double1.php?username=test’ order by 1–+,獲取一個新的id=10,當再次訪問double2.php?id=10時,頁面回傳空白;再次嘗試,訪問double1.php?username=test’ order by 10–+,獲取一個新的id=11,當再次訪問double2.php?id=11時,頁面回傳錯誤資訊(Unknown column ‘10’ in ‘order clause’),如圖42所示,
圖42 訪問order by 10的結果
??這說明空白頁面就是正常回傳,通過不斷地嘗試,筆者判斷出資料庫中一共有3個欄位,
??訪問double1.php?username=test’ union select 1,2,3–+,獲取一個新id=12,再訪問double2.php?id=12,發現頁面回傳了union select中的1和2欄位,結果如圖43所示,
圖43 使用Union陳述句的結果
??在2或3的位置,插入我們的陳述句,比如訪問double1.php?username=test’ union select 1,user(),3–+,獲得新的id=13,再訪問double2.php?id=13,得到user()的結果,如圖44所示,使用此方法就可以獲取資料庫中的資料,
圖44 利用二次注入獲取資料
2.6 二次注入代碼分析
??二次注入中double1.php頁面的代碼如下所示,實作了簡單的用戶注冊功能,程式獲取到GET引數username的引數password,然后將username和password拼接到SQL陳述句,使用insert陳述句插入到資料庫中,由于引數username使用addslashes進行轉義(轉義了單引號,導致單引號無法閉合),引數password進行了MD5哈希,所以此處不存在SQL注入漏洞,
<?php header('Content-type:text/html;charset=utf-8');
$con=mysqli_connect("localhost","root","root","test");
if (mysqli_connect_errno())
{
echo "連接失敗: " . mysqli_connect_error();
}
$username = @$_GET['username'];
$password = @$_GET['password'];
$result = mysqli_query($con,"insert into users(`username`,`password`) values ('".addslashes($username)."','".md5($password)."')");
echo "新的id為:".mysqli_insert_id($con);
?>
??當訪問username=test’&password=123456時,執行的SQL陳述句為:
insert into users(`username`,`password`) values ('test\'','e10adc3949ba59abbe56e057f20f883e')
??從圖45中的資料庫里可以看到,插入的用戶是test’,
圖45 插入到資料庫中的資料
??在二次注入中double2.php中的代碼如下所示,首先將GET引數ID轉換成int型別(防止拼接到SQL陳述句時,存在SQL注入漏洞),然后到users表中獲取ID對應的username,接著到person表中查詢username對應的資料,
<?php header('Content-type:text/html;charset=utf-8');
$con=mysqli_connect("localhost","root","root","test");
if (mysqli_connect_errno())
{
echo "連接失敗: " . mysqli_connect_error();
}
$id = intval(@$_GET['id']);
$result = mysqli_query($con,"select * from users where `id`=".$id);
$row = mysqli_fetch_array($result);
$username = $row['username'];
$result2 = mysqli_query($con,"select * from person where `username`='".$username."'");
if (!$result2)
{
echo mysqli_error($con);
exit();
}
if($row2 = mysqli_fetch_array($result2))
{
echo $row2['username'] . " : " . $row2['money'];
}
else
{
echo mysqli_error($con);
}
?>
??但是此處沒有對$username進行轉義,在第一步中我們注冊的用戶名是test’,此時執行的SQL陳述句為:
select * from users where `username`='test''
??單引號被帶入SQL陳述句中,由于多了一個單引號,所以頁面會報錯,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302178.html
標籤:其他
