每個月其實都有很多資安事件發生,像是某某公司資料外洩、被駭客入侵、系統管理不當等等。台灣 IT 相關的媒體也會報這類新聞,但我們想提供新聞資訊之餘,還能有更多反思。

我們今後會拿一些資安新聞跟大家介紹,分享一些我們認為背後的資安問題與企業問題,並且分享攻擊手法和防禦方法。

密碼沒被好好管理的事件其實非常多,尤其是在小公司的服務或台灣的網站(?),甚至他們也許只是沒告訴你,他們在搜集你的密碼。

扣掉一些不會想要好好管密碼的公司,當然也有一些是不小心的,Google 就是一個例子。

誤存密碼的事件

五月底的時候,Google 在他們官方部落格發了一篇文章,大致如下:

我們最近發現在 G Suite 服務中,誤把一部分使用者的密碼以未雜湊(Unhashed)的形式記錄在加密的內部系統中,不過這樣的問題僅影響 G Suite 用戶,並不影響 Google 一般帳號。

之所以會發現是在今年一月的時候,有新的 G Suite 客戶遇到註冊的問題,讓 Google 在追查原因時發現了這樣的漏洞。

而問題的原因在於 2005 年的一項功能實作錯誤所導致。這項功能是在管理員控制台儲存了未雜湊的密碼副本,不過這些密碼僅存在他們內部系統 14 天。

雖然問題已經修復,並且也沒有看到存取或濫用這些密碼的證據,但 Google 還是通知 G Suite 管理員更換這些密碼,並且建議使用者多用更多如兩步驟驗證(2FA)等的防禦機制。

事情嚴重嗎?

在聲明稿上的資訊來看,其實不算太嚴重。因為密碼雖然被誤存,但只存在內部服務,並且 Google 也說明這麼密碼沒有被濫用的證據(不過也有可能已經被濫用只是沒證據而已)。

但這只是就「這個事件」來看不算嚴重,但就以這個行為疏失來說,其實是嚴重性高的。很多公司其實都有這種密碼誤存的問題,只是他們可能是誤存在外部機器、或一些更明顯的地方,或甚至已經被駭客拿去黑市販賣密碼了。

如果身為一個網站工程師,你一定會知道、而且你一定要知道:網站不該存明文密碼。 在我們分析這次資安事件前,先來科普基本的存密碼方法。

雜湊(Hash)函式 - 密碼儲存的方法

網站不該存明文密碼

明文(Plaintext)的意思是在密碼學上的一種說法,指這個資訊是「可讀訊息」,而如果被加密或經過雜湊過後的密碼,就不屬於明文(你可以想像玩風聲的時候送「文本(牌打開)」和「密電(牌蓋起來)」的差別)。

一般來說,網站是不會、也不該儲存使用者的密碼的。網站只儲存「雜湊過後(Hashed)的密碼」。而這個雜湊密碼,根據密碼學的原理,很難被解回原本的密碼

假設使用者有個密碼 iLoveYou2,網站不應該把這九個字存起來,而是要把這九個字丟進雜湊函數(比起過時且有資安問題的 md5,現在普遍會用 sha256 這種雜湊函數),來得到一個獨一無二的亂碼:

$ echo -n iLoveYou2 | shasum -a 256
a355eaea819726af0c18f59f15fe3b017eaf2d6add88c89798b9812a8e4dc1d6  -

$ echo -n iLoveYou | shasum -a 256
103d6dd815166561716e265a69bf7dec567cc3347de3a1451f20647b3911cbd3  -

a355eaea819726af0c18f59f15fe3b017eaf2d6add88c89798b9812a8e4dc1d6 這個是 iLoveYou2 經過 sha256 雜湊後出來的亂碼,而 103d6dd815166561716e265a69bf7dec567cc3347de3a1451f20647b3911cbd3 這個是 iLoveYou 經過 sha256 雜湊後出來的亂碼。

你可以看到差一個字(少一個 2),雜湊函數出來的結果就差很多。而當你拿到 a355..c1d6 ,因為密碼學的原理,你「幾乎無法」知道他一開始放入的字串其實是 iLoveYou2

這就是網站要存密碼的方式,網站只需要存 a355..c1d6 這一長串,不需要存你真正的密碼。而一但你要再次登入的時候,你把 iLoveYou2 這串密碼傳送給網站,網站只要算一遍你送來的這串經過 sha256 之後會不會等於 a355..c1d6 上面那串(同個字串丟入 sha256 會是同樣的亂碼),如果相同的話代表你是合法的使用者,你擁有真正的密碼可以登入。

駭客怎麼攻擊

我前面提到「幾乎無法」知道他真正的密碼。但其實如果我拿到 a355..c1d6 這串雜湊過後的亂碼,還是可能可以知道原本真正的密碼是 iLoveYou2。應該說是「猜到」,我們可以暴力破解(Brute Force) 的方式一個一個字猜,從 a 丟進 sha256 看答案一不一樣,再丟 aasha256 看一不一樣,猜到天荒地老。

不過當然不會是我自己來猜,我們喜歡用工具來解決這些問題。John The Ripper 就是一套快速幫你猜密碼的工具。如果駭客偷到一個雜湊過後的密碼,他可以用這個工具來暴力破解,就有機會取得你真正的密碼。

如果你覺得這種攻擊很爛而且根本猜不中,但事實是就是會猜得中。因為有些使用者的密碼真的設太爛了,可能只有六個數字或六個字母,這樣等級的密碼在 John The Ripper 面前也許不用一天就解得出來。

比較好的存法

比較好存密碼的做法應該要加鹽巴(Salt)來防止「彩虹表(Rainbow Table)攻擊」:駭客可以在自己的電腦先算好上千萬個雜湊值,等以後偷到網站的密碼雜湊值之後,不用暴力破解,只要查表就可以了。

假設我設了一個全世界最好的密碼 123456,因為這個密碼太簡單了駭客早就先算好這個雜湊值,他可以馬上查表就發現 8d96..6c92 的密碼是 123456。要預防這樣的攻擊的話,網站在存密碼的時候會幫你在這串密碼後面加上一些鹽巴:

$ echo -n 123456 | shasum -a 256
8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92  -

$ echo -n 123456ELOo9C8gtkGweZdi | shasum -a 256
a73613bda2733cb9d443d7db87b649ed0011004daee4431f9c218606b9ea43cd  -

在後面加上一串無關緊要的字串 ELOo9C8gtkGweZdi 駭客就無法用彩虹表攻擊直接找出密碼。

而之後如果你要登入,你一樣是送 123456 給網站,網站會先將你的密碼後面加上 ELOo9C8gtkGweZdi 才送去雜湊,確認如果雜湊結果一樣那就代表你是合法的使用者。

不過與其用 sha256 自己來加鹽巴,建議你可以用更好的雜湊函式:bcrypt,內建加鹽預防彩虹表攻擊,bcrypt 也可以調整參數來減慢暴力破解的速度。

但根本問題還是自己的那串密碼,太簡單的密碼就算這樣加鹽巴,駭客也還是可以暴力破解,使用者自己還是需要為自己的密碼負責才行。

為什麼 Google 會誤存未雜湊密碼

官方聲明「未雜湊」,我們可以先理解是明文密碼,儘管官方聲明他們是將這些明文密碼誤存在「加密的」內部系統,這個內部系統代表著 Google 內部員工其實是有機會可以取得資訊的。

但像 Google 裡面有這麼多厲害的工程師,為什麼還是會犯這樣的錯誤?我們可以來做幾項猜測:

是功能特色而不是漏洞

功能特色(Feature)和漏洞也許是一體兩面的。

我曾經聽過有間公司他們在做登入功能的時候,會把使用者要登入的密碼也記錄起來。

原因是他們常收到使用者抱怨登入不進去,但結果是使用者自己打錯密碼。於是公司工程師就做了一個「功能」。這個功能特色是會記錄所有使用者登入時輸入的密碼。一但有使用者來抱怨無法登入,工程師就會把使用者輸入的密碼拿給使用者看,問他們說:是不是你打錯密碼了呢?

也許 Google 並沒有開發這樣功能的打算,但在新聞稿上寫說和管理員可以「重置和恢復被管理使用者的密碼」有關,是否這個恢復密碼的機制就是問題點?在設計讓管理員可以恢復使用者密碼的功能時,是存「加密後」的密碼(可解回真正密碼),而不是雜湊過的密碼(不可解回真正密碼)?

除錯功能

工程師都知道,我們在開發時喜歡開除錯模式(Debug Mode),把一些除錯資訊秀出來確認自己開發正確。

在確認密碼相關功能的時候,我們可能會寫一些邏輯像是:如果在開發環境,那就幫我記錄一下我打的密碼。

但如果這個除錯功能不小心也被部署在真正產品上,是不是使用產品的人密碼都被記錄了?許多網站有時都會不小心打開一些除錯功能,有時看似無傷大雅,但卻可以讓駭客偷到網站更機密的資訊。

日誌配置錯誤

和除錯功能類似,也是為了做分析、障礙排除、找臭蟲(Debug)等等,我們會記錄一些流量資訊、使用者資訊在日誌裡。記太少會無法找到錯誤原因,記太多好像除了硬碟要大一點,比較沒什麼問題。

但事實上,很多駭客喜歡去找公司的日誌檔案,從裡面翻找一些有用的資訊。一但記太多資訊,像是記錄「所有請求的封包」,就會把登入封包也記錄下來。而這個登入封包裡面,會有使用者的明文帳號和明文密碼。

你可以怎麼做

發揮良心,不要直接存密碼

如果你也不希望自己密碼被偷的話,那就將心比心,我們在開發服務存別人的資訊和密碼的時候,好好管理和儲存。

密碼加鹽並且只存雜湊過後的密碼。並且不要記錄任何密碼的任何其他形式、字串等等。

通常網站也都會有忘記密碼的功能,請讓使用者重設密碼,而不是告訴他之前的密碼是什麼。因為告訴他密碼,其實意味著網站已經明明白白的存了一份使用者的密碼了。

防止日誌濫用

就算你硬碟容量很多,也不能隨意記錄任何流量,因為有時敏感資訊就會這樣被記錄下來。不要把使用者的敏感資訊都記在日誌裡了,如果真的需要記錄敏感資訊,也應該是先將使用者敏感資訊雜湊過後(更好的做法是記錄訊息鑑別碼)再存到日誌。

使用者自保

我們身為使用者,其實無法知道每個網站的資安程度到底是如何,外表看似很新穎的公司,可能也只是金玉其外、敗絮其中。使用者我們自己也要好好注意:

  • 不要太相信服務:在準備用每個服務的時候,可以先用你自己比較不重要的帳號來註冊,如果你真的相信這個網站了,再看要不要換成自己常用帳號來使用。
  • 不要用單一密碼:註冊不同服務和網站,建議都用不同的密碼,密碼可以靠一些密碼管理工具來管理。至少一但某個網站被駭,不會導致自己所有帳號都遭殃。
  • 我被駭了嗎?(Have I Been Pwned?):如果擔心自己密碼早已外洩,可以到 have i been pwned? 這個網站上輸入你的信箱,這個網站收集了非常多已經洩漏在網路上的帳號和密碼,你可以在這網站上查詢自己帳號的密碼是不是早已經被公諸於世了。

資安問題有時候看似微不足道,也似乎不影響企業發展。但這其實跟自己道德良心也有些關係,既然別人要來用我們的服務,我們就要好好顧好別人的資料。而身為使用者也要有資安意識,拒絕那些濫用自己資料的企業。

但資安很難免還是會有疏忽,就算犯錯,我們也應該像這些大公司一樣勇於承擔這些問題並且對使用者負責。希望大家都可以當一個有良心的企業,和有資安意識的使用者。