手機驗證碼登入原理、風險和應對策略

波斯馬發表於2022-01-17

手機驗證碼登入是一種常見的應用登入方式,簡單方便,不用記憶密碼,市面上能見到的APP基本都支援這種登入方式,很多應用還把登入和註冊整合到了一起,註冊+登入一氣呵成,給使用者省去了很多麻煩,頗有一機在手、天下我有的感覺。

登入原理

手機驗證碼登入的原理很簡單,對於一個正常的登入流程,看下邊這張圖就夠了:

WX20220114-220950@2x

實際應用中會存在一些收不到驗證碼的情況,可能的原因如下:

  • 在手機端,簡訊被某些軟體認為是垃圾資訊而被攔截或者刪除,或者因為手機卡欠費導致收不到簡訊。

  • 在應用服務端,因為程式錯誤,或者安全控制策略導致部分簡訊傳送失敗。

  • 在簡訊平臺或者電信運營商系統,因為黑名單、關鍵字、流量控制,或者其它某些技術原因導致傳送失敗。

針對收不到簡訊的問題,系統中會增加重發驗證碼功能,如果多次重發還收不到,系統可以支援上行簡訊或者語音驗證碼的方式,這兩種方式都是簡訊驗證碼的變種。

  • 上行簡訊是讓使用者將系統提前生成好的若干字元傳送到系統指定的簡訊號碼,據此可以驗證使用者擁有指定手機的控制權,從而也就認證了使用者的身份。

    上行簡訊驗證碼

  • 語音驗證碼可以讓使用者發起,也可以在系統收到簡訊傳送未成功的回執時主動推送,使用者手機會收到一個自動語音通話,其中包含登入所需的驗證碼。

安全風險和應對策略

手機驗證碼的安全風險主要是被惡意利用和竊取。

因為手機驗證碼的應用十分廣泛,為了有一個更全面的認識,這裡說的安全風險沒有侷限在登入這一點上,所有使用手機驗證碼的場景都可能存在。這裡的應對策略主要是站在系統開發者的角度,通過各種技術方案來解決或者降低手機驗證碼的安全風險。

簡訊詐騙

詐騙者先獲取到使用者手機號,然後冒充金融機構、公權力部門、親朋好友,在應用中輸入使用者手機號請求驗證碼後,向使用者索要對應的手機驗證碼,使用者稍不注意可能就會造成金錢損失。

簡訊詐騙示意圖

針對此類問題,系統開發者可以考慮如下一些方案:

  • 在驗證碼中宣告:工作人員不會索取,打死也不要洩漏給別人。不過人在一些特殊情況下是不會理會這些警告的。

  • 跟蹤使用者的常用登入特徵,比如獲取驗證碼時的裝置、IP、WIFI、地域不是常用的,系統就可以馬上簡訊或者語音通知使用者可能存在安全風險,請謹慎操作;系統還可以直接升級安全級別要求更多的驗證方式,比如需要再次獲取驗證碼、輸入安全碼、刷取指紋、識別人臉、插入U盾等等驗證方式。

還有一種相對隱蔽的詐騙方式,詐騙者直接向使用者傳送仿冒釣魚網站的地址,使用者在釣魚網站獲取驗證碼時,詐騙者拿著使用者手機號去真實網站請求驗證碼,此時使用者會收到一個真實的驗證碼,使用者在釣魚網站輸入驗證碼後,詐騙者就可以拿著這個驗證碼去真實網站使用。

針對這種情況,前邊的識別使用者常用登入特徵的方式仍然有效。此外簡訊平臺和電信運營商也有責任對簡訊內容進行把關,簡訊平臺需要驗證傳送者的真實身份、稽核簡訊內容,並提供動態的流量控制機制,這樣可以過濾掉絕大部分詐騙簡訊。

其實電信運營商是能夠識別手機位置的,如果電信運營商能夠提供一種安全的位置認證服務,也可以解決大部分驗證碼詐騙問題,比如前端提交驗證碼認證時攜帶電信運營商提供的位置標識,應用服務商可以拿著這個位置標識去找電信運營商驗證位置,當然這只是一個設想,現實中還沒有這種方法。

簡訊攻擊

可能有兩種場景下的簡訊攻擊:

  • 使用者在前端不停的點選獲取驗證碼,可能是擔心收不到驗證碼,也可能是失去了等待的耐心,也可能是惡意向別的手機號傳送。

  • 攻擊者直接呼叫傳送驗證碼的介面,在極端的時間傳送大量驗證碼請求,可能是發給某個使用者也可能是一批使用者。

此類操作首先會浪費簡訊資源,給應用服務商造成損失;惡意攻擊還會向無辜的使用者傳送大量簡訊,造成騷擾攻擊。

簡訊攻擊示意圖

應對這種問題,可以考慮如下一些方案:

  • 增加其它驗證。

    獲取簡訊驗證碼之前必須先通過這些驗證,比如圖形驗證碼、滑動驗證碼、數學公式驗證碼等等。這些方式可以增加傳送簡訊驗證碼的難度,降低人工的傳送速度,儘量避免機器人自動操作。

  • 對操作進行限流。

    比如現在前端常見的傳送簡訊驗證碼倒數計時,一般每次請求驗證碼後經過若干秒才能再次傳送。因為如果攻擊者獲取到了傳送驗證碼的服務介面,就可以擺脫前端邏輯的限制,所以後端也可以採用同樣的策略,對裝置Id、手機號、IP、使用者、業務型別等等,以及它們的各種組合,進行頻率控制。應用開發者還可以根據傳送結果特徵來進行控制,比如空號率,如果空號太多則說明可能是機器人隨機生成的手機號。在單一頻率的限制基礎之上,還可以增加更多的時間控制,在分鐘、小時、天等時間維度上做不同的閾值限制。

  • 給使用者提供一個簡訊退訂入口。

    使用者頻繁收到非自己主動發起的驗證碼簡訊時,可以提供一個退訂入口,讓使用者在短時間內關閉簡訊驗證碼,應用服務此時可以忽略給使用者傳送驗證碼的請求,或者直接去掉髮送驗證碼的功能入口。

但是這種控制要儘量以不影響使用者的正常業務操作為前提,否則就得不償失了。

  • 比如圖形驗證碼的難度不要太高,畢竟大部分業務不是12306,你照搬過來可能就會弄巧成拙。

  • 再比如對於限流控制,假設正常使用者一般只在一天的某些時候進行操作,不會一天24小時都在做某一件事,則可以這樣做:每個手機號每小時只能傳送X次,每天只能傳送Y次,這兩個數值要符合 X<Y & 24*X>>Y。

  • 對於嚴重的攻擊,應該設定熔斷機制,此時不得不犧牲可用性。比如短時間湧入了大量針對不同手機號的驗證碼需求,很可能是受到了DDOS攻擊,因為資源有限,此時正常使用者的操作也會受到影響,可以依託全侷限流,觸發限流時直接關閉驗證碼服務一段時間。

網路竊聽

假設使用者收到了登入驗證碼,輸入正確後提交服務端驗證。在從手機端到服務端的傳輸過程中,會經過很多的網路裝置和伺服器系統,登入提交的內容有被攔截獲取的可能,此時攻擊者就可以阻斷請求,自己拿著使用者的手機號和驗證碼去登入。

網路竊聽示意圖

應對這種問題,一般需要對網路傳輸內容進行加密,比如現在常用的https通訊,可以保證兩端之間的傳輸內容安全,不被竊聽。對於傳輸安全,一般這樣處理也就夠了。

不過https也不是銀彈,如果有攻擊者在客戶端偷偷匯入了自己的證書,然後讓網路請求都先通過自己進行代理,再傳送到目標地址,則攻擊者還是能夠獲取到請求內容,想體驗這種方式的可以使用fiddler試試。還有https證書存在錯發的可能,如果給攻擊者發放了別人的證書,此時安全傳輸也就沒什麼意義了。

https中間人攔截

為了更高的安全性,傳輸內容可以在應用中加解密,客戶端對要傳輸的資料按照與服務端的約定進行加密,然後再傳送到網路,攻擊者截獲後,如果沒有有效的解密手段,則可以保證資料不被竊聽。加密的重點是保證金鑰安全,不被竊取和替換,可以採用其它安全通道傳輸,甚至線下傳遞的方式。對於驗證碼這種僅做驗證的資料,還可以通過加鹽後進行慢Hash運算,攻擊者即使拿到了傳輸內容,要進行破解的難度也相當巨大。

本地竊聽

如果系統上安裝了惡意軟體或者非官方版本的軟體,特別是在盜版系統、被Root或者越獄的手機系統中,攻擊者也能比較容易的攔截並竊取簡訊驗證碼;同時網路竊聽中的加解密也可能失去作用,因為軟體已經不可信,在不同的操作之間有麼有發生什麼貓膩,很難確定。

最近幾年在移動裝置上引入了一個稱為可信執行環境(簡稱TEE)的概念,獨立於作業系統,單獨的應用,單獨執行,有的甚至有單獨的處理器和儲存,外部很難進入和破解。一些關鍵的操作都封裝在這裡邊,比如指紋的採集、註冊和認證,金鑰的生成和使用,版權視訊的解碼和顯示,等等。如果把簡訊驗證碼的處理也放在這裡邊,無疑會安全很多,不過這要解決很多通訊方面的問題,收益與成本可能不成正比。在桌上型電腦中這一技術還所見不多,可能桌上型電腦的環境已經有了比較成熟的安全體系,不過從移動端遷移過來難度應該也不大。

簡訊嗅探

簡訊嗅探也是一種竊聽技術,不過是通過攻擊電信網路通訊的方式。

現在手機一般都使用4G、5G網路了,但是“簡訊嗅探”技術只針對2G網路,不法分子通過特殊裝置壓制基站訊號,或者選擇網路質量不佳的地方,或者使用4G偽基站欺騙手機,這會導致網路降頻,使手機的3G、4G通訊降低到2G。

2G網路下,只有基站驗證手機,手機不能驗證基站,攻擊者通過架設偽基站,讓目標手機連線上來,然後就能獲取一些連線鑑權資訊,再冒充目標手機去連線真基站,連上以後撥打攻擊者的另一個手機,通過來電顯示得到目標手機號碼。

基站本身並不會用特定方向的訊號與每部手機通訊,而是向四周以廣播的形式傳送訊號。所以每部手機實際上也是可以接收到其他手機的訊號,2G網路傳輸資料時沒有加密,簡訊內容是明文傳輸的,就可以嗅探到目標手機的簡訊。加之2G通訊協議是開源的,所以這件事的技術門檻並不高。

簡訊嗅探原理

因為這種攻擊要求手機不能移動,如果基站切換就沒用了,所以攻擊一般選擇夜深人靜的時候。對於普通使用者來說,睡覺的時候可以選擇關機或者開啟飛航模式;另外開通 VoLTE ,可以讓電話和簡訊都是走 4G 通道,不過網路降級很難防範;或者買個能識別偽基站的手機,不過沒辦法保證百分百能夠識別;或者就只能等著移動運營商關閉2G網路了。

對於應用系統開發者,應該認識到通訊通道的不安全性。必要的時候開啟雙因子驗證,除簡訊驗證碼外還可以使用簡訊上行驗證、語音通話傳輸、專用密碼驗證、常用裝置繫結、生物特徵識別、動態選擇身份驗證方式等等多種二次驗證方法。

重放攻擊

假設某些交易服務需要通過簡訊驗證碼來驗證使用者的身份。如果有攻擊者截獲了交易請求報文,然後多次傳送到服務端,服務端僅檢查了驗證碼是否正確,則可能實際發生多次交易。此時攻擊者都不需要解密傳輸內容。

重放攻擊示意圖

此時應該限制驗證碼只能夠使用一次,服務端收到交易請求時首先檢查驗證碼,檢查通過後將驗證碼置位或刪除,然後再處理交易,不管交易是否成功,驗證碼都不能再次使用。另外還應該在生成驗證碼時設定一個較短的有效期,如果使用者沒有實際提交,攻擊者也必須在有效期內才能使用,增加攻擊難度。

當然你也可以使用更通用的防重放手段,比如每次請求驗證碼都先從後端獲取一個隨機數,隨機數如果已經使用過則不能再次使用,隨機數如果不存在也不能處理請求。當然隨機數也可以在前端生成,服務端如果收到了重複的隨機數則拒絕請求,但是需要防止傳輸過程中隨機數不被篡改,可以通過金鑰簽名的方式。


以上就是本文主要內容,才疏學淺,如有錯漏,歡迎指正。

收穫更多架構知識,請關注公眾號 螢火架構。原創內容,轉載請註明出處。

相關文章