iOS越獄之程序獲得root權限

正常途徑下, 我們編寫的程序發佈在App store上, 使用官方規定的SDK. 但有些時候, 正常途徑實現不了的功能, 可以在破解的iphone上面實現. 以cydia上文件管理軟件iFile爲例, iFile可以修改系統的任何文件, 這需要iFile具有root權限, 在iphone沒有破解的情況之下, 是無論如何都實現不了的.  我個人並不支持破解, 但之前接到個任務編寫的一個程序只要求運行在破解了的iphone上, 以cydia方式發佈, 並要有root權限, 就研究了一下. 

對於iphone系統, 有兩個目錄會安裝應用程序
1. /Application 
2. /var/mobile/Applications

/var/mobile/Applications下的應用程序會有很多限制, 似乎系統會認爲此目錄下的程序一定會運行在沙盒中, 不管怎麼設置權限也無用. /Application目錄下的程序限制會小一些, 要取得root權限, 第一步就是要將程序安裝在/Application目錄下.

幸好有cydia. 系統破解之後, 絕大多數都會安裝上cydia. 自己搭建cydia源, 第三方軟件也可以通過cydia來發布. 搭建cydia源中有一步是將編譯出的程序打包成deb. 打包的時候, 可以指定最終安裝後的目錄結構. 至於如何搭建cydia源, google一下會有詳細的教程, 這裏不多說, 下面已假設可以將程序安裝在/Application目錄下.

先簡單複習一下unix的權限管理, iOS系統其實是個小的unix.
unix下面每個文件都有自己所屬, 和訪問權限.
比如用戶complex_ok是組mobile的成員, 他登錄的時候創建了一個文件A, 默認下, A就屬於用戶complex_ok, 組爲mobile.
另外文件A還可以指定自己的訪問權限, 分成用戶, 組, 其它人三個級別, 三個級別都可以指定自身的 是否可讀, 是否可寫, 是否可執行. 

比如 文件A屬於用戶complex_ok, 組爲mobile
它的訪問權限指定爲 用戶可讀可寫可執行, 組可讀可寫, 其他人爲只讀.

這個時候用戶complex_ok登錄的時候, 可以執行文件A, 如果用戶HelloKitty, 也屬於組mobile, HelloKitty對文件A可以進行讀寫, 但不可以執行, 而其它非同組的人, 就只讀.

當我們使用iphone的時候, 我們實際上是以用戶mobile, 組mobile的身份登錄的. 當某文件屬於root用戶, 權限設爲組和其它人都只讀, 正常時候就不能修改這文件.
幸好unix還可以爲文件的訪問權限指定setuid位, 這個位很重要
比如可執行程序A, 程序也是文件, 程序A是屬於root用戶的. 假設用戶mobile運行程序A, 如果沒有爲程序A設置setuid位, 程序A是以用戶mobile的權限運行. 如果指定了setuid位, 就算用戶是mobile, 並非root, 但因爲程序A是屬於root用戶的, 程序A也可以以root的權限運行.

明白setuid位的作用, 似乎取得運行root權限的程序就很簡單了. 比如我們也想編寫自己的文件管理程序aFile, 使aFile也運行在root權限, 我們就將aFile程序的修改成屬於root用戶, 再將權限位設置成可執行, 並有setuid位. 使用cydia將程序安裝到/Application, 用戶點擊iFile的圖標, 這樣iFile就以root權限運行了.

想法是好的, 但是這樣還不行. 當用戶點擊程序的圖標時, 是通過iphone系統調用程序的, iphone系統會有一個安全檢查, 它會檢查到程序將以root權限運行應用程序, 就不會執行, 你會看到程序閃一下, 就被結束了. 

所以我們還需要一個間接層, 編寫一個引導程序A, 再通過A調用B.
首先將A的權限設置爲其它人可讀可執行, B的所屬設置爲root, 權限設置爲其它人可讀可執行, 並有setuid爲.
當用戶點擊圖標, iphone系統調用程序A, 它判斷出程序A並沒有root權限, 正常執行, 程序A這時候去調用B, 因爲B是A調用的, 程序A是我們自己寫的, 並不做安全檢查, 這樣B有setuid位之後, 所屬爲root, 就可以以root執行了.

那如何使iphone系統調用引導程序A而不是調用正常程序B呢? 很簡單, 改改名字就可以了.
比如你建立的工程爲aFile, 正常編譯出一個aFile.app文件, 右鍵, 顯示包內容, 將裏面的可執行文件aFile, 修改名字爲aFile_, 再將你的引導程序改成aFile, 這樣安裝之後, 點擊圖標系統就會自動調用你的引導程序. 引導程序的編寫很簡單, 大體爲
int main(int argc, char *argv[]) 
{
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
       NSString* string = [[NSBundle mainBundle] pathForResource:@"aFile_" ofType:nil];

    argv[0] = (char*)[string UTF8String];
    execve([string UTF8String], argv, NULL);
    
        [pool release];
        return 0;
}

取得root權限後, 就可以做很多事情了, 你的程序編寫時候也要小心一點.

在打包成deb時候, 可以用腳本自動修改文件權限和所屬.
權限修改的命令爲chmod, 所屬修改的命令爲chown.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章