技術攻防篇:澳門民間投票 2019 失敗經驗分享

Jason CHAO
庭•思•間
Published in
Jan 5, 2021

本文源自於2020年12月5日在台灣零時政府雙年會(g0v Summit)上之報告,分享另有政治威脅篇

報告及此篇文章只代表我個人,不代表 2019 投票活動之發起組織。

吸收 2014 澳門民間公投經驗

2014年的澳門民間公投是非常嚴謹,對所有投票人都有檢驗身份證資料,投票得出的數字有高可信性。吸收了2014年被打壓的經驗,投票發起組織(新澳門學社)想在安全及低風險的環境下舉辦投票,所以要減少活動的政治爭議。這次活動不叫公投,也不收集身份證資料,改為只檢驗澳門本地電話號碼。

投票程式設計的主要考量

雖然本次投票不處理身份證號碼等敏感資料,安全風險應該比2014年低很多,但設計上的安全考量仍然以假設投票有在處理敏感資料,同時也考量結果計算要比2014年更透明。

投票程式的核心邏輯可以很簡單,好像這裡幾行的偽程式碼一樣,先檢查你有投票了沒有?如果沒有投票,就讓你投票。是不是有需要在設計上想太多呢?當然,如果設計這樣簡單,很快就會出問題。

第一,要記錄及管制同一電話號碼或者身份證在一段時間內嘗試通過驗證的次數,這個邏輯很普遍,我想也不用太多說明。

第二,資料在儲存時在不同層面有加密。萬一其中一層出現安全問題,也不會對整個活動安全造成影響。加密有三條加密鑰匙,若果遺失任可一條鑰匙,資料就不可恢復。

第三,無可避免的,要驗證澳門電話號碼要經過澳門的電訊網絡的短訊服務,澳門很多人只有安裝微信,所以我無辦法依靠WhatsApp 等較安全的平台。我可以做的是透過澳門以外的電信商發出驗證訊息,以及不斷更換發出者號碼以防止阻截。之後,我們發現外地短訊無辦法轉送到大約17% 的澳門號碼。澳門市場小,外地電訊商也不緊張去及時處理問題。最後我只好加入後備發送機制,若果透過美國電訊商發送短訊未有成功狀態更新,就再透過澳門本地的數據機發出。

第四,要比2014年增加點票透明度,每人投票後會看到一個查詢碼,之後可以在公開的選票資料中找到自己一票有否被點算。而每筆投票記錄都與上一筆有加密算法上的聯繫,形成一條鏈。

再配合在投票開放期間,每兩小時在公佈投票人數同時,也公佈累積加密摘要。外界可以在投票結束後,獨立核實主辦方公開的選票記錄是否與投票期間公佈的加密摘要相符,計算時否正確,以確實資料曾否被修改。

技術攻擊及防禦

第一,攻擊者掃描是否有已知的程式漏洞,因為程式是新開發,不是基於現有的 CMS,這些操作對我們是無效的。大家都見到右手邊記錄的簡體中文字,都不難猜到攻擊來源了吧。

第二,程式原設有重寄短訊功能,但之後取消,當中發出次數限制的功能我以為存在但其實沒有啟用。所以,其中一個點被發現可以向同一電話號碼不斷發出短訊,好運的是,攻擊在一個半小時內就被發現後,就馬上處理了。但短短1.5小時內已導致短訊發出資金被額外消耗多大約台幣5000元(港幣約1,400元),但這數目可算說是所有攻擊造成的唯一實際損失。

問題解決之後,我想不要讓攻擊者知道問題已經解決,想讓他們以為這攻擊還有效,我故意將請求回覆的狀態仍然寫著成功,加上當時攻擊的速率很低,每秒1請求,我認為可以接受,所以就放任無效的攻擊繼續來,目的是消耗他們的時間,減低他們改變攻擊方法的機會。

要封鎖攻擊IP地址是做不完的,因為攻擊者不斷在轉換不同國家的網絡出口,所以我不再做發現一個攻擊IP封一個的動作。我集中在收緊網絡流量限制。這裏顯示的是投票一開始的設定流量限制,最初的設定很寬鬆。我抱歉最終的設定沒有截圖保留下來。

這種放任無效攻擊的策略,不排除達到了消耗對方時間的目的。我相信假的成功狀態令攻擊者以為同一方法仍有效,攻擊者在四、五天內將同一無效攻擊量從每秒1請求慢慢提升到約每秒260請求。但在這情況下,放任策略不能長久下去。

因為Cloudflare 對來自新的IP 地址的高流量要幾秒鐘才有反應阻截,投票程式亦不一定能阻截頭0.5 秒內的高流量。伺服器是幾乎同時處理多個請求,所以每個請求在寫入資料前檢查未有超過限制,但一同寫入後就超出了限制。在這裏高並行問題實際對投票安全及完整性沒有影響,因為驗證及之後的請求全部都不會成功。但技術上算少少的突破了我設定的限制。高並行問題是有方法處理的,但改寫程序的時間成本高。

所以最後,我決定放棄放任無效攻擊的策略,要求澳門以外的IP 地址執行瀏覽器運行JavaScript 的檢查。一實施之後,攻擊就停止了。

觀察

在防守工作中,我有一些有趣的觀察。第一,中國攻擊者也是按類似九九六工作制上班。九九六是中國科技行業剝削的代名詞,意思是早上九時上班晚上九下班一星期工作六天的制度。我發現攻擊來源IP地址只會在中國時間早上十時至晚上十時才有變化,我猜這段時間就是他們上下班的時間。我身處英國夏季時間,可以在他們下班後,先阻截不再改變的IP地址,慢慢分析記錄,再決定下一步怎樣做。換句話說,我與攻擊者有7小時時差對防守有優勢。

觀察二,設計要想辦法平衡安全與易用,比如說,常見的選照片reCaptcha,對我們可能很簡單,但對老一輩來說可能很難。使用者失敗太多次會很沮喪。這是真實義工所表達的意見。圖靈測試是一個重要的關卡要來防止自動程式干擾,未來可能要找一個更好驗證人類操作的方法。

技術攻防過程時間表

經驗學習及反思

針對投票的技術上的攻擊是成功阻擋了,但投票最終不敵政治上的威脅

這次的打壓方式是很低調,但是很有力度。我猜想目的是避免引起更多關注。比如說,為甚麼沒有大型的 DDoS 的攻擊呢?可能這會很容易引起國際媒體的關注。所以技術上,他們使用花時間、成功率較低的攻擊策略。

值得保持的做法是不介意花心思將投票程式過度設計,提供更多保護。此外,技術人員在外地遠端提供支援,不受本地環境干預,也是對投票資料安全保護的一個重要部份。

也有要再思考的做法,放任無效的攻擊,讓攻擊者認為無效的攻擊有效,會否引起更多問題,要再研究及實證。

個人方面,程式的開發、保護工作要花很多時間。其實2019年8月我是在忙法律碩士論文的時間,本來計劃只抽出兩星期出來幫忙做投票的事情,但最後變了要抽四個星期。投票宣佈結果後,距離我交論文只有十天,但還有40%未完成。所以呢,有其他事忙就不要「跳大坑了」(註:為台灣零時政府社群之術語,指「自行認領一份工作」)。

--

--

Jason CHAO
庭•思•間

doctoral researcher, technologist and advocate of human rights / LGBT+ equality