標籤:
0x01 背景
PHP程式員在開發過程中難免會使用一些字元替換函數(str_replace)、反轉義函數(stripslashes),但這些函數使用位置不當就會繞過全域的防護造成SQL注入漏洞。
0x03 漏洞分析str_replace函數的錯誤使用
第一種情況是寫程式時會使用str_replace函數將參數中的單引號、括弧等字元替換為空白,這樣在一些雙條件查詢的情況就會引發注入問題。缺陷代碼如下:
<?php require_once(‘common.php‘); $conn = mysql_connect(‘localhost‘, ‘root‘, ‘braid‘) or die(‘bad!‘); mysql_query("SET NAMES binary‘"); mysql_select_db(‘test‘, $conn) OR emMsg("資料庫連接失敗"); $tmp_id = isset($_GET[‘id‘]) ? $_GET[‘id‘] : 1; $title = isset($_GET[‘title‘]) ? $_GET[‘title‘] : ‘news title‘; //程式編寫時直接用str_replace去掉id裡的單引號 $id = str_replace("‘",‘‘,$tmp_id); //sql查詢語句通過id和titile兩個條件進行查詢 $sql = "SELECT * FROM news WHERE id=‘{$id}‘ and title=‘{$title}‘"; echo $sql; $result = mysql_query($sql, $conn) or die(mysql_error()); ?>
|
瀏覽器輸入”http://localhost/sqltest/streplace.php?id=1‘&title=news title”,發現報錯了,我們直接列印出執行的sql語句如:
發現參數id右邊的單引號被反斜線轉義成字元了,說明又可以注入了。
簡單分析下上面id參數的執行過程,-1’經過addslashes函數轉義後變成了-1\’,然後再經過str_replace函數幹掉了單引號變成了-1\,最後帶入查詢的語句才是下面這樣:
SELECT * FROM news WHERE id=‘1\‘ and title=‘news title‘
反斜線轉義了sql查詢語句裡id後面那個單引號,導致title參數可以構造sql注入語句了,我們直接構造擷取管理員賬戶密碼的語句”http://localhost/sqltest/streplace.php?id=-1‘&title=unionselect 1,2,concat(name,0x23,pass) from admin%23”
第二種情況是str_replace函數是使用者可控的,就是說使用者想把啥替換成空就可以將什麼替換為空白。
首先我們先看看addslashes函數對%00-%ff的轉義情況,經過fuzz發現%00會被轉義為\0,如下:
那麼注入的時候我們提交%00’,經過addlashes就會變為\0\’,這時候我們用replace函數替換0為空白就變成了\‘,成功轉義了逸出字元讓單引號逃逸出來,從而造成注入漏洞。
stripslashes函數的錯誤使用
這個函數的定義是刪除由 addslashes() 函數添加的反斜線,所以很明顯使用不當的話就會引發SQL注入。缺陷代碼如下:
<?php require_once(‘common.php‘); $conn = mysql_connect(‘localhost‘, ‘root‘, ‘braid‘) or die(‘bad!‘); mysql_query("SET NAMES binary‘"); mysql_select_db(‘test‘, $conn) OR emMsg("資料庫連接失敗"); $tmp_id = isset($_GET[‘id‘]) ? $_GET[‘id‘] : 1; $id = stripslashes($tmp_id); $sql = "SELECT * FROM news WHERE id=‘{$id}‘"; echo $sql.‘<br />‘; $result = mysql_query($sql, $conn) or die(mysql_error()); ?>
|
瀏覽器輸入”http://localhost/sqltest/stripslashes.php?id=-1‘",發現報錯了,echo出執行的sql語句如:
分析下參數id的執行過程,-1’經過addslashes函數轉義後變成了-1\’,然後再經過stripslashes函數幹掉了反斜線變成了-1’,所以又可以愉快的注入了。
擷取管理員賬戶密碼的語句”http://localhost/sqltest/stripslashes.php?id=-1‘ union select 1,2,concat(name,0x23,pass) from admin%23”
原文連結:http://www.cnbraid.com/2016/04/29/sql5/,如需轉載請聯絡作者。
【PHP代碼審計】 那些年我們一起挖掘SQL注入 - 6.全域防護Bypass之一些函數的錯誤使用