在取得Wii主機所使用的金鑰之後,接下來要做的工作就是要「修改」我們想要在Wii上執行的程式,讓Wii的安全機制認為這的程式是由官方認可,並經過數位簽署的程式,如此一來不需修改主機部分,就可執行自製程式。
前情提要:
家用主機秘辛5:數秒內抽換光碟, PS 盜版片也能騙過驗證機制
家用主機秘辛6:最暢銷主機 PS2 的大後門,用壞軌光碟 Swap Magic 破解
「字」在電腦中的型態
在最低階的程式中,主機無法分辨整數(int)、無正負號整數(unsigned int)、浮點數(float)、字元(char,範圍為-128到127)、無正負號字元(unsigned char範圍為0到255),或是其他格式。對於主機而言,這些格式的資料都是一堆由0與1組成的代碼,這些代碼或許是有意義的指令,也可能單純只是資料,無論這些代碼的內容是什麼,都是由人所編寫的程式,告訴主機該如何運作,主機只會在乎代碼的長度是多少,8 bit、16 bit、32 bit或64 bit。
在C語言中,編譯器會事先定義各種型態資料的格式,其最主要的目的就是告訴電腦這些資料的長度,以及該如何應用這些資料,舉個例子來說,16進位的0x61可以代表10進位的整數97,或是字元「a」,而0xFFFFFFFF可以代表數字-1、白色,或是做為指標(雖然很少這樣用)。
由於資料格式的種類相當多,多到C語言會強迫程式開發者定義資料的格式,但是還是免不了開發者誤用這些資料。
▲由於資料會有不同型態,牽涉到該如何使用這些資料,因此C語言規定需要在程式中宣告資料型態。
比較兩邊字串是否相符
Wii會透過硬體進行SHA-1數位簽署的驗證,其效率會比透過軟體驗證高,但是在RSA數位簽署部分,則是會以軟體方式進行驗證。在進行遊戲或各種程式的驗證時,Wii會先替RSA數位簽署解密,得到的內容就是遊戲或程式的hash值,另一方面,Wii也會計算遊戲或程式的hash值,並比對兩者是否相同。
其比對的方法如下:
strncmp(RSAhash, CalculatedHash, n)
上面的指令是標準的C語言函式,它的功能是比較兩個字串的前n個字元是否相等,相等就回傳0,第一個字串大於第二個字串回傳正值,反之回傳負值。這個函式也會被用來避免讀到原本不應該讀到的資料,或是避免資料超出記憶體的存取範圍。
這個函式的功能之一,是當找到空白位元(0x00)時就退出函式。我們換個方式想,既然軟體的hash值是由計算得到,換句話說也就是以整數的格式存在,也就是有可能有「00」混在其中,所以當兩者的hash值包含0x00,後方的資料就不會被檢查到。
想像一下後面的2組hash值:
1a 0b 88 9e 00 5c
1a 0b 88 9e 00 6c
當然,上面2組hash值是不一樣的東西,但是由於strncmp會在遇到「00」之後中斷,所以函式就會回報比較過後2組hash值相同,而不會檢查到「00」之後的資料。
我們當然不想承擔任何風險,所以我們在破解時,只要創造1組開頭是「00」的RSA金鑰,並透過暴力破解法強制創造1組hash值開頭也是「00」的程式(只需修改程式的部分位元,而不破壞整個程式結構),就可以讓所有程式,包括自己所寫的程式通過驗證,此外也可以用一樣的方式,自己修改系統選單、IOS,甚至是Wii的開機程序,並讓它們通過驗證。
這真是千年難得一見的大失誤。
▲使用strncmp進行資料比對的下場,就是很容易被偽造資料矇混過關。
下集預告:又是Bare Metal惹的禍
原文刊載於http://wololo.net/2014/01/20/10-days-of-hacking-day-6-the-wii
感謝原文作者Acid_Snake同意轉載
Original article by Acid_Snake. Translate by konamigood.
請注意!留言要自負法律責任,相關案例層出不窮,請慎重發文!