安卓鎖屏不到2分鐘被破解,僅需換一張SIM卡_風聞
量子位-量子位官方账号-2022-11-12 18:20
Pine 蕭簫 發自 凹非寺
量子位 | 公眾號 QbitAI
換個SIM卡,就能解鎖別人的手機?!
並且整個解鎖過程不超過兩分鐘。

一位外國小哥偶然間發現了谷歌Pixel手機上的這個漏洞:
能夠直接繞過手機本身的指紋和密碼保護,切換手機卡就能更改密碼解鎖屏幕。
嚴格來説,這個漏洞並非谷歌Pixel手機“獨有”,而是Android系統中的一個bug,任何基於Android搭建的操作系統都可能受到影響。
例如有網友試了試開源安卓系統LineageOS(刷機黨常用系統),就發現同樣“中招了”:

還有網友在自己的Android12系統上試了下這種破解方式,“it works”!

不過這還不是最離譜的,更離譜的是這位小哥在向谷歌反饋之後,安全團隊隔了近半年才修復這個漏洞。
在説小哥和谷歌關於這個漏洞的“拉鋸戰”之前,我們先回過頭來看看這是個什麼樣的漏洞?
2分鐘內就能破解手機鎖屏
小哥“貼心”地上傳了以破壞者視角破解漏洞全過程的視頻,整個過程花了不到兩分鐘。

話不多説,直接來看。
首先用錯誤的指紋和手機密碼解鎖手機,直至鎖定。

然後用一張其他的SIM卡直接更換手機原來的SIM卡。

接下來再用錯誤的SIM卡密碼(注意:這裏的密碼和手機密碼不是一回事)鎖定SIM卡。

SIM卡被鎖定後,手機便會索要其PUK密碼,在這SIM卡的原始包裝上,如果丟失也可直接打電話向運營商查詢。
PUK(Personal Identification NumberUnlock Key),SIM卡自帶的PIN解鎖碼。

輸入PUK密碼後,直接重置新SIM的密碼便能開鎖,手機原有的密碼和指紋都成功繞過。
bingo!

至於是如何發現這個漏洞以及為什麼過了近半年才修復這個漏洞,也是個很有意思的過程。
以下是小哥的經歷:
當時手機電量快耗盡關機了,他充上電重新啓動後,手機要求提供SIM卡的PIN碼,但卻突然忘記了密碼,在亂試一通之後“成功”把手機鎖定。
要解開這個鎖定便需要PUK密碼,所幸他找到了原有包裝並輸入了PUK碼。結果,重置SIM卡密碼後,手機竟然直接解鎖了!

發現這個大Bug之後,小哥向谷歌(Android VRP)提交了這個內部漏洞報告,也是從這時開始,小哥和谷歌的“拉鋸戰”開始了。

他仔細查看了Android和谷歌的設備安全獎勵計劃,發現自己最高可以獲得10萬美金的獎勵,於是便申請了。

不過在報告提交一個月後,小哥收到了Android安全團隊的一份郵件:
Android安全團隊認為,這個問題另一位外部研究人員之前已經報告過了。
對此小哥認為,這份回郵的言外之意就是,最高十萬美金的獎勵他一分錢都拿不到。

時間又過了一個月,小哥收到安全團隊的郵件,對方稱漏洞還在修復中……
又又過了一個月,九月谷歌發佈了新的補丁,但這個Bug依舊沒有修復……
不過小哥也不是輕言放棄的人,他直接來到谷歌辦公室,用谷歌Pixel手機演示了一下這個漏洞。
而後他給安全團隊定了個漏洞修復期限:10月15日之前。而對方的回覆也很乾脆:10月份這個Bug修不好!

在拉扯一番後,小哥和谷歌建立了聯繫,能夠實時得到漏洞修復的反饋。
谷歌方也確定了修復工作的具體時間:11月份進行,現在這個漏洞已於11月5日谷歌的安全更新中被解決。
值得一提的是,關於提交漏洞的獎勵,小哥最終也拿到了7萬美金,不過谷歌對此還做出了一番解釋,用小哥的原話來説,就是:
儘管我的報告是重複的,但正是因為我的報告,他們才開始着手修復。正因為如此,他們決定破例一次,並獎勵給我70000美元。
小哥和谷歌的完整對話鏈接附在文末了,感興趣的夥伴可以自行查看。(手動狗頭)
究竟為什麼會出現這樣的漏洞?
現在,谷歌的安卓工程師們終於把這個漏洞給補上了。
然而讓小哥驚訝的是,bug修復遠不止他想象的“一行代碼補丁”那麼簡單。
從提交的修改情況來看,光是要改動的文件數量,就達到12個:

所以這個漏洞究竟是怎麼出現的?
簡單來説,Android系統中有一個叫做“安全屏幕”(security screen)的概念,其中包含兩種東西,一種是PIN、指紋、密碼等各種直接解鎖密保的屏幕操作,另一種是SIM PIN和SIM PUK等各種解鎖手機鎖定狀態的操作。
這些操作被放在一個棧(stack)中。
正常解鎖谷歌手機時,直接用PIN、指紋或密碼都可以,但不能超過3次,否則就會被鎖定。
但如果忘記密碼,手機(在輸入3次錯誤密碼後)被強制鎖定了,同時SIM PIN條目可見,它就會被放置在其他屏幕解鎖操作之上,用來讓你解除手機的鎖定狀態。

**△**棧原理
這時候,如果使用SIM卡自帶的PUK密碼,就能通過一個叫“PUK重置組件”的模塊調用**.dismiss()**函數,將手機鎖定解除,並繼續顯示棧下面的其他屏幕解鎖操作,在小哥的案例中是指紋鎖屏。

**△**就是這個函數
這裏注意,**.dismiss()**函數可不是一個“專人專用”的函數,它並不只會解除SIM卡的手機鎖定屏幕,連PIN、密碼和指紋之類的正常鎖屏也能解鎖……
這就導致它極容易受到競態條件影響,一旦兩個線程執行順序出現一點兒誤差,就可能導致屏幕解鎖出現問題。
競態條件即兩個或者以上進程或者線程併發執行時,其最終的結果依賴於進程或者線程執行的精確時序。

舉個栗子,如果在“PUK重置組件”的模塊調用.dismiss()函數之前,就有操作改變了當前的安全屏幕,那麼.dismiss()函數就可能誤解鎖指紋鎖屏。
關鍵來了,由於手機SIM卡狀態是隨時更新的(系統一直在監視SIM卡狀態),因此如果SIM卡狀態發生變化,系統也會更新當前的安全屏幕。
所以一旦“PUK重置組件”成功調用了.dismiss()函數,它就會在解鎖PUK屏幕之前,直接先解鎖了指紋鎖屏!
根據谷歌公開的漏洞報告,它在Android 10到Android 13系統中都可能出現:

當然,也有網友測試發現,Android 11似乎不受影響,而是在Android 12中出現了。

還有網友發現三星手機也“逃過一劫”:

現在,安卓工程師們重構了.dismiss()函數,簡單來説就是給它打個小小的補丁,讓它只能解鎖帶有“SimPuk”標記的安全屏幕(也就是隻能解除手機鎖定屏幕)。
小哥本人對此沒有異議,但也有網友認為,這不是這次漏洞的最優解:

永遠不要假設任何bug都只有一種特殊情況。如果不解決代碼的根本邏輯,災難就一直存在。
你的安卓手機中出現了這個bug嗎?
對話傳送門:feed.bugs.xdavidhu.me
參考鏈接:
[1]https://bugs.xdavidhu.me/google/2022/11/10/accidental-70k-google-pixel-lock-screen-bypass/
[2]https://news.ycombinator.com/item?id=33544883