二次注入攻擊
二次注入攻擊的測試地址在本書第2章。
double1.php頁面的功能是新增使用者。
第一步,輸入使用者名稱test'和密碼123456,如圖4-45所示,單擊“send”按鈕提交。
圖4-45
頁面返回連結/4.3/double2.php?id=4,是新增的新使用者個人資訊的頁面,訪問該連結,結果如圖4-46所示。
圖4-46
從返回結果可以看出,伺服器端返回了MySQL的錯誤(多了一個單引號引起的語法錯誤),這時回到第一步,在使用者名稱處填寫test' order by 1%23,提交後,獲取一個新的id=5,當再次訪問double2.php?id=5時,頁面返回正常結果;再次嘗試,在使用者名稱處填寫test' order by 10%23,提交後,獲取一個新的id=6,當再訪問double2.php?id=6時,頁面返回錯誤資訊(Unknown column '10' in 'order clause'),如圖4-47所示。
圖4-47
這說明空白頁面就是正常返回。不斷嘗試後,筆者判斷資料庫表中一共有4個欄位。在使用者名稱處填寫-test' union select 1,2,3,4%23,提交後,獲取一個新的id=7,再訪問double2.php?id=7,發現頁面返回了union select中的2和3欄位,結果如圖4-48所示。
圖4-48
在2或3的位置,插入我們的語句,比如在使用者名稱處填寫-test' union select 1,user(), 3,4#,提交後,獲得一個新的id=8,再訪問double2.php?id=8,得到user()的結果,如圖4-49所示,使用此方法就可以獲取資料庫中的資料。
圖4-49
二次注入程式碼分析
二次注入中double1.php頁面的程式碼如下所示,實現了簡單的使用者註冊功能,程式先獲取GET引數“username”和引數“password”,然後將“username”和“password”拼接到SQL語句中,最後使用insert語句將引數“username”和“password”插入資料庫。由於引數“username”使用addslashes函式進行了轉義(轉義了單引號,導致單引號無法閉合),引數“password”進行了MD5雜湊,所以此處不存在SQL隱碼攻擊漏洞。
<?php $con=mysqli_connect("localhost","root","123456","test"); if (mysqli_connect_errno()) { echo "連線失敗: " . mysqli_connect_error(); } $username = $_POST['username']; $password = $_POST['password']; $result = mysqli_query($con,"insert into users(`username`,`password`) values ('".addslashes($username)."','".md5($password)."')"); echo '<a href="/4.3/double2.php?id='. mysqli_insert_id($con) .'">使用者資訊</a>';?>
當訪問username=test'&password=123456時,執行的SQL語句如下:
insert into users(`username`,`password`) values ('test\'', 'e10adc3949ba59abbe56e057f20f883e')
從圖4-50所示的資料庫中可以看出,插入的使用者名稱是test'。
圖4-50
在二次注入中,double2.php中的程式碼如下:
<?php$con=mysqli_connect("localhost","root","123456","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 winfo where `username`='".$username."'");if($row2 = mysqli_fetch_array($result2)){echo $row2['username'] . " : " . $row2['address'];}else{echo mysqli_error($con);}?>
先將GET引數ID轉成int型別(防止拼接到SQL語句時,存在SQL隱碼攻擊漏洞),然後到users表中獲取ID對應的username,接著到winfo表中查詢username對應的資料。
但是此處沒有對$username進行轉義,在第一步中註冊的使用者名稱是test',此時執行的SQL語句如下:
select * from winfo where `username`='test''
單引號被帶入SQL語句中,由於多了一個單引號,所以頁面會報錯。
Ms08067安全實驗室專注於網路安全知識的普及和培訓,是專業的“圖書出版+培訓”的網路安全線上教育平臺,專注於網路安全領域中高階人才培養。
平臺已開設Web安全零基礎就業,Web高階安全攻防進階,紅隊實戰攻防特訓,Java程式碼安全審計,惡意程式碼分析與免殺實戰,CTF基礎實戰特訓營,網路安全應急響應,安全工具開發,AI與網路安全等系統培訓課程。實驗室出版安全圖書《Web安全攻防:滲透測試實戰指南》、《內網安全攻防:滲透測試實戰指南》、《Python安全攻防:滲透測試實戰指南》、《Java程式碼審計:入門篇》等。
掃描客服微信 獲取更多課件+學習資料