XSS與字符編碼的那些事兒

目錄

0x00:基本介紹
0x01:html實體編碼
0x02:新增的實體編碼 實體編碼變異以及瀏覽器的某些工作原理!
0x03:javascript編碼
0x04:base64編碼
0x05:閑扯

?

0x00基本介紹

提起XSS 想到的就是插入字符字符編碼與各種解析了!

這也就是各種xss編碼插件跟工具出世的原因!之前不懂瀏覽器是如何對我們編碼過的代碼進行解析的時候就是一頓亂插!

各種編碼 各種插 沒把編碼還原就算了 還原了就算運氣好!后來到PKAV經過二哥和短短的調教后才算是弄清楚了一點編碼與解析方面的知識!

現在也算是運用自如了把!

現在介紹一下在xss中最經常用到的編碼

html實體編碼(10進制與16進制):

如把尖括號編碼[ < ]??-----> html十進制: &#60;??html十六進制:&#x3c;

javascript的八進制跟十六進制:

如把尖括號編碼[ < ]??-----> js八進制:\74??js十六進制:\x3c

jsunicode編碼:

如把尖括號編碼[ < ]??----->jsunicode:\u003c

url編碼 base64編碼:

如把尖括號編碼[ < ]??-----> url: %22??base64: Ig==

0x01 html實體編碼

html實體編碼本身存在的意義是防止與HTML本身語義標記的沖突。

但是在XSS中卻成為了我們的一大利器,但是也不能盲目的使用!

html中正常情況只識別:html10進制,html16進制!

現在介紹一下我們應該如何在xss過程中靈活的使用各種編碼呢?

比如現在你的輸出點在這:

<img src="[代碼]">

在這里過濾了script??< > / \ http: 以及各種危險字符 比如創建一個html節點什么的!

有的站只允許你引用一個img文件夾里的圖片 但是圖片是你可以控的 可以通過抓包來修改的!

我們如果想加載外部js 或者一個xss平臺的鉤子我們應該怎么寫呢?

那么我們可以在這里 閉合雙引號 寫事件: οnerrοr=[html language="實體編碼"][/html][/html]

比如我現在彈個窗:

<img src="x" onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">

原code:

<img src="x" onerror="alert(1)">

這里我用的是html十進制編碼 也可以使用十六進制的html實體編碼!

但是為什么這里我沒有用jsunicode 以及 js八進制跟js十六進制呢!

瀏覽器是不會在html標簽里解析js中的那些編碼的!所以我們在οnerrοr=后面放js中的編碼是不會解析 你放進去是什么 解析就是什么!

大多數網站是不會&#號的,如果過濾了怎么辦呢?

那么再來講一下另外一個案例:

enter image description here

源碼如下:  enter image description here

頁面中的Go按鈕中包含一個a標簽 輸入的值會存在于a標簽的href屬性中,href中用了javascript偽協議,可以在href跳轉時執行js代碼!

所以造成了xss!

我們提交的值如下:

wooyun%26%23x27,alert(1)%2b%26%23x27

由于頁面對單引號 & 符號 以及 #符號過濾!但是html中可以識別html實體編碼!但是實體編碼是由&#組成!

這個時候&#已經被過濾 我們只能通過url編碼來對 & # 兩個符號進行編碼!再讓瀏覽器解碼成 &# 然后拼接x27 最后就成為了單引號的html16進制編碼!

解碼后:我們的提交值為:

',alert(1)'

href代碼為:

?
1
<a href="javascript:location='./3.3.php?offset='+document.getElementById('pagenum').value+'&searchtype_yjbg=yjjg&searchvalue_yjbg='">GO</a>

ps:在之前說了html標簽中識別html實體編碼,并且會在html頁面加載時會對編碼進行解碼!那么&#x27 已經是單引號了 但是并不會閉合! 然后在點擊過程中執行javascript代碼 這個時候由于html里&#x27被解析成單引號但是沒閉合 這個時候js被執行 這個我們提交的在html加載時解析成了字符串單引號但是不能閉合之前的引號 因為現在是把我們提交的編碼了的單引號 當成字符串來顯示 但是現在他是存在于a標簽中的href里的 href鏈接里的地址是javascript偽協議,我們現在點擊的時候 會執行里面的代碼 關鍵來了 這個時候我們之前被當做字符串的單引號 被再次解析 這個時候就沒任何過濾規則來過濾它 程序也沒那么智能 之前當做字符串的單引號起作用了 javascript不知道他是個字符串 它只知道瀏覽器解析成了什么 他就帶入進去!就在這個時候我們的字符串單引號就成功的閉合了!當點擊go時 我們的代碼執行!

上面這個例子講了html編碼 以及特殊情況下的編碼那么再講下當你的輸入點存在于script標簽中的時候!我們就應該用js中的編碼了!

既然知道是如何解析的了 那么便又有了以下新的想法!

0x02 新增的實體編碼,變異以及瀏覽器的某些工作原理

通常程序做 XSS 防御的時候會考慮到一些 HTML 編碼的問題,會攔截或轉義 " \ 這樣的東西 那么我的雙引號跟尖括號就被攔截了!

但基礎這種黑名單方式可能出現的問題:

1. 不認識 HTML5 新增的實體命名編碼,如

?
1
2
3
4
5
6
&colon; => [冒號]
&NewLine; => [換行]
??
??
??
case: <a href="javasc&NewLine;ript&colon;alert(1)">click</a>

2.對 HTML 編碼的解析規則不夠熟悉,就像十進制和十六進制編碼的分號是可以去掉的。

還有,數字編碼前面加「0」,這也是一條很好的繞過 WAF 的向量。

如下圖(我去掉了后面的分號 另外在每個數字前加了一個零):  enter image description here

數字前面是可以加多個0的 閑的蛋疼的基友可以自己試下!

<a href="javasc&NewLine;ript&colon;alert(1)">click</a> 

這句代碼能夠執行么?

不知道那些不是很清楚瀏覽器工作原理的基友,在最開始有沒有懷疑這段代碼能不能執行!

起碼我最開始 懷疑過!即使編碼被解析回來了 換行了還能執行么!

當時就去問了我的好基友 XX大神[一位跟短短一樣擁有著跟常用不一樣的思維 在我們看來是很不同于正常人的人]

然后大神給了我一份比較詳細的瀏覽器工作原理 很長很長!

我就把最主要的copy下來貼上吧!

解析器-詞法分析器 Parser-Lexer combination

解析可以分為兩個子過程——語法分析及詞法分析

詞法分析就是將輸入分解為符號,符號是語言的詞匯表——基本有效單元的集合。對于人類語言來說,它相當于我們字典中出現的所有單詞。

語法分析指對語言應用語法規則。

解析器一般將工作分配給兩個組件——詞法分析器(有時也叫分詞器)負責將輸入分解為合法的符號,解析器則根據語言的語法規則分析文檔結構,從而構建解析樹,詞法分析器知道怎么跳過空白和換行之類的無關字符。

然后我的理解是這樣的:

<a href="javasc&NewLine;ript&colon;alert(1)">click</a>

首先html編碼被還原出來 然后就成了換行 跟冒號

<a href="javasc
ript:alert(1)">click</a>??

為什么換行后還能夠執行 是因為瀏覽器中的解析器中詞法分析器 起的作用會跳過空白跟換行之類的無效字符。

然后就構造成了一個完整的語句

<a href="javascript:alert(1)">click</a> 

代碼執行!

看完那些之后瞬間心里覺得原來跟原理性相關的東西真的很重要!能夠讓你寫 xss payload更加靈活!

0x03 javascript編碼

javascript中只識別幾種編碼:Jsunicode js8進制 js10進制

就拿下面這個例子來講吧!

第一種情況 你輸入的值存入某個變量 然后最后出現在某個能把字符串當做js代碼來執行的函數里!

如:

eval()??setTimeout()?? setInterval()

以上都是會將字符串當做js代碼執行的函數! 如果是以下情況:

var search = "可控點";
document.getElementById().innerHTML=search;

以上情況很多都是出現在你搜索后 然后顯示的 你所查詢的關鍵字

如果過濾了 <> ' " & % 等等這些!然后再輸出到頁面上!

按理說這樣是安全了!但是我們把輸入的值改成 jsunicode 編碼

如 我們改成 <img src=x onerror=alert(1)> 然后進行js八進制編碼  然后服務器端接受后 經過過濾器 沒有發現該過濾的就進入到了innerHTML中

現在我們來看看 輸出是什么效果!

我就用chrome console來演示吧!  enter image description here

看到了把 經過js的解碼 我們的代碼又還原回來了 并且注入到了網頁中!這時候代碼執行!成功彈窗!

在js中是可以用jsunicode js16進制 js8進制的!

為什么這里不用16進制 跟unicode編碼!是因為 八進制的相對而言最短!

在xss中字符數的長短 也是一個很重要的問題!越短越好!

在asp的站中插XSS代碼的時候,存儲型 會因為你數據庫中字段的長度不夠

而存不進去 然后報錯!這種情況經常發生!所有養成用最少的字符 來達到你的目的 是最好的!

既然提到了js中的十六進制編碼 跟js中的unicode編碼 那么也上兩張圖吧!

十六進制在js中是\x[16hex] 來表示的 如:<??\x3center image description here

大家看到跟八進制的用法也是一樣的!只不過多了一個字符X 雖然我很喜歡這個字符 但是我更喜歡八進制的短小精悍!

下面再說說jsunicode編碼:

他的表示方式是這樣的:\uxxxx \uxxx < 轉碼后: /u003c

上圖:  enter image description here

0x04 base64編碼

到目前為止 我遇到使用base64編碼的情況 大多數是這樣!

<a href="可控點">
<iframe src="可控點">

在這種情況下 如果過濾了<> ' " javascript 的話 那么要xss可以這樣寫 然后利用base64編碼!

<a href="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a>

這樣當test A鏈接點擊時 就會以data協議 頁面以html/text的方式解析 編碼為base64 然后單點擊a鏈接時 base64的編碼就被還原成我們原本的

<img src=x onerror=alert(1)>

然后成功彈窗!

如下圖:

enter image description here  在iframe里也同樣可以使用!大家自己測試把!

0x05 閑扯

web前端的世界真的太難讓人捉摸透!

其實好多阻擋在面前的就是那些原理性的東西!懂了就好了!

看著二哥挖掘反射型xss 讓我感覺很像js代碼審計!

用二哥的話來說,首先你js的功底得比寫js的人功力要高 然后你就比較容易挖掘到xss!所以我感覺js比xss來說相當重要!二哥一直寫了六七年的js 才練就今天的功力!所以我特別堅信這句話!

一般測試xss首先我會先測試一些反射型!提交幾個非法字符 然后看過濾成什么了!然后再打開chrome console 然后再追蹤當前網頁中 以及網頁所引用文件中的一些關鍵字!比如這個輸入框的id =xxxx 然后我就一直追蹤下去!如果某個數組 或者變量 的值把它傳入進去了 然后就一直追蹤下去 一直找到源頭!把代碼都看一邊 如果能繞過的話 自己在chrome稍稍調試下就能挖掘出來了!

當然這種方法也是二哥教!二哥跟短短一直都是我膜拜的對象!短短跟我講了講 瀏覽器的解析,二哥講了 dom的渲染 js的解析以及等等 說不完的一些技巧!

頓時趕腳 挖掘XSS是那么的容易!

附 XSS Encode插件打包:http://www.2cto.com/uploadfile/2013/1022/20131022111710439.zip

END

轉載于:https://www.cnblogs.com/milantgh/p/3789343.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處:https://dhexx.cn/hk/18442.html

如若內容造成侵權/違法違規/事實不符,請聯系我的編程經驗分享網進行投訴反饋,一經查實,立即刪除!


相關文章:

  • SpringBoot整合EasyExcel+MyBatis-Plus實現Excel批量導入和導出
  • SAP修改前臺屏幕字段文本
  • spark常用RDD算子 - foldByKey
  • SpringBoot整合Shiro+Redis框架權限管理
  • 【Lucene4.8教程之二】索引
  • 自制AutoMapper實現DTO到持久層Entity的轉換
  • spark常用RDD算子 - SortByKey
  • Nginx安裝及使用
  • 成功路很多,選對放心日賺幾百不是問題
  • spark常用RDD算子 - groupByKey
  • SpringBoot整合RabbitMQ消息中間件及多種設計模式
  • LCHub:ChatGPT4和低代碼來臨,程序員面臨下崗?
  • 運行Applet程序
  • Ubuntu12.04編譯Android4.0.1源碼全過程-----附wubi安裝ubuntu編譯android源碼硬盤空間不夠的問題解決...
  • Redis+SpringBoot整合
  • spark常用RDD算子 - cogroup
  • c# Xml反序列化示例
  • 《大話數據結構》圖的BFS和DFS
  • spark常用RDD算子 - 鍵值對關聯操作 subtractByKey, join,fullOuterJoin, rightOuterJoin, leftOuterJoin
  • 樹莓派_Linux串口編程_實現自發自收
  • 3.3FactoryMethod——工廠方法
  • Springboot筆記
  • spark常用RDD算子 - PairRDD的Action操作countByKey, collectAsMap
  • Spring與Hibernate、Mybatis整合
  • 學習ASP.NET MVC(五)——我的第一個ASP.NET MVC CURD頁面
  • SpringCloud學習之路
  • Spark Rdd分區 coalesce()方法和repartition()方法
  • 存儲引擎-存儲結構之二:頁
  • 配置開發支持高并發TCP連接的Linux應用程序全攻略
  • Spark RDD中的寬依賴和窄依賴
  • 學習java虛擬機
  • javascript 設置元素樣式 函數
  • 解決問題
  • Spark RDD Partitioner 分區機制解析
  • MySQL學習日記
  • 【不積跬步,無以致千里】關閉631端口cups打印服務和8009端口ajp
  • 阿里云服務器上安裝mysql的心路歷程(博友們進來看看哦)
  • Spark RDD分區 分區劃分器
  • SpringBoot發送郵件定時任務
  • 4.調個綠豆沙護眼色
  • MAC電腦之搭建lua開發環境
  • Spark RDD 緩存,持久化 cache(),persist()
  • 深入學習存儲過程
  • 指針的疑問
  • Scala 中的函數式編程基礎(二)
  • Git分支命令與項目實踐
  • Spark RDD checkpoint()機制
  • inline、block、inline-block的區別
  • PHP 提高PHP性能的編碼技巧以及性能優化
  • 瀏覽器的工作原理:新式網絡瀏覽器幕后揭秘