這其實是前幾天看到 B 站代碼被開源后的一個感想,為什么要冒這么大風險去做這事,活著不好嗎?到底是 996 讓你瘋狂?還是不給漲薪還克扣工資?或者黑了你的蔡徐坤?鬼知道為什么會有這想法。 然后腦子里就冒出了一個更奇怪的想法,如果我要在代碼里下毒,要怎么做?
如何在 Android 代碼中下毒
這其實是前幾天看到 B 站代碼被開源后的一個感想,為什么要冒這么大風險去做這事,活著不好嗎?到底是 996 讓你瘋狂?還是不給漲薪還克扣工資?或者黑了你的蔡徐坤?鬼知道為什么會有這想法。
然后腦子里就冒出了一個更奇怪的想法,如果我要在代碼里下毒,要怎么做?
友情提示:如果你是一個管理者,或者一個項目的負責人,讀完以后請盡快去檢查你公司的代碼,小心被人下毒了。
Android 工程的幾個風險
隨手寫一段奇葩代碼在項目中,這不算下毒,畢竟這種毒分分鐘就被查出來了,還有可能成為控訴你的證據。
要說下毒,首先要講的就是幾個容易下毒的點了。
- 現在的 Android 工程都是使用 Gradle 管理依賴庫了。但是 Gradle 有一個非常奇葩的特性,允許你依賴一個 snapshot 包,而這個特性正常情況下甚至是無法被關閉的(特殊情況走自定義除外)。
- ContentProvider 居然是可以自動執行的,只要在 manifest 文件中聲明了你的 ContentProvider,并且保證這個 ContentProvider的 authorities 不會與其他的沖突,它的onCreate()方法就可以在應用啟動的時候被自動執行。當然,沖突了你也裝不上。
- Android 保留了遠程代碼執行能力,盡管現在的插件化手段越來越困難,但那些也都是限制在系統組件層面,如果只是想單純的在遠程執行一段 helloworld 程序,這實在太簡單。
- Android 截至目前都沒有一個正常的,可以確保退出的方法(別告訴我System.exit()算你的正常退出)。而當你調用System.exit()的時候,任何一個異常處理函數都不會有記錄,因為他特么就不是個異常。
- 原生函數居然可以讓 JAVAScript 直接調用,并且還沒任何權限問題,只要知道入口函數,任何一個網頁的 js 都能調用。雖然 API17以后本地要加上 @JavaScriptInterface注解的,這已經是進步了。但是這貨他到現在居然都還是個 runtime 注解,結合第三條,其實沒什么鳥用。
- 我不想寫了,寫再多可能要出事了。
配毒藥
上面這幾條,隨便兩三點混合起來,都是致命的。畢竟,無形裝逼,最為致命。
舉個栗子:
我在職的時候,隨便在代碼里面丟個 jcenter 的 snapshot 包依賴,此刻這個包是沒有任何風險的。 離職了以后,通過遠端,覆蓋掉這個 snapshot 包,在關鍵代碼中下點毒,寫個異常或者上面說的 System.exit()。此刻,這個包就有風險了。
稍微聰明一點,改進一下,在依賴的時候依賴一個正式包。但是依賴的這個正式包,再去依賴一個 snapshot 包,同樣可行。
上面的步驟有個問題,就是這個關鍵的代碼,他本身有可能不會被執行到。在改進一下,在 snapshot 這個 aar 里用上第二條說的:用 ContentProvider 在應用啟動的時候,就開始下毒,隨便開個線程,延遲個隨機數,再根據時間戳做個取模,隨機一批用戶,調用System.exit(),不反編譯代碼,神仙來了也不知道包為什么莫名其妙就閃退了。
前面一種例子適合 snapshot 包的場景,經常會有公司的打包機器是不允許連接外網的,其實很大程度就避免了這種問題。
只要你愿意,隨便網上丟一個class,再下載下來,通過ClassLoader直接 run 起來,一樣達到目的。
甚至你還可以限制再死一點,你公司在深圳,那就深圳的 IP 全部執行默認邏輯,外地 IP 才開始下毒??傊挥心阆氩坏?,沒有你辦不到。
最后
哦對了,git 的提交者信息也都是可以改的。
git config user.name(email)
放手干去吧,搞死那些 996 的公司,不會有證據的,別說是我教你的。