淺談開啟magic_quote_gpc后的sql注入攻擊與防范
更新時間:2012年01月15日 19:15:49 作者:
通過啟用php.ini配置文件中的相關(guān)選項,就可以將大部分想利用SQL注入漏洞的駭客拒絕于門外
通過啟用php.ini配置文件中的相關(guān)選項,就可以將大部分想利用SQL注入漏洞的駭客拒絕于門外。
開啟magic_quote_gpc=on之后,能實現(xiàn)addslshes()和stripslashes()這兩個函數(shù)的功能。在PHP4.0及以上的版本中,該選項默認情況下是開啟的,所以在PHP4.0及以上的版本中,就算PHP程序中的參數(shù)沒有進行過濾,PHP系統(tǒng)也會對每一個通過GET、POST、COOKIE方式傳遞的變量自動轉(zhuǎn)換,換句話說,輸入的注入攻擊代碼將會全部被轉(zhuǎn)換,將給攻擊者帶來非常大的困難。
雖然如此,攻擊者仍然有機會進行SQL注入攻擊。。。。。。前提是,當參數(shù)為數(shù)字型的時候,且未經(jīng)過Intval()函數(shù)的處理,因為經(jīng)過intval()的處理之后,所有的數(shù)據(jù)就都會強制轉(zhuǎn)換成數(shù)字。
前面已經(jīng)提到過,開啟magic_quote_gpc=on之后,相當于使用addslshes()這個函數(shù)。但是數(shù)字型沒有用到單引號,所以理所當然的繞過了addslshes()函數(shù)的轉(zhuǎn)換了。而使用MySQL自帶的char()函數(shù)或者HEX(),char()可以將參數(shù)解釋為整數(shù)并且返回這些整數(shù)的ASCII碼字符組成的字符串,使用十六進制表示必須在數(shù)字前加上0x。
實例演示:
假設(shè)我們知道管理員的用戶名為admin,密碼不知道。并且已經(jīng)將magic_quote_gpc啟用。
SQL語句:$sql="select * from users where username=$name and password='$pwd'";注意:變量$name沒加引號
此時,在地址欄中輸入username=admin%23,則合成后的sql語句為:
select * from users where username='admin\' #' and password='';
這時候通過url地址欄輸入的單引號(')將被加上反斜線,該sql語句將失效。
admin轉(zhuǎn)換成ASCII后是char(97,100,109,105,110)
此時在地址欄中輸入username=char(97,100,109,105,110)%23
SQL語句就變成了:
select * from users where username=char(97,100,109,105,110)#' and password='';
執(zhí)行結(jié)果為真,就可以順利進入后臺。
對于數(shù)字型注入攻擊,必須在任何的數(shù)字型參數(shù)放入數(shù)據(jù)庫之前使用intval()對參數(shù)進行強制轉(zhuǎn)換成數(shù)字,從而可以斷絕數(shù)字型注入漏洞的產(chǎn)生。
比如:$id=intval($_GET[‘id']);
select * from articles where id='$id';
地址欄中輸入:id=5' or 1=1%23
SQL語句將變成:select * from articles where id='5';
而不是select * from articles where id='5' or 1=1#;
總結(jié):
對于每一個變量都記得加上單引號,比如where username='$name',
開啟magic_quote_gpc并不是絕對安全的,對于數(shù)字型注入攻擊,僅僅使用addslashes()函數(shù)進行轉(zhuǎn)換是不夠的,還需使用intval()強制將參數(shù)轉(zhuǎn)換成數(shù)字
如何防止SQL注入攻擊
方法一:密碼比對
思路:首先通過用戶輸入的用戶名去查詢數(shù)據(jù)庫,得到該用戶名在數(shù)據(jù)庫中對應(yīng)的密碼,再將從數(shù)據(jù)庫中查詢到的密碼和用戶提交過來的密碼進行比對。
代碼:
$sql="select password from users where username='$name'";
$res=mysql_query($sql,$conn);
if ($arr=mysql_fetch_assoc($res)){//如果用戶名存在
if ($arr['password']==$pwd) {//密碼比對
echo "登錄成功";
}else{
echo "密碼輸入有誤";
}
}else {
echo "該用戶名不存在";
}
分析:該情況下,代碼健壯了不少,即使在magic_quote_gpc=Off的情況下,也能防止SQL注入攻擊。因為攻擊者想成功登錄的話,得繞過兩道坎,第一是輸入的用戶名要存在,這一步可以構(gòu)造一個SQL語句(‘ or 1=1%23)直接繞過,但是這樣子無法通過第二道坎。因為需要用戶輸入一個正確的密碼才能通過,顯然,這已經(jīng)拒絕了SQL注入攻擊。
方法二:使用PDO的PDO::prepare()預(yù)處理操作來防止SQL注入攻擊
思路:創(chuàng)建一個pdo對象,利用pdo的預(yù)處理操作可以防止SQL注入攻擊
代碼:
$name=$_GET['username'];
$pwd=$_GET['password'];
$sql="select * from users where username=? and password=?";
//1.創(chuàng)建一個pdo對象
$pdo=new PDO("mysql:host=localhost;port=3306;dbname=injection","root","");
//2.設(shè)置編碼
$pdo->exec("set names 'utf8'");
//3.預(yù)處理$sql語句
$pdoStatement=$pdo->prepare($sql);
//4.把接收到的用戶名和密碼填入
$pdoStatement->execute(array($name,$pwd));
//5.取出結(jié)果
$res=$pdoStatement->fetch();
if(empty($res)){
echo "用戶名或密碼輸入有誤";
}else{
echo "登錄成功";
}
開啟magic_quote_gpc=on之后,能實現(xiàn)addslshes()和stripslashes()這兩個函數(shù)的功能。在PHP4.0及以上的版本中,該選項默認情況下是開啟的,所以在PHP4.0及以上的版本中,就算PHP程序中的參數(shù)沒有進行過濾,PHP系統(tǒng)也會對每一個通過GET、POST、COOKIE方式傳遞的變量自動轉(zhuǎn)換,換句話說,輸入的注入攻擊代碼將會全部被轉(zhuǎn)換,將給攻擊者帶來非常大的困難。
雖然如此,攻擊者仍然有機會進行SQL注入攻擊。。。。。。前提是,當參數(shù)為數(shù)字型的時候,且未經(jīng)過Intval()函數(shù)的處理,因為經(jīng)過intval()的處理之后,所有的數(shù)據(jù)就都會強制轉(zhuǎn)換成數(shù)字。
前面已經(jīng)提到過,開啟magic_quote_gpc=on之后,相當于使用addslshes()這個函數(shù)。但是數(shù)字型沒有用到單引號,所以理所當然的繞過了addslshes()函數(shù)的轉(zhuǎn)換了。而使用MySQL自帶的char()函數(shù)或者HEX(),char()可以將參數(shù)解釋為整數(shù)并且返回這些整數(shù)的ASCII碼字符組成的字符串,使用十六進制表示必須在數(shù)字前加上0x。
實例演示:
假設(shè)我們知道管理員的用戶名為admin,密碼不知道。并且已經(jīng)將magic_quote_gpc啟用。
SQL語句:$sql="select * from users where username=$name and password='$pwd'";注意:變量$name沒加引號
此時,在地址欄中輸入username=admin%23,則合成后的sql語句為:
select * from users where username='admin\' #' and password='';
這時候通過url地址欄輸入的單引號(')將被加上反斜線,該sql語句將失效。
admin轉(zhuǎn)換成ASCII后是char(97,100,109,105,110)
此時在地址欄中輸入username=char(97,100,109,105,110)%23
SQL語句就變成了:
select * from users where username=char(97,100,109,105,110)#' and password='';
執(zhí)行結(jié)果為真,就可以順利進入后臺。
對于數(shù)字型注入攻擊,必須在任何的數(shù)字型參數(shù)放入數(shù)據(jù)庫之前使用intval()對參數(shù)進行強制轉(zhuǎn)換成數(shù)字,從而可以斷絕數(shù)字型注入漏洞的產(chǎn)生。
比如:$id=intval($_GET[‘id']);
select * from articles where id='$id';
地址欄中輸入:id=5' or 1=1%23
SQL語句將變成:select * from articles where id='5';
而不是select * from articles where id='5' or 1=1#;
總結(jié):
對于每一個變量都記得加上單引號,比如where username='$name',
開啟magic_quote_gpc并不是絕對安全的,對于數(shù)字型注入攻擊,僅僅使用addslashes()函數(shù)進行轉(zhuǎn)換是不夠的,還需使用intval()強制將參數(shù)轉(zhuǎn)換成數(shù)字
如何防止SQL注入攻擊
方法一:密碼比對
思路:首先通過用戶輸入的用戶名去查詢數(shù)據(jù)庫,得到該用戶名在數(shù)據(jù)庫中對應(yīng)的密碼,再將從數(shù)據(jù)庫中查詢到的密碼和用戶提交過來的密碼進行比對。
代碼:
復(fù)制代碼 代碼如下:
$sql="select password from users where username='$name'";
$res=mysql_query($sql,$conn);
if ($arr=mysql_fetch_assoc($res)){//如果用戶名存在
if ($arr['password']==$pwd) {//密碼比對
echo "登錄成功";
}else{
echo "密碼輸入有誤";
}
}else {
echo "該用戶名不存在";
}
分析:該情況下,代碼健壯了不少,即使在magic_quote_gpc=Off的情況下,也能防止SQL注入攻擊。因為攻擊者想成功登錄的話,得繞過兩道坎,第一是輸入的用戶名要存在,這一步可以構(gòu)造一個SQL語句(‘ or 1=1%23)直接繞過,但是這樣子無法通過第二道坎。因為需要用戶輸入一個正確的密碼才能通過,顯然,這已經(jīng)拒絕了SQL注入攻擊。
方法二:使用PDO的PDO::prepare()預(yù)處理操作來防止SQL注入攻擊
思路:創(chuàng)建一個pdo對象,利用pdo的預(yù)處理操作可以防止SQL注入攻擊
代碼:
復(fù)制代碼 代碼如下:
$name=$_GET['username'];
$pwd=$_GET['password'];
$sql="select * from users where username=? and password=?";
//1.創(chuàng)建一個pdo對象
$pdo=new PDO("mysql:host=localhost;port=3306;dbname=injection","root","");
//2.設(shè)置編碼
$pdo->exec("set names 'utf8'");
//3.預(yù)處理$sql語句
$pdoStatement=$pdo->prepare($sql);
//4.把接收到的用戶名和密碼填入
$pdoStatement->execute(array($name,$pwd));
//5.取出結(jié)果
$res=$pdoStatement->fetch();
if(empty($res)){
echo "用戶名或密碼輸入有誤";
}else{
echo "登錄成功";
}
相關(guān)文章
mysql 8.0.18.zip安裝配置方法圖文教程(windows 64位)
這篇文章主要為大家詳細介紹了mysql 8.0.18.zip安裝配置方法圖文教程,以及卸載以前數(shù)據(jù)庫的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-10-10MySql中取前幾行數(shù)據(jù)使用limit來完成
在mysql中是沒有top關(guān)鍵字的,不過可以用limit來完成此功能,下面舉例為大家詳細介紹下它的使用方法,不會的朋友可以學(xué)習(xí)下2013-07-07