了解CTF的朋友們缴淋,肯定對一種題型不陌生——Misc准给,Misc里面有各種各樣的編碼,眼花繚亂的文本通過層層解碼后得到一個令人滿意的結果是一件及其感人的事件重抖。
其實除了解題露氮,這些編碼本身在計算機領域也有重要的應用。所以當我們在CTF里看到一種新的編碼時钟沛,不要簡單丟到解碼器里得出結果就認為萬事大吉了畔规,了解它——“知其然”和“所以然”,這才能在CTF里學到更多的東西恨统。
01 字符編碼的歷史
一叁扫、誕生——ASCII碼
我們都知道計算機只能處理數字三妈,所以如果你要處理文本,就必須把文本轉換為數字莫绣。最早的計算機在設計之初畴蒲,采用8個比特(bit)作為一個字節(jié)(byte),所以一個字節(jié)最大能表示的整數就是255
对室,如果要表示更大等整數模燥,就必須用更多的字節(jié)。
由于計算機是美國人發(fā)明的掩宜,因此蔫骂,最早只有127
個字符被編碼到計算機里,也就是大小寫英文字母牺汤、數字和一些符號纠吴,這個編碼表被稱為ASCII編碼,比如大寫字母A
的編碼是65
慧瘤,小寫字母z
的編碼是122
。
ASCII 碼使用指定的7 位或8 位二進制數組合來表示128
或256
種可能的字符固该。標準ASCII 碼也叫基礎ASCII碼锅减,使用7 位二進制數(剩下的1位二進制為0)來表示所有的大寫和小寫字母,數字0 到9伐坏、標點符號怔匣, 以及在美式英語中使用的特殊控制字符。
二桦沉、戰(zhàn)國春秋——世界人民的各種編碼
但是要處理中文顯然一個字節(jié)是不夠的每瞒,至少需要兩個字節(jié),而且還不能和ASCII編碼沖突纯露,所以剿骨,中國制定了GB2312編碼,用來把中文編進去埠褪。
你可以想得到的是浓利,全世界有上百種語言,日本把日文編到Shift_JIS里钞速,韓國把韓文編到Euc-kr里贷掖,各國有各國的標準,就會不可避免地出現沖突渴语,結果就是搏存,在多語言混合的文本中义郑,顯示出來會有亂碼。
三饶囚、秦王掃六合——為統(tǒng)一而生的Unicode
為了解決亂碼,人們決定把所有語言都統(tǒng)一到一套編碼里热康。于是,Unicode應運而生。
Unicode標準也在不斷發(fā)展汇在,但最常用的是用兩個字節(jié)表示一個字符(如果要用到非常偏僻的字符,就需要4個字節(jié))≡啻穑現代操作系統(tǒng)和大多數編程語言都直接支持Unicode糕殉。
現在,我們不妨將ASCII碼和Unicode碼進行一個比較:
ASCII碼是一個字節(jié)殖告,Unicode碼是兩個字節(jié)
字符 | ASCII | Unicode |
---|---|---|
A | 01000001 | 00000000 01000001 |
中 | X | 01001110 00101101 |
因為漢字中
已經超出ASCII碼的范圍阿蝶,所以無法表示。
由上表可知黄绩,如果把ASCII編碼的A
用Unicode編碼羡洁,只需要在前面補0就可以,因此爽丹,A
的Unicode編碼是00000000 01000001
筑煮。
四、更上一層樓——UTF-8
如果統(tǒng)一成Unicode編碼粤蝎,亂碼問題從此消失了真仲。但是,如果你寫的文本基本上全部是英文的話初澎,用Unicode編碼比ASCII編碼需要多一倍的存儲空間秸应,在存儲和傳輸上就十分不劃算。
所以碑宴,本著節(jié)約的精神软啼,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8
編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節(jié)延柠,常用的英文字母被編碼成1個字節(jié)祸挪,漢字通常是3個字節(jié),只有很生僻的字符才會被編碼成4-6個字節(jié)贞间。如果你要傳輸的文本包含大量英文字符匕积,用UTF-8編碼就能節(jié)省空間:
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 01000001 | 01000001 |
中 | X | 01001110 00101101 | 11100100 10111000 10101101 |
五、計算機里的實際表現
搞清楚了ASCII榜跌、Unicode和UTF-8的關系闪唆,我們就可以總結一下現在計算機系統(tǒng)通用的字符編碼工作方式:
在計算機內存中,統(tǒng)一使用Unicode編碼钓葫,當需要保存到硬盤或者需要傳輸的時候悄蕾,就轉換為UTF-8編碼。
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換為Unicode字符到內存里帆调,編輯完成后奠骄,保存的時候再把Unicode轉換為UTF-8保存到文件:所以你看到很多網頁的源碼上會有類似<meta charset="UTF-8" />
的信息番刊,表示該網頁正是用的UTF-8編碼含鳞。
六、總結
以上內容主要源自阮老師的博文《字符串和編碼》
簡單了解了字符編碼的歷史后芹务,要想在比賽中多得一些分蝉绷,我們還要判斷給定的文本采用的是哪種編碼方式。
ASCII
源文本:I love you 1314
編碼后:73 32 108 111 118 101 32 121 111 117 32 49 51 49 52
對應可以轉換成二進制枣抱,八進制熔吗,十六進制等
Unicode
源文本:love
&#x [Hex]:love
&# [Decimal]:love
\U [Hex]:\U006C\U006F\U0076\U0065
\U+ [Hex]:\U+006C\U+006F\U+0076\U+0065
Unicode在線編解碼
UTF-8
對于英文字符來說UTF-8與ASCII的編碼結果無異
源文本:愛
編碼后:爱
此外,UTF-8
佳晶、UTF-16
桅狠、UTF-32
都是針對Unicode的再一次編碼,(Unicode Transformation Formats轿秧, 或UTF中跌,即Unicode格式轉換的縮寫)
02 深不見底的編碼
有了上面的基礎,接下來我們探究點更深入的問題菇篡。
字符編碼:“o(>﹏<)o不要啊”
字符或者說信息晒他,在進行編碼后除了存儲在硬盤里,還要進行傳輸以便人們可以進行信息交流逸贾。
而在進行數據傳輸時,為了滿足傳輸環(huán)境的限制或者對數據進行壓縮節(jié)省資源津滞,我們還要再次對字符進行編碼铝侵。但是為了更好理解這一內容,我們需要回到原點触徐,看看究竟什么是編碼咪鲜。
一、現代編碼模型
基本概念
現代編碼模型自底向上分為五個層次:
層次 | 名稱 |
---|---|
1.練氣 | 抽象字符表(Abstract Character Repertoire) |
2.筑基 | 編碼字符集(Coded Character Set) |
3.金丹 | 字符編碼表(Character Encoding Form) |
4.元嬰 | 字符編碼方案(Character Encoding Schema) |
5.化神 | 傳輸編碼語法(Transfer Encoding Syntax) |
練氣:抽象字符表(ACR)
抽象字符表是現代編碼模型的最底層撞鹉,它是一個集合疟丙,通過枚舉指明了所屬的所有抽象字符。但是要了解抽象字符集是什么鸟雏,我們首先需要了解什么是字符與抽象字符
字符
字符是指字母享郊、數字、標點孝鹊、表意文字(如漢字)炊琉、符號。 例: a
,啊
,あ
,α
等,都是抽象的字符苔咪。
抽象字符
抽象字符就是抽象的字符锰悼。像a
這樣的字符是有形的,但在計算機中团赏,有許多的字符是空白的箕般,甚至是不可打印的。比如ASCII字符集中的NULL舔清,就是一個抽象字符丝里。
抽象字符表
抽象字符表顧名思義,指的是抽象字符的集合鸠踪。 已經有了很多標準的字符集定義丙者。 比如US-ASCII, UCS(Unicode), GBK。
需要注意一點的是营密,字符集也是有開放與封閉的區(qū)分的械媒。 ASCII抽象字符集定義了128個抽象字符,再也不會增加评汰,這就是一個封閉字符集纷捞。 Unicode嘗試收納所有的字符,一直在不斷地擴張之中被去。
筑基:編碼字符集(CCS)
編碼字符集是一個每個所屬字符都分配了碼位的字符集主儡。 編碼字符集也經常簡單叫做字符集。
抽象字符集(Character set)是抽象字符的集合惨缆,而集合是無序的糜值。 無序的抽象字符集并沒有什么卵用,因為我們只能判斷某個字符是否屬于某個字符集坯墨,卻無法方便地引用寂汇,指稱這個集合中的某個特定元素。
所以為了更好的描述捣染,操作字符骄瓣,我們可以為抽象字符集中的每個字符關聯(lián)一個數字編號,這個數字編號稱之為碼位(Code Point)耍攘。
舉個栗子榕栏,為amber抽象字符集進行編碼,就可以得到amber編碼字符集蕾各。
amber={'a':0x0, '啊':0x1, '①':0x2, 'α':0x3}
在這里a
不再是一個簡單的抽象字符了扒磁,而是一個編碼字符(Coded Chacter),且擁有碼位(Code Point) 0x0
式曲。
金丹:字符編碼表(CEF)
在講抽象字符表ACR的時候曾經提起渗磅,Unicode是一個開放字符集,未來可能有更多的符號加入到這個字符集中來。也就是說UCS需要的碼位始鱼,理論上是無限的仔掸。 但是計算機的整形能表示的整數范圍是有限的。譬如医清,一個字節(jié)的無符號整形(unsigned char, uint8)能夠表示的碼位只有0~0xFF起暮,共256個;而一個無符號短整形(unsigned short, uint16)的可用碼位只有0~0xFFFF会烙,共65536個负懦;一個整形(unsigned int, uint32)能表示的碼位有0~0xFFFFFFFF,共4294967295個柏腻。
一個無限大的整數纸厉,一一映射為指定字寬的碼元序列。就是CEF要解決的問題五嫂, 這個問題可以通過變長編碼來解決颗品。 無論是UTF-8還是UTF-16,本質思想都是通過預留標記位來指示碼元序列的長度沃缘。從而實現變長編碼的躯枢。
碼元 Code unit: The minimal bit combination that can represent a unit of encoded text for processing or interchange. 碼元是能用于處理或交換編碼文本的最小比特組合。通常計算機處理字符的碼元為一字節(jié)槐臀,即8bit锄蹂。同時因為計算機中char其實是一種整形,而整形的計算往往以計算機的字長作為一個基礎單元水慨,通常來講得糜,也就是4字節(jié)。Unicode定義了三種不同的CEF晰洒,分別采用了1字節(jié)朝抖,2字節(jié),4字節(jié)的碼元欢顷,正好對應了計算機中最常見的三種整形長度。
元嬰:字符編碼方案(CES)
通過CEF捉蚤,我們已經可以將字符轉為碼元(Code Unit)抬驴。無論是哪種UTF-X的碼元,都可以找到計算機中與之對應的整形存放缆巧。那么現在我們能說存儲處理交換字符這個問題解決了嗎布持? 還不行。 因為從碼元落實到底層的存儲陕悬,還有一些問題需要解決题暖。 假設一個字符按照UTF16拆成了A,B兩個碼元,那實際存儲的時候究竟應該把A放在前面呢還是B放在前面呢胧卤?而另一個程序又如何知道當前這份文件是按照什么樣的端序存儲碼元的呢唯绍? 無論是大端法與小端法的選擇,還是用于決定編碼字節(jié)序的標記枝誊,都是CES需要操心的方案况芒。
我們通常所說的動詞編碼(Encode)就是指使用CES,將CCS中字符組成的字符串轉變?yōu)樽止?jié)序列叶撒。而解碼(Decode)就是反過來绝骚,將字節(jié)序列通過CES的一一映射還原為CCS中字符組成的序列。
``
化神:傳輸編碼語法(TES)
通過CES祠够,我們已經可以將一個字符表示為一個字節(jié)序列压汪。 但是有時候,字節(jié)序列表示還不夠古瓤。比如在HTTP協(xié)議中止剖,在URL里,一些字符是不允許出現的湿滓。這時候就需要再次對字節(jié)流進行編碼滴须。
著名的Base64編碼,就是把字節(jié)流映射成了一個由64個安全字符組成字符集所表示的字符流叽奥。從而使字節(jié)流能夠安全地在Web中傳輸扔水。
至此,我們已經有了對編碼有了一個大致而不再是簡單的了解朝氓。本文這部分的絕大部分內容源自VONNG的一篇博文
二魔市、CTF中的傳輸編碼語法
常常好奇CTF里為什么會有base64、UTF-7等等這些奇怪的東西赵哲,現在我們知道了這些奇怪的編碼并不是出題人用來整你的待德,而是在實際生活中發(fā)揮了作用的呢!
1.Base64
維基百科:Base64是一種基于64個可打印字符來表示二進制數據的表示方法枫夺。由于2的6次方等于64将宪,所以每6個比特為一個單元,對應某個可打印字符橡庞。三個字節(jié)有24個比特较坛,對應于4個Base64單元,即3個字節(jié)可表示4個可打印字符扒最。它可用來作為電子郵件的傳輸編碼丑勤。在Base64中的可打印字符包括字母A-Z、a-z吧趣、數字0-9法竞,這樣共有62個字符耙厚,此外兩個可打印符號在不同的系統(tǒng)中而不同。一些如uuencode的其他編碼方法岔霸,和之后binhex的版本使用不同的64字符集來代表6個二進制數字薛躬,但是它們不叫Base64。
為什么要進行Base64編碼
其實BASE64編碼的初衷是為了滿足電子郵件中不能直接使用非ASCII碼字符的規(guī)定秉剑,但是也有其他重要意義:所有的二進制文件泛豪,都可以因此轉化為可打印的文本編碼,使用文本軟件進行編輯侦鹏,并且對于數據流來說是一種簡單的加密诡曙。
編碼原理
Base64編碼要求把3個8位字節(jié)轉化為4個6位的字節(jié),之后在6位的前面補兩個0略水,形成8位一個字節(jié)的形式价卤,6位2進制能表示的最大數是2的6次方是64,這也是為什么是64個字符(A-Z,a-z渊涝,0-9慎璧,+,/這64個編碼字符跨释,=號不屬于編碼字符胸私,而是填充字符)的原因,這樣就需要一張映射表鳖谈,如下:
可以看下面幾個例子:
其實我們都一樣
有很多編碼其實都屬于Base64系列
Base家族:在Base家族中還有Base32和Base16岁疼,其實Base32/Base16和Base64目的是一樣的,只是具體的編碼規(guī)則的不一樣罷了缆娃。Base32編碼將二進制文件轉換成由32個ASCII字符組成的文本捷绒;Base16編碼則將二進制文件轉換成由16個字符組成的文本。
UTF-7:UTF-7是一個修改版Base64(Modified Base64)贯要。主要是將UTF-16的數據暖侨,用Base64的方法編碼為可打印的字符序列。目的是傳輸Unicode數據崇渗。主要的區(qū)別在于不用等號
=
補余字逗,因為該字符通常需要大量的轉譯。現在UTF-7已經走入歷史宅广,很少被人使用葫掉。
2.Quoted-printable
維基百科:Quoted-printable或QP encoding,沒有規(guī)范的中文譯名乘碑,可譯為可打印字符引用編碼或使用可打印字符的編碼挖息。Quoted-printable是使用可打印的ASCII字符 (如字母金拒、數字與"=")表示各種編碼格式下的字符兽肤,以便能在7-bit數據通路上傳輸8-bit數據, 或者更一般地說在非8-bit clean媒體上正確處理數據
Quoted-printable與Base64是兩種基本的MIME內容傳輸編碼, 如果通常的"8bit"編碼不適用. 如果文本不含很多非ASCII字符套腹,quoted-printable編碼的結果的可讀性相當好而且緊湊. 但是,如果輸入的大多數是非ASCII字符资铡,那么quoted-printable編碼將變得既不可讀又非常低效. Base64并不是人可讀的电禀,但對于所有數據其成本均勻,適用于二進制數據與非拉丁字母語言文本笤休。
編碼原理
任何8-bit字節(jié)值可編碼為3個字符:一個等號"="后跟隨兩個十六進制]數字(0–9或A–F)表示該字節(jié)的數值. 例如尖飞,ASCII碼換頁符(十進制值為12)可以表示為"=0C", 等號"="(十進制值為61)必須表示為"=3D". 除了可打印ASCII字符與換行符以外,所有字符必須表示為這種格式.
所有可打印ASCII字符(十進制值的范圍為33到126)可用ASCII字符編碼來直接表示, 但是等號"="(十進制值為61)不可以這樣直接表示.
ASCII的水平制表符(tab)與空格符, 十進制為9和32, 如果不出現在行尾則可以用其ASCII字符編碼直接表示店雅。如果這兩個字符出現在行尾政基,必須QP編碼表示為"=09" (tab)或"=20" (space).
如果數據中包含有意義的行結束標志,必須轉換為ASCII回車(CR)換行(LF)序列闹啦,既不能用原來的ASCII字符也不能用QP編碼的"="轉義字符序列沮明。 相反,如果字節(jié)值13與10有其它的不是行結束的含義窍奋,它們必須QP編碼為=0D與=0A.
例子
If you believe that truth=3Dbeauty, then surely=20= mathematics is the most beautiful branch of philosophy.
解碼后:
If you believe that truth=beauty, then surely mathematics is the most beautiful branch of philosophy.
3.被MIME打敗的編碼
還有幾種編碼在CTF中也經常見到荐健,但是在實際應用中很少遇到,主要是因為同為傳輸編碼語法琳袄,MIME中的兩種編碼base64和QP encoding已經足夠強大江场,很好地滿足了人們的使用要求。
Uuencode
維基百科:uuencode這個名字是衍生自"Unix-to-Unix encoding"窖逗,原先是Unix系統(tǒng)下將二進制的資料借由uucp郵件系統(tǒng)傳輸的一個編碼程式址否,是一種二進制到文字的編碼。
XXencoding
維基百科:Xxencode是一種類似于uuencode的一種二進制到文字的編碼滑负,它只使用字母數字字符在张,以及加號和減號。也是一種用于傳輸文件的編碼格式矮慕。
XXencode 將輸入文本以每三個字節(jié)為單位進行編碼帮匾。如果最后剩下的資料少于三個字節(jié),不夠的部份用零補齊痴鳄。這三個字節(jié)共有 24 個 Bit瘟斜,以 6bit 為單位分為 4 個組,每個組以十進制來表示所出現的數值只會落在 0 到 63 之間痪寻。以所對應值的位置字符代替螺句。
三、總結
到了這里我們對傳輸編碼語法進行一個對比總結
Base64
源文本:I love you 1314!
編碼后:SSBsb3ZlIHlvdSAxMzE0IQ==
Base32
源文本:I love you 1314!
編碼后:JEQGY33WMUQHS33VEAYTGMJUEE======
Base16
源文本:I love you 1314!
編碼后:49206C6F766520796F75203133313421
Base全家桶 可以看到Base16是不用=填充的
UTF-7
源文本:我愛amber1314啊
編碼后:+YhFyMQBhAG0AYg-e+AHIAMQAzADEANFVK-
這是一個神器 UTF-7的編碼特點在于首有+
橡类,尾有-
蛇尚。
Quoted-printable
源文本:我愛amber1314啊
編碼后:=E6=88=91=E7=88=B1amber1314=E5=95=8A
W3C不只于QP 特點是非ASCII碼表中的字符前有=
UUencode
源文本:amber.txt
編碼后:
begin 644 amber.txt
%86UB97(
`
end
begin 644
一般為UUencode的標識
XXencode
源文本:我愛amber1314啊
編碼后:Enh8kfa3hMaJmAHAlB90V0U++
只有數字,大小寫字母顾画,+
取劫,-
UU+XX都在這里
03 Web世界里的字符編碼
看到這里確實很不容易匆笤,感謝能堅持到現在的讀者。
但對于字符編碼還有一部分內容十分重要谱邪,不論是CTF還是實際生活炮捧,Web都扮演了舉足輕重的角色,所以我們不得不看看Web世界里的字符編碼惦银。而這一部分的內容也與大名鼎鼎的XSS漏洞息息相關咆课。
一、瀏覽器解析過程
Web世界離不開瀏覽器扯俱,瀏覽器是顯示信息书蚪,進行交互的地方。而信息的展示又離不開一個個HTML文檔迅栅,所以我們先要看看瀏覽器是如何解析HTML文檔的善炫。
瀏覽器在解析HTML文檔時無論按照什么順序,主要有三個過程:HTML解析库继、JS解析和URL解析箩艺,每個解析器負責HTML文檔中各自對應部分的解析工作。
首先瀏覽器接收到一個HTML文檔時宪萄,會觸發(fā)HTML解析器對HTML文檔進行詞法解析艺谆,這一過程完成HTML解碼并創(chuàng)建DOM樹,接下來JavaScript解析器會介入對內聯(lián)腳本進行解析拜英,這一過程完成JS的解碼工作静汤,如果瀏覽器遇到需要URL的上下文環(huán)境,這時URL解析器也會介入完成URL的解碼工作居凶,URL解析器的解碼順序會根據URL所在位置不同虫给,可能在JavaScript解析器之前或之后解析。
二侠碧、三個火槍手
1.URL編碼
一般來說抹估,URL只能使用英文字母、阿拉伯數字和某些標點符號弄兜,不能使用其他文字和符號。這意味著替饿,如果URL中有漢字和其他符號语泽,就必須編碼后使用。我們在進行 URL 請求時视卢,瀏覽器會自動幫我們把部分符號轉換成 %
+ 十六進制數字
的形式
http://127.0.0.1/flag.php?x=1{)wo我
轉化為
http://127.0.0.1/flag.php?x=1{)wo%E6%88%91
2.HTML實體編碼
有些時候踱卵,我們想在頁面上顯示的東西會跟 HTML 本身的標記沖突。
比如我們只想在頁面中顯示 <script>alert();</script>
而不是執(zhí)行這串代碼的時候据过,我們如下這樣寫是不行的:
<html>
<body>
<script>alert();</script>
</body>
</html>
進行HTML實體編碼后惋砂,我們的代碼就成了
<html>
<body>
<script>alert();</script>
</body>
</html>
上面用到的是'&' + '約定名稱' + ';'
的形式蔬充,其實還有
'&#' + '十進制數字' + ';'
'&#x' + '十六進制數字' + ';'
比如上文的 <
這個字符可以表示為 <
和 <
3.JavaScript編碼
JavaScript編碼主要是為了解決URL編碼留下的坑進行的。(具體參見這篇文章)
簡單來講班利,就是不同的操作系統(tǒng)、不同的瀏覽器榨呆、不同的網頁字符集導致URL編碼的結果差異懸殊罗标,為了保證客戶端只用一種編碼方法向服務器發(fā)出請求,人們使用Javascript先對URL編碼积蜻,然后再向服務器提交闯割。
JavaScript編碼一般有以下幾種形式
- escape()函數編碼:形式為
%uXXXX
、%XX
竿拆,字符范圍0-F
宙拉,本身就是URL編碼的一種實現方式 - Unicode 編碼:
'\u' + '四位十六進制數字'
不夠四位前面補0 - JSFuck: 一種基于JavaScript原子部分的晦澀的編程風格,它只有6種字符:
[
]
(
)
!
+
丙笋,也可以來編寫程序并執(zhí)行谢澈,可以做到所有JavaScript能做的事情
三、復合編碼
<a href="javascript:alert(1)">test</a>
針對上述a標簽我們分析一下該環(huán)境中瀏覽器的解析順序御板,首先HTML解析器開始工作锥忿,并對href中的字符做HTML解碼,接下來URL解析器對href值進行解碼怠肋,正常情況下URL值為一個正常的URL鏈接敬鬓,如:“https://www.xxx.com“,那么URL解析器工作完成后是不需要其他解碼的笙各,但是該環(huán)境中URL資源類型為JavaScript钉答,因此該環(huán)境中最后一步JavaScript解析器還會進行解碼操作,最后解析的腳本被執(zhí)行杈抢。
整個解析順序為3個環(huán)節(jié):HTML解碼>URL解碼>JS解碼
下面我們對其進行做JS編碼>URL編碼>HTML編碼共3層数尿,進行驗證。
<a href="javascript:alert(1)">test</a>
JS編碼:<a href="javascript:\u0061\u006c\u0065\u0072\u0074(1)">test</a>
URL編碼:<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)">test</a>
HTML編碼:<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)">test</a>
如下圖惶楼,將編碼后的內容可以正常執(zhí)行砌创。
四、總結
這就是Web世界里的一些編碼內容鲫懒,這些編碼在XSS攻擊中尤為重要嫩实,可以說是XSS的編碼基礎。
這部分內容主要源自兩篇文章
XSS 編碼的一些基礎知識
淺談XSS—字符編碼和瀏覽器解析原理
URL編碼
源文本:https://www.baidu.com/s?wd=https://www.baidu.com/s?wd=我的貼身锌遥花
編碼后:https://www.baidu.com/s?wd=%E6%88%91%E7%9A%84%E8%B4%B4%E8%BA%AB%E6%A0%A1%E8%8A%B1
HTML編碼
源文本:<>
編碼后:<>
或<>
或<>
JS編碼
源文本:alert(1)
編碼后:alert%281%29
或\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029
04 終于寫完了
一開始沒有想到甲献,會寫這么多內容。不過我一直覺得CTF不是終點颂翼,CTF里遇到的知識往往比題目本身更有挑戰(zhàn)晃洒、也更具趣味慨灭。
最后不得不說,本文的作者其實也是一個剛剛入門的小白球及,如果文中有錯誤的地方氧骤,請各位大神不吝賜教。