一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

PHP+SQL 注入攻擊的技術(shù)實(shí)現(xiàn)以及預(yù)防辦法

總結(jié)一下經(jīng)驗(yàn)。在我看來(lái),引發(fā) SQL 注入攻擊的主要原因,是因?yàn)橐韵聝牲c(diǎn)原因:
  1. php 配置文件 php.ini 中的 magic_quotes_gpc 選項(xiàng)沒(méi)有打開(kāi),被置為 off
  2. 開(kāi)發(fā)者沒(méi)有對(duì)數(shù)據(jù)類型進(jìn)行檢查和轉(zhuǎn)義
  不過(guò)事實(shí)上,第二點(diǎn)最為重要。我認(rèn)為, 對(duì)用戶輸入的數(shù)據(jù)類型進(jìn)行檢查,向 MYSQL 提交正確的數(shù)據(jù)類型,這應(yīng)該是一個(gè) web 程序員最最基本的素質(zhì)。但現(xiàn)實(shí)中,常常有許多小白式的 Web 開(kāi)發(fā)者忘了這點(diǎn), 從而導(dǎo)致后門(mén)大開(kāi)。
  為什么說(shuō)第二點(diǎn)最為重要?因?yàn)槿绻麤](méi)有第二點(diǎn)的保證,magic_quotes_gpc 選項(xiàng),不論為 on,還是為 off,都有可能引發(fā) SQL 注入攻擊。下面來(lái)看一下技術(shù)實(shí)現(xiàn):
 一. magic_quotes_gpc = Off 時(shí)的注入攻擊
  magic_quotes_gpc = Off 是 php 中一種非常不安全的選項(xiàng)。新版本的 php 已經(jīng)將默認(rèn)的值改為了 On。但仍有相當(dāng)多的服務(wù)器的選項(xiàng)為 off。畢竟,再古董的服務(wù)器也是有人用的。
  當(dāng)magic_quotes_gpc = On 時(shí),它會(huì)將提交的變量中所有的 '(單引號(hào))、"(雙號(hào)號(hào))、/(反斜線)、空白字符,都為在前面自動(dòng)加上 /。下面是 php 的官方說(shuō)明:

復(fù)制代碼 代碼如下:
magic_quotes_gpc boolean

Sets the magic_quotes state for GPC (Get/Post/Cookie) operations. When magic_quotes are on, all ' (single-quote), " (double quote), / (backslash) and NUL's are escaped with a backslash automatically

如果沒(méi)有轉(zhuǎn)義,即 off 情況下,就會(huì)讓攻擊者有機(jī)可乘。以下列測(cè)試腳本為例:
復(fù)制代碼 代碼如下:
<?
if ( isset($_POST["f_login"] ) )
{
// 連接數(shù)據(jù)庫(kù)...
// ...代碼略...

// 檢查用戶是否存在
$t_strUname = $_POST["f_uname"];
$t_strPwd = $_POST["f_pwd"];
$t_strSQL = "SELECT * FROM tbl_users WHERE username='$t_strUname' AND password = '$t_strPwd' LIMIT 0,1";

if ( $t_hRes = mysql_query($t_strSQL) )
{
// 成功查詢之后的處理. 略...
}
}
?>

<html><head><title>sample test</title></head>
<body>
<form method=post action="">
Username: <input type="text" name="f_uname" size=30><br>
Password: <input type=text name="f_pwd" size=30><br>

<input type="submit" name="f_login" value="登錄">
</form>
</body>

在這個(gè)腳本中,當(dāng)用戶輸入正常的用戶名和密碼,假設(shè)值分別為 zhang3、abc123,則提交的 SQL 語(yǔ)句如下:
復(fù)制代碼 代碼如下:
SELECT * FROM tbl_users
WHERE username='zhang3' AND password = 'abc123' LIMIT 0,1

如果攻擊者在 username 字段中輸入:zhang3' OR 1=1 #,在 password 輸入 abc123,則提交的 SQL 語(yǔ)句變成如下:
復(fù)制代碼 代碼如下:
SELECT * FROM tbl_users
WHERE username='zhang3' OR 1=1 #' AND password = 'abc123' LIMIT 0,1

由于 # 是 mysql中的注釋符, #之后的語(yǔ)句不被執(zhí)行,實(shí)現(xiàn)上這行語(yǔ)句就成了:
復(fù)制代碼 代碼如下:
SELECT * FROM tbl_users
WHERE username='zhang3' OR 1=1

  這樣攻擊者就可以繞過(guò)認(rèn)證了。如果攻擊者知道數(shù)據(jù)庫(kù)結(jié)構(gòu),那么它構(gòu)建一個(gè) UNION SELECT,那就更危險(xiǎn)了:

  假設(shè)在 username 中輸入:zhang3 ' OR 1 =1 UNION select cola, colb,cold FROM tbl_b #

  在password 輸入: abc123,

  則提交的 SQL 語(yǔ)句變成:
復(fù)制代碼 代碼如下:
SELECT * FROM tbl_users
WHERE username='zhang3 '

OR 1 =1 UNION select cola, colb,cold FROM tbl_b #' AND password = 'abc123' LIMIT 0,1
  這樣就相當(dāng)危險(xiǎn)了。如果agic_quotes_gpc選項(xiàng)為 on,引號(hào)被轉(zhuǎn)義,則上面攻擊者構(gòu)建的攻擊語(yǔ)句就會(huì)變成這樣,從而無(wú)法達(dá)到其目的:
復(fù)制代碼 代碼如下:
SELECT * FROM tbl_users
WHERE username='zhang3/' OR 1=1 #'
AND password = 'abc123'
LIMIT 0,1

SELECT * FROM tbl_users
WHERE username='zhang3 /' OR 1 =1 UNION select cola, colb,cold FROM tbl_b #'
AND password = 'abc123' LIMIT 0,1

 二. magic_quotes_gpc = On 時(shí)的注入攻擊
  當(dāng) magic_quotes_gpc = On 時(shí),攻擊者無(wú)法對(duì)字符型的字段進(jìn)行 SQL 注入。這并不代表這就安全了。這時(shí),可以通過(guò)數(shù)值型的字段進(jìn)行SQL注入。

  在最新版的 MYSQL 5.x 中,已經(jīng)嚴(yán)格了數(shù)據(jù)類型的輸入,已默認(rèn)關(guān)閉自動(dòng)類型轉(zhuǎn)換。數(shù)值型的字段,不能是引號(hào)標(biāo)記的字符型。也就是說(shuō),假設(shè) uid 是數(shù)值型的,在以前的 mysql 版本中,這樣的語(yǔ)句是合法的:
復(fù)制代碼 代碼如下:
INSERT INTO tbl_user SET uid="1";
SELECT * FROM tbl_user WHERE uid="1";

  在最新的 MYSQL 5.x 中,上面的語(yǔ)句不是合法的,必須寫(xiě)成這樣:
復(fù)制代碼 代碼如下:
INSERT INTO tbl_user SET uid=1;
SELECT * FROM tbl_user WHERE uid=1;

  這樣我認(rèn)為是正確的。因?yàn)樽鳛殚_(kāi)發(fā)者,向數(shù)據(jù)庫(kù)提交正確的符合規(guī)則的數(shù)據(jù)類型,這是最基本的要求。

  那么攻擊者在 magic_quotes_gpc = On 時(shí),他們?cè)趺垂裟兀亢芎?jiǎn)單,就是對(duì)數(shù)值型的字段進(jìn)行 SQL 注入。以下列的 php 腳本為例:
復(fù)制代碼 代碼如下:
<?
if ( isset($_POST["f_login"] ) )
{
// 連接數(shù)據(jù)庫(kù)...
// ...代碼略...

// 檢查用戶是否存在
$t_strUid = $_POST["f_uid"];
$t_strPwd = $_POST["f_pwd"];
$t_strSQL = "SELECT * FROM tbl_users WHERE uid=$t_strUid AND password = '$t_strPwd' LIMIT 0,1";
if ( $t_hRes = mysql_query($t_strSQL) )
{
// 成功查詢之后的處理. 略...
}

}
?>
<html><head><title>sample test</title></head>
<body>
<form method=post action="">
User ID: <input type="text" name="f_uid" size=30><br>

Password: <input type=text name="f_pwd" size=30><br>
<input type="submit" name="f_login" value="登錄">
</form>
</body>


  上面這段腳本要求用戶輸入 userid 和 password 登入。一個(gè)正常的語(yǔ)句,用戶輸入 1001和abc123,提交的 sql 語(yǔ)句如下:

SELECT * FROM tbl_users WHERE userid=1001 AND password = 'abc123' LIMIT 0,1
  如果攻擊者在 userid 處,輸入:1001 OR 1 =1 #,則注入的sql語(yǔ)句如下:

SELECT * FROM tbl_users WHERE userid=1001 OR 1 =1 # AND password = 'abc123' LIMIT 0,1
  攻擊者達(dá)到了目的。

 三. 如何防止 php SQL 注入攻擊
  如何防止 php sql 注入攻擊?我認(rèn)為最重要的一點(diǎn),就是要對(duì)數(shù)據(jù)類型進(jìn)行檢查和轉(zhuǎn)義。總結(jié)的幾點(diǎn)規(guī)則如下:

php.ini 中的 display_errors 選項(xiàng),應(yīng)該設(shè)為 display_errors = off。這樣 php 腳本出錯(cuò)之后,不會(huì)在 web 頁(yè)面輸出錯(cuò)誤,以免讓攻擊者分析出有作的信息。
調(diào)用 mysql_query 等 mysql 函數(shù)時(shí),前面應(yīng)該加上 @,即 @mysql_query(...),這樣 mysql 錯(cuò)誤不會(huì)被輸出。同理以免讓攻擊者分析出有用的信息。另外,有些程序員在做開(kāi)發(fā)時(shí),當(dāng) mysql_query出錯(cuò)時(shí),習(xí)慣輸出錯(cuò)誤以及 sql 語(yǔ)句,例如:
復(fù)制代碼 代碼如下:
$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
// 正確的處理
}
else
{
echo "錯(cuò)誤! SQL 語(yǔ)句:$t_strSQL /r/n錯(cuò)誤信息".mysql_query();
exit;
}

  這種做法是相當(dāng)危險(xiǎn)和愚蠢的。如果一定要這么做,最好在網(wǎng)站的配置文件中,設(shè)一個(gè)全局變量或定義一個(gè)宏,設(shè)一下 debug 標(biāo)志:

全局配置文件中:
復(fù)制代碼 代碼如下:
define("DEBUG_MODE",0); // 1: DEBUG MODE; 0: RELEASE MODE

//調(diào)用腳本中:
$t_strSQL = "SELECT a from b....";
if ( mysql_query($t_strSQL) )
{
// 正確的處理
}
else
{
if (DEBUG_MODE)
echo "錯(cuò)誤! SQL 語(yǔ)句:$t_strSQL /r/n錯(cuò)誤信息".mysql_query();
exit;
}

對(duì)提交的 sql 語(yǔ)句,進(jìn)行轉(zhuǎn)義和類型檢查。
 四. 我寫(xiě)的一個(gè)安全參數(shù)獲取函數(shù)
  為了防止用戶的錯(cuò)誤數(shù)據(jù)和 php + mysql 注入 ,我寫(xiě)了一個(gè)函數(shù) PAPI_GetSafeParam(),用來(lái)獲取安全的參數(shù)值:
復(fù)制代碼 代碼如下:
define("XH_PARAM_INT",0);
define("XH_PARAM_TXT",1);
function PAPI_GetSafeParam($pi_strName, $pi_Def = "", $pi_iType = XH_PARAM_TXT)
{
if ( isset($_GET[$pi_strName]) )
$t_Val = trim($_GET[$pi_strName]);
else if ( isset($_POST[$pi_strName]))
$t_Val = trim($_POST[$pi_strName]);
else
return $pi_Def;

// INT
if ( XH_PARAM_INT == $pi_iType)
{
if (is_numeric($t_Val))
return $t_Val;
else
return $pi_Def;
}

// String
$t_Val = str_replace("&", "&",$t_Val);
$t_Val = str_replace("<", "<",$t_Val);
$t_Val = str_replace(">", ">",$t_Val);
if ( get_magic_quotes_gpc() )
{
$t_Val = str_replace("http:///"", """,$t_Val);
$t_Val = str_replace("http://''", "'",$t_Val);
}
else
{
$t_Val = str_replace("/"", """,$t_Val);
$t_Val = str_replace("'", "'",$t_Val);
}
return $t_Val;
}

  在這個(gè)函數(shù)中,有三個(gè)參數(shù):

$pi_strName: 變量名
$pi_Def: 默認(rèn)值
$pi_iType: 數(shù)據(jù)類型。取值為 XH_PARAM_INT, XH_PARAM_TXT, 分別表示數(shù)值型和文本型。
  如果請(qǐng)求是數(shù)值型,那么調(diào)用 is_numeric() 判斷是否為數(shù)值。如果不是,則返回程序指定的默認(rèn)值。

  簡(jiǎn)單起見(jiàn),對(duì)于文本串,我將用戶輸入的所有危險(xiǎn)字符(包括HTML代碼),全部轉(zhuǎn)義。由于 php 函數(shù) addslashes()存在漏洞,我用 str_replace()直接替換。get_magic_quotes_gpc() 函數(shù)是 php 的函數(shù),用來(lái)判斷 magic_quotes_gpc 選項(xiàng)是否打開(kāi)。


  剛才第二節(jié)的示例,代碼可以這樣調(diào)用:
復(fù)制代碼 代碼如下:
<?
if ( isset($_POST["f_login"] ) )
{
// 連接數(shù)據(jù)庫(kù)...
// ...代碼略...

// 檢查用戶是否存在
$t_strUid = PAPI_GetSafeParam("f_uid", 0, XH_PARAM_INT);
$t_strPwd = PAPI_GetSafeParam("f_pwd", "", XH_PARAM_TXT);
$t_strSQL = "SELECT * FROM tbl_users WHERE uid=$t_strUid AND password = '$t_strPwd' LIMIT 0,1";
if ( $t_hRes = mysql_query($t_strSQL) )
{
// 成功查詢之后的處理. 略...
}
}
?>

  這樣的話,就已經(jīng)相當(dāng)安全了。PAPI_GetSafeParam的代碼有點(diǎn)長(zhǎng),但犧牲這點(diǎn)效率,對(duì)保證安全,是值得的。希望大家多批評(píng)指正。:)

php技術(shù)PHP+SQL 注入攻擊的技術(shù)實(shí)現(xiàn)以及預(yù)防辦法,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 免费观看很黄很色的大片 | 国产精自产拍久久久久久 | 国产一区三区二区中文在线 | 微拍秒拍99福利精品小视频 | 久草色播 | 欧美黄色片在线观看 | 深夜啪啪网站 | 黄色高清在线观看 | 真人午夜a一级毛片 | 色综合视频在线 | 亚洲精品国产综合久久一线 | 在线亚洲欧美性天天影院 | 一区在线视频 | 久久精品这里热有精品2015 | 精品国产自在现线久久 | 伊人网久久网 | 亚洲精品在线第一页 | 国产精品久久久久无毒 | 国产精选第一页 | 一级毛片特黄久久免费看 | 在线色 | 国产麻豆久久 | 很黄很暴力深夜爽爽无遮挡 | 欧美人与zoxxxx另类9 | 五月开心激情网 | 色呦呦免费视频 | 中文字幕一区二区三区乱码 | 日韩成人免费在线 | 精品国产日韩久久亚洲 | 国产播放器一区 | 久久亚洲国产成人亚 | 综合伊人久久 | 极品吹潮视频大喷潮tv | 亚洲综合精品香蕉久久网 | 视频黄在线观看 | 一区二区影视 | 九色综合伊人久久富二代 | 韩国美女爽快一级毛片黄 | 51国产偷自视频区视频手机播器 | 五月亭亭免费高清在线 | 麻豆一区 |