XSS基礎學習
By:Mirror王宇陽
什麼是XSS
XSS攻擊是指在網頁中嵌入一段惡意的用戶端Js腳本代碼片段,JS腳本惡意代碼可以擷取使用者的Cookie、URL跳轉、内容篡改、會話劫持……等。
xss攻擊手段本身對服務端沒有直接的危害,xss主要是借助網站傳播;一般通過留言闆、郵件、等其他途徑向受害者發送一段惡意的URL,受害者通過通路該惡意URL可能會導緻惡意的xss腳步會在受害者的用戶端浏覽器中執行,實作自己的目的
XSS的攻擊類别分為:反射型、存儲型、DOM型等三大類攻擊類别。
反射型XSS
反射型XSS會把使用者輸入的資料直接傳回給頁面,是一種非持久型攻擊;這類型的xss是最為常見的,主要的利用方法就是惡意腳本添加到參數(URL)發送給使用者誘騙使用者點選後反射資料給頁面。
- 頁面源碼
XSS | 反射型 xss反射型注入攻擊測試 測試語句:
- 背景源碼
Text page | Return 反射型測試頁面
-
源碼分析
我們輸入的内容會被執行并嵌入在HTML頁面中;$_GET['name']會觸發js惡意代碼并嵌入HTML頁面中。
- 測試
XSS基礎學習 - XSS測試
XSS基礎學習 - 結果發現:我們在輸入text框中寫入了一個Js代碼,代碼直接被執行并嵌入在HTML頁面中;衆所周知,Js代碼和HTML代碼直接暴露在用戶端,一旦寫入的Js代碼可以被執行并嵌入在HTML頁面中即視為存在XSS攻擊。
- 正常頁面
- XSS測試
-
惡意利用
我們通過向受害者發送如下的惡意URL就可以實作在使用者用戶端執行該惡意js腳本;
攻擊者還會将URL進行各式各樣的加密轉換的處理,最大程度的減少URL惡意腳本的暴露;http://127.0.0.1/xss/xss.php?name=
存儲型XSS
存儲型XSS是一種持久的xss攻擊類别,攻擊者将惡意腳本植入到服務端資料庫或長期的嵌入在HTML頁面中;當使用者符合觸發條件後就會觸發Js的xss惡意腳本。
存儲型的xss通常會存儲在用戶端或資料庫中,當使用者通路頁面即觸發xss。
存儲型的xss不需要構造URL誘騙使用者去點選,大大的減少暴露和增加隐秘性。
- 建立資料庫和表
create table text( uid int(10) not null auto_increment primary key, title varchar(20) null, content text(100) null )engine=innodb default charset=utf8;
- HTML頁面源碼
xss | 存儲型 xss|存儲型測試 留言闆測試 主題: 留言:
XSS基礎學習 - PHP背景源碼
xss | 存儲型
-
分析
當使用者在content寫入一個可執行惡意js腳本的标簽即可過程xss例如:,送出查詢後内容就會寫入在資料庫中,在資料庫的查詢結果回顯至頁面後就可以觸發了,這裡舉兩個例子,一個是手動觸發,一個是自動加載觸發。
- 這是寫入一個input标簽,滑鼠點選事件可執行一個js腳本即一個彈窗。
XSS基礎學習 XSS基礎學習 這裡是寫入了一個img标簽但是标簽src無索引會錯誤error,由此觸發onerror屬性執行js;也可以使用其他類似于onload屬性……XSS基礎學習 XSS基礎學習 測試過程中發現單引号無法存入資料庫,原因本小白也是半懂不懂;在sql執行的寫入的時候單引号會被轉義,對此可以嘗試雙單引号來實作最後也會以單引号的語句儲存在表中。XSS基礎學習 XSS基礎學習
DOM型xss
基于DOM的XSS攻擊手段,效果上和反射型XSS類似;通過修改頁面的DOM節點形成XSS。
DOM規定:
- 一個文檔就是一個文檔節點
- 每個HTML标簽就是一個元素節點
- 包含在HTML元素中的文本是文本節點
- 每一個HTML屬性是一個屬性節點
- 節點與節點之間都有等級關系
- 測試源碼
xss | DOMXSS - DOM攻擊測試頁面超連結"; }" _ue_custom_node_="true">測試區域xss測試:
- 當我們想id=xss送出資料後,送出的内容則會作為a标簽的href屬性被寫入在HTML頁面中;而攻擊者則采用閉合拼接的方式來構成惡意的xss
-
XSS基礎學習 XSS基礎學習 - 構造惡意的閉合xss
這樣的xss構造語句會向測試區域發送惡意的構造标簽實作攻擊目的超連結xss 送出: " onclick=alert("Hello,World!")
XSS基礎學習 XSS基礎學習
- 構造惡意的閉合xss
XSS常見測試語句
XSS繞過思路
- Js編碼
JS提供了四種字元編碼的政策
- 三個八進制數字,空位補0,\***
- 兩個十六進制數,空位補0,\x**
- 四個十六進制數,空位補0,\u****
- 控制字元,例如 \r , \h , \t
- HTML實體編碼
命名實體:命名以 “&” 開頭,分号結尾;參考:實體編碼字元
字元編碼:十進制、十六進制ASCII編碼或Unicode字元編碼
- URL編碼
線上工具:http://tool.chinaz.com/tools/urlencode.aspx
線下工具:URL編碼解碼工具(Burp-Decoder)
XSS檢測
使用手動檢測可以最大精确化,但是對于大型的web應用是困難的是;最首要的重要就是哪裡有輸入、輸入的結果輸出的地方。
手工檢測XSS要使用特殊意義的字元,這樣可以快速的測試是否存在XSS;
-
可得知輸出位置
輸入一些敏感字元,例如: > < " ' ( )等,遵照自送出後檢視HTML源代碼,檢視自己輸入的字元是否被轉義;
-
無法得知輸出位置
大多的web應用時非開源的,測試XSS的時候無法得知具體的輸出位置顯示;例如:我們的評論送出後會交由背景進行内容敏感檢查,我們就無法得知具體的輸出位置了;
上述是一個表單,我們可以使用/> xxx測試該标簽的具體輸出位置
xss利用方式
Cookie竊取
Cookie時能夠讓網站伺服器吧少量的文本資料存儲到用戶端的硬碟或記憶體中,用于維持HTTP無狀态協定導緻的可持續網站會話;
-
如何産生:
當我們通路某網站,網站服務端由于HTTP時無狀态協定,而用戶端和伺服器無法直接判斷是否來自同一個客戶源,為此當使用者通路第一次網站後并登入等操作,服務端會傳回Cookie給用戶端的硬碟或記憶體中存留
-
如何使用:
當使用者第二次通路服務端的時候,服務端就會檢查用戶端中是否有Cookie檔案,如果有Cookie則會利用該檔案登入并通路網站
-
Cookie格式:
每一個浏覽器儲存的Cookie的檔案位置均不同,這裡以Firefox浏覽器為例,我們通路DVWA平台并登入,儲存使用者和密碼形成Cookie
Cookie主要由變量名key和值value組成:XSS基礎學習 Set-Cookie:=[;=][;expires=][;domain=][;path=][;secure][;HttpOnly]
Set-Cookie HTTP伺服器的響應頭,Web伺服器通過此頭講Cookie發給用戶端
name=value Cookie必有部分,使用者通過name取得Cookie的對應的Value值
expires= 規定了Cookie的有效終止日期;預設該字段則cookie不會存儲在硬碟中
domain= 規定了哪些Internet域中的Web伺服器可以讀取用戶端的Cookie檔案,如果預設則Web伺服器的域名為Value;
path= 定義Web伺服器上哪些路徑下的頁面可以擷取伺服器發送的Cookie檔案;Value為/表示Web伺服器中所有頁面都可以擷取Cookie檔案;如果預設,Path的Value則是Web伺服器向用戶端發送Cookie的URL;
Secure Cookie中标明變量,隻有當web伺服器和用戶端之間采用HTTPS加密認證協定才可以進行連接配接通信送出Cookie檔案
HttpOnly 禁止JavaScript讀取
Cookie中的内容經過加密處理,隻有Web伺服器的Cookie處理程式可以解析Cookie真正的意義
- 利用xss擷取cookie
-
建立一個cookie
setcookie() 函數向用戶端發送一個 HTTP cookie。參考文章
setcookie(name,value,expire,path,domain,secure) # 參數定義 name 必需。規定 cookie 的名稱。 value 必需。規定 cookie 的值。 expire 可選。規定 cookie 的有效期。 若是删除一個cookie則可以設定時間為過去時 path 可選。規定 cookie 的伺服器路徑。 domain 可選。規定 cookie 的域名。 secure 可選。規定是否通過安全的 HTTPS 連接配接來傳輸 cookie。 注釋:可以通過 $HTTP_COOKIE_VARS["user"] 或 $_COOKIE["user"] 來通路名為 "user" 的 cookie 的值。 注釋:在發送 cookie 時,cookie 的值會自動進行 URL 編碼。接收時會進行 URL 解碼。如果你不需要這樣,可以使用 setrawcookie() 代替。
- 頁面添加設定COOKIE
XSS | 反射型 xss反射型注入攻擊測試 測試語句:
- xss擷取Cookie
XSS基礎學習 - 惡意構造URL
若是使用者通路了這個URL則會直接暴露自己的COOKIE,一旦暴露,攻擊者可以僞造COOKIE通路。http://127.0.0.1/xss/xss.php?name=
-
COOKIE安全
正是因為Cookie存在用戶端且可以容易被僞造,是以最初的預防辦法就是高度加密;使用者擷取Cookie資訊後僞造Cookie登入即可操作該賬号。對于高度加密的COOKIE攻擊者至于要原樣僞造一個即可,因為解密的大多是在服務端解密Cookie的;Cookie被竊取後就會導緻Cookie僞造會話/Cookie欺騙嚴重的安全漏洞。
-
正常防禦XSS
字元過濾
-
輸入過濾
永遠不要相信使用者的輸入;一般情況在用戶端要設定字元驗證過濾敏感的字元、限制長度、要求格式……等。當然用戶端的内容使用者都是可控的,單單依靠用戶端是不可靠的,通過Burp等工具,可以輕易的修改資料包,繞過 用戶端的過濾檢查。
-
輸出轉碼
千萬不要把使用者的輸入内容完整的回顯至HTML頁面中!一般使用HTMLEncode進行編碼處理。
htmlspecialchars()函數可以将部分特殊字元轉出HTML實體編碼。
輸出的轉碼可以預防xss腳本直接回顯執行XSS基礎學習 -
黑名單
使用黑名單和白名單對輸入的内容進行正則比對,不符合的則不執行并取消。開發人員将敏感的關鍵詞 、特殊字元進行黑名單設定,将一些符合條件的字元、關鍵詞納入白名單。
- 前端過濾函數
function xss_clean($data){ // Fix &entity\n; $data=str_replace(array('&',''),array('&','<','>'),$data); $data=preg_replace('/(&#*\w+)[\x00-\x20]+;/u','$1;',$data); $data=preg_replace('/(&#x*[0-9A-F]+);*/iu','$1;',$data); $data=html_entity_decode($data,ENT_COMPAT,'UTF-8'); // Remove any attribute starting with "on" or xmlns $data=preg_replace('#(]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu','$1>',$data); // Remove javascript: and vbscript: protocols $data=preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2nojavascript...',$data); $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu','$1=$2novbscript...',$data); $data=preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u','$1=$2nomozbinding...',$data); // Only works in IE: $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i','$1>',$data); $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i','$1>',$data); $data=preg_replace('#(]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu','$1>',$data); // Remove namespaced elements (we do not need them) $data=preg_replace('#]*+>#i','',$data); do{// Remove really unwanted tags $old_data=$data; $data=preg_replace('#]*+>#i','',$data); }while($old_data!==$data); // we are done... return $data; }
- 後端過濾
$value) { if (!is_array($value)) { if (!get_magic_quotes_gpc())//不對magic_quotes_gpc轉義過的字元使用addslashes(),避免雙重轉義。 { $value = addslashes($value); //給單引号(')、雙引号(")、反斜線(\)與NUL(NULL字元)加上反斜線轉義 } $value = preg_replace($ra,'',$value); //删除非列印字元,粗暴式過濾xss可疑字元串 $arr[$key] = htmlentities(strip_tags($value)); //去除 HTML 和 PHP 标記并轉換為HTML實體 } else { SafeFilter($arr[$key]); } } } } ?>
HttpOnly Cookie
防止xss竊取Cookie可以使用HttpOnlyCookie;
當一個Cookie在Set-cookie消息頭中被标明為HttpOnly時,用戶端的js是不可以直接通路該cookie的。
- PHP設定HttpOnly
- 修改php.ini檔案,設定session.cookie_httponly =1
-
setcookie('','','','','','',TRUE); setrawcookie('','','','','','',TRUE);