iOS應(yīng)用代碼注入防護

在應(yīng)用開發(fā)過程中祝谚,我們不僅僅需要完成正常的業(yè)務(wù)邏輯宪迟,考慮應(yīng)用性能、代碼健壯相關(guān)的問題交惯,我們有時還需要考慮到應(yīng)用安全的問題次泽。
那么應(yīng)用安全的問題涉及到很多方面。比如防止靜態(tài)分析的席爽,代碼混淆意荤、邏輯混淆;防止重簽名的拳昌,應(yīng)用ID檢測袭异、甚至是代碼的HASH檢測等等钠龙。那么這篇文章我想聊聊關(guān)于代碼的注入檢測炬藤,因為發(fā)現(xiàn)隨著iOS系統(tǒng)的更新,我們防護的手段發(fā)生了一些變化。

代碼注入的方式

代碼注入的方式大致分為兩種

  • 越獄注入:通過修改DYLD_INSERT_LIBRARIES 環(huán)境變量的值,來插入動態(tài)庫并執(zhí)行
  • 非越獄注入:
    • 直接將自定義的Framwork或者dylib庫打包進入APP并重簽名碴里。
    • 利用yololib修改MachO文件,添加庫路徑.在應(yīng)用啟動時,dyld會加載并執(zhí)行.

早期防護方式

在工程的Build Settings中找到Other Linker Flages 并添加字段
-Wl,-sectcreate,__RESTRICT,__raestrict,/dev/null
此操作的作用是在可執(zhí)行文件中添加一個Section.我們使用MachOView分析如下:

MachOView

當MachO文件中擁有這個字段,那么我們通過越獄環(huán)境插入動態(tài)庫的方式就會失效.起到防護的作用.其原理在DYLD源碼中可以分析到.

dyld源碼分析

首先這里分析的DYLD源碼版本是519.2.2版本.
我們可以通過檢索DYLD_INSERT_LIBRARIES定位到_main函數(shù)加載插入動態(tài)庫的代碼如下.

            // load any inserted libraries
        if  ( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {
            for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) 
                loadInsertedDylib(*lib);
        }

但是早在這個環(huán)境變量判斷之前,dyld已經(jīng)做了一個判斷

    if ( gLinkContext.processIsRestricted ) {
        pruneEnvironmentVariables(envp, &apple);
        // set again because envp and apple may have changed or moved
        setContext(mainExecutableMH, argc, argv, envp, apple);
    }

如果判斷出進程是restricted!也就是當前進程是限制插入動態(tài)庫的!就會調(diào)用pruneEnvironmentVariables函數(shù)移除相關(guān)的環(huán)境變量.
那么我們的processIsRestricted值什么時候為true呢?
繼續(xù)分析源碼可以發(fā)現(xiàn)兩個關(guān)鍵函數(shù)影響其值.其中 hasRestrictedSegment 函數(shù)專門檢測RESTRICT段

// any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
    if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {
        gLinkContext.processIsRestricted = true;
    }

通過注釋也能發(fā)現(xiàn).任意進程的__RESTRICT段設(shè)置為restricted動態(tài)庫插入將被限制.
我們進入到processIsRestricted函數(shù)內(nèi),實現(xiàn)如下.

#if __MAC_OS_X_VERSION_MIN_REQUIRED
static bool hasRestrictedSegment(const macho_header* mh)
{
    const uint32_t cmd_count = mh->ncmds;
    const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));
    const struct load_command* cmd = cmds;
    for (uint32_t i = 0; i < cmd_count; ++i) {
        switch (cmd->cmd) {
            case LC_SEGMENT_COMMAND:
            {
                const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;

                //dyld::log("seg name: %s\n", seg->segname);
                if (strcmp(seg->segname, "__RESTRICT") == 0) {
                    const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));
                    const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];
                    for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                        if (strcmp(sect->sectname, "__restrict") == 0) 
                            return true;
                    }
                }
            }
            break;
        }
        cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
    }

    return false;
}

所以通過添加Other Linker Flags 在MachO中設(shè)置RESTRICT段賦值為restricted可以用來防護越獄的代碼注入.
但是新版的dyld源碼中去掉了__RESTRICT檢測.從iOS10開始,這種防護手段已失效

小編給大家推薦一個iOS技術(shù)交流群:551346706沈矿!群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法、底層進階咬腋、swift羹膳、逆向、底層面試題整合文檔等免費資料根竿!

DYLD_INSERT_LIBRARIES 檢測

那么既然dyld加載過程不再檢測__RESTRICT段了我們就手動的檢測DYLD_INSERT_LIBRARIES環(huán)境變量.通過函數(shù)可查看當前進程環(huán)境變量的值.

  char *env = getenv("DYLD_INSERT_LIBRARIES");
  NSLog(@"%s",env);

在沒有插入動態(tài)庫時,env為null.
那么一旦為自己的應(yīng)用寫入插件時,我們就可以看到控制臺的輸出

2019-01-03 19:20:37.285 antiInject[7482:630392] /Library/MobileSubstrate/MobileSubstrate.dylib

白名單檢測

那么上面的檢測只可以檢測越獄環(huán)境中的代碼注入,在非越獄環(huán)境中,逆向工程師可以利用yololib工具注入動態(tài)庫.所以我們可以檢索一下自己的應(yīng)用程序所加載的動態(tài)庫是否是我們源程序所有

bool HKCheckWhitelist(){

    int count = _dyld_image_count();
    for (int i = 0; i < count; i++) {
        //遍歷拿到庫名稱陵像!
       const char * imageName = _dyld_get_image_name(i);
        //判斷是否在白名單內(nèi),應(yīng)用本身的路徑是不確定的,所以要除外.
        if (!strstr(libraries, imageName)&&!strstr(imageName, "/var/mobile/Containers/Bundle/Application")) {
            printf("該庫非白名單之內(nèi)!寇壳!\n%s",imageName);
            return NO;
        }
    }
    return YES;
}

其中l(wèi)ibraries變量是<q style="box-sizing: border-box;">白名單</q>.

小編給大家推薦一個iOS技術(shù)交流群:551346706醒颖!群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法、底層進階壳炎、swift泞歉、逆向、底層面試題整合文檔等免費資料!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腰耙,一起剝皮案震驚了整個濱河市榛丢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挺庞,老刑警劉巖晰赞,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異选侨,居然都是意外死亡宾肺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門侵俗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锨用,“玉大人,你說我怎么就攤上這事隘谣≡鲇担” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵寻歧,是天一觀的道長掌栅。 經(jīng)常有香客問我,道長码泛,這世上最難降的妖魔是什么猾封? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮噪珊,結(jié)果婚禮上晌缘,老公的妹妹穿的比我還像新娘。我一直安慰自己痢站,他們只是感情好磷箕,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阵难,像睡著了一般岳枷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呜叫,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天空繁,我揣著相機與錄音,去河邊找鬼朱庆。 笑死盛泡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的椎工。 我是一名探鬼主播饭于,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼蜀踏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掰吕?” 一聲冷哼從身側(cè)響起果覆,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎殖熟,沒想到半個月后局待,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡菱属,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年钳榨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纽门。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡薛耻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赏陵,到底是詐尸還是另有隱情饼齿,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布蝙搔,位于F島的核電站缕溉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吃型。R本人自食惡果不足惜证鸥,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勤晚。 院中可真熱鬧枉层,春花似錦、人聲如沸运翼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽血淌。三九已至,卻和暖如春财剖,著一層夾襖步出監(jiān)牢的瞬間悠夯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工躺坟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沦补,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓咪橙,卻偏偏與公主長得像夕膀,于是被迫代替她去往敵國和親虚倒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 在應(yīng)用開發(fā)過程中产舞,我們不僅僅需要完成正常的業(yè)務(wù)邏輯魂奥,考慮應(yīng)用性能、代碼健壯相關(guān)的問題易猫,我們有時還需要考慮到應(yīng)用安全...
    iOS猿_員閱讀 3,045評論 1 4
  • 1 dyld 1.1 dyld簡介 在iOS系統(tǒng)中耻煤,幾乎所有的程序都會用到動態(tài)庫,而動態(tài)庫在加載的時候都需要用d...
    Kevin_Junbaozi閱讀 11,805評論 4 44
  • layout: wikititle: iOS逆向分析筆記categories: Reverse_Engineeri...
    超哥__閱讀 10,716評論 3 16
  • [TOC] 修改系統(tǒng)應(yīng)用 目標:消除對手機桌面的提醒氣泡 通過cycript分析氣泡連接手機并登陸准颓,通過進程列表指...
    _順_1896閱讀 1,832評論 0 3
  • Cycript 找到當前界面上的所有對象 通過控件的 nextResponder 查找視圖控制器 打印當前控制器下...
    7c205247047d閱讀 1,580評論 0 1