閱讀903 返回首頁    go iPhone_iPad_Mac_apple


在iOS應用程序中使用Frida繞過越獄檢測

 您當前的位置: 安全博客 >  技術研究 >  在iOS應用程序中使用Frida繞過越獄檢測


         阿裏聚安全在之前的三篇博客中介紹了利用Frida攻擊Android應用程序,整個過程仿佛讓開發者開啟上帝視角,在本篇博客中,我們將會介紹在iOS應用程序中使用Frida繞過越獄檢測。即使你從來沒有使用過Frida,這篇文章也將會作為進入移動安全開發和分析的入門指南。


相關文章內容:

利用FRIDA攻擊Android應用程序(一)

利用FRIDA攻擊Android應用程序(二)

利用FRIDA攻擊Android應用程序(三)

一、Frida介紹

Frida是一個可以hook App的動態代碼工具包,可以向Windows、macOS、Linux、iOS、Android和QNX的本機應用程序中注入JavaScript或自己的庫代碼。最開始的時候,它是基於穀歌的V8 Javascript運行,但是從版本9開始,Frida已經開始使用其內部的Duktape運行。



列舉一些Frida的使用場景:

1、hooking特定函數並更改返回值

2、分析定製協議,同時其動態嗅探/解密

3、應用調試

4、在iOS應用上dump 類和方法信息


Firda眾多不同的使用場景,花樣繁多的啟動方式,包括各種強大的API和方法,讓它成為開發者建立自己安全分析的首選工具。它可以使用命令行界麵或類似frida-trace的工具來跟蹤底層函數。同時還可以使用C、NodeJS或Python綁定完成更複雜的任務。但是在其內部,Frida使用Javascript的時候較多,可以通過JavaScript完成大部分的工作。


Frida之所以如此的能對安全檢測如此有用,就是因為它能夠在非越獄的設備上運行。 Frida提供了一個叫做“FridaGadget.dylib”的動態庫,可以用來在未越獄設備上為應用程序插入FridaGadget.dylib。開發者可以使用Swizzler2等工具來修改應用程序以在應用程序中添加FridaGadget.dylib。


iOS係統下,已有幾種基於Frida的安全分析工具,例如Needle和AppMon。

Needle是一個開源的模塊化框架,主要簡化iOS應用程序安全評估過程,並作為一個中心點。鑒於其模塊化方法,Needle很容易擴展新模塊,可以以Python腳本的形式加入。

地址:https://github.com/mwrlabs/needle


AppMon是監測和修改本地macOS、iOS、Android係統API的自動化框架,並能通過web接口顯示和操作

地址:https://github.com/dpnishant/appmon



二、在iOS上的設置Frida

設置步驟十分簡單,開發者同時在iOS設備和電腦上設置安裝Frida。

在iOS設備安裝步驟如下:

1、在iOS設備中打開Cydia APP

2、添加URL地址:https://build.frida.re




3、打開Source或搜索Frida,點擊Modify,然後安裝。




4、打開終端並輸入pip install frida來安裝Frida綁定, 當然你還可以使用python、C或NodeJS綁定來完成更複雜的任務


三、使用Frida連接iOS進程

完成Frida所有設置後,開始對iOS應用安全評估和利用之旅。

Damn Vulnerable iOS Application(DVIA)作為本次的測試方法,地址:https://damnvulnerableiosapp.com/

下文涉及的代碼,GitHub地址:https://github.com/interference-security/frida-scripts/tree/master/iOS


我們將從DVIA中分析越獄檢測操作,當前設備已顯示越獄。




首先查看目標設備的所有運行進程列表

frida-ps –U


 

從上麵的截圖可以看到所有在iOS設備上運行的進程。

輸入frida –U process-name即可附加到任一進程,在Frida控製台獲取目標進程的屬性,內存和函數。


現在我們可以在Frida的shell中工作,它可以與我們的iOS進程進行交互,也可以編寫JavaScript來獲取我們想要的分析數據


四、Dump 類和方法信息

這個步驟是用於識別哪個ViewController和function負責驗證iOS設備是否越獄


ViewController是iOS應用程序中重要的部分,是應用程序數據和視圖之間的重要橋梁,ViewController管理應用中的眾多視圖。 iOS的SDK中提供很多原生ViewController,以支持標準的用戶界麵,例如表視圖控製器(UITableViewController)、導航控製器(UINavigationController)、標簽欄控製器(UITabbarController)和iPad專有的UISplitViewController等。


先寫一個基礎的Frida腳本來dump目標應用程序中所有的class文件和method信息。開始尋找任何和越獄相關的內容,以便我們在Frida的幫助下繞過越獄檢測。


進程示意圖如下:



1、在DVIA中使用Frida尋找越獄檢測的類

先來看看應用程序中所有的class文件

for (var className in ObjC.classes)

    {

        if (ObjC.classes.hasOwnProperty(className))

        {

            console.log(className);

        }

}


運行腳本,我們就會看到Frida附加到目標進程,一旦加載完成,它將在目標進程中顯示出許多class文件。

使用grep命令來找到相關的class文件是比較好的辦法。當我們運行grep Jailbreak的命令時,我們就會看到一個名為JailbreakDetectionVC的類,如下圖所示




在找到所有實例之後,會看到一個safe to ignore的錯誤聲明。因此首要任務就是尋找目標類,找出此類中任何相關的方法,這是一個有趣的過程。


2、在DVIA中使用Frida尋找越獄檢測的方法

使用ObjC.classes.class-name.$methods,此例中隻需在我們的目標類-JailbreakDetectionVC,找到該方法。

console.log("[*] Started: Find All Methods of a Specific Class");

if (ObjC.available)

{

    try

    {

        var className = "JailbreakDetectionVC";

        var methods = eval('ObjC.classes.' + className + '.$methods');

        for (var i = 0; i < methods.length; i++)

        {

            try

            {

                console.log("[-] "+methods[i]);

            }

            catch(err)

            {

                console.log("[!] Exception1: " + err.message);

            }

        }

    }

    catch(err)

    {

        console.log("[!] Exception2: " + err.message);

    }

}

else

{

    console.log("Objective-C Runtime is not available!");

}

console.log("[*] Completed: Find All Methods of a Specific Class");


繼續運行,運行grep檢索例如Jailbreak、Jailbroken、detection的字符串,如下圖所示




我們找到isJailbroken、jailbreakTest1Tapped:、jailbreakTest2Tapped:的3種字符串,符合上檢索目標。其中,isJailbroken看起來最像檢測設備是否越獄並返回值的函數。


3、在DVIA中使用Frida修改越獄檢測方法的返回值

查看isJailbroken發送的返回值

{

    try

    {

        var className = "JailbreakDetectionVC";

        var funcName = "- isJailbroken";

        var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');

        Interceptor.attach(hook.implementation, {

          onLeave: function(retval) {

            console.log("[*] Class Name: " + className);

            console.log("[*] Method Name: " + funcName);

            console.log("\t[-] Type of return value: " + typeof retval);

            console.log("\t[-] Return Value: " + retval);

          }

        });

    }

    catch(err)

    {

        console.log("[!] Exception2: " + err.message);

    }

}

else

{

    console.log("Objective-C Runtime is not available!");


運行腳本,在iOS應用中按下Jailbreak Test 1按鈕,我們可以在Frida控製台看到返回值

因為設備已經越獄,顯示的返回值為0*1,意味著返回函數True。


接下來我們的任務是覆蓋返回值並修複方法,以便每當按下Jailbreak Test 1按鈕的時候,返回值為false或0*0。


我們添加另一行來改變這個特定函數的返回值。通過下麵的代碼來實現,並將其記錄到控製台。

newretval = ptr("0x0")

retval.replace(newretval)

console.log("\t[-] New Return Value: " + newretval)


最終腳本如下:

if (ObjC.available)

{

    try

    {

        var className = "JailbreakDetectionVC";

        var funcName = "- isJailbroken";

        var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');

        Interceptor.attach(hook.implementation, {

          onLeave: function(retval) {

            console.log("[*] Class Name: " + className);

            console.log("[*] Method Name: " + funcName);

            console.log("\t[-] Type of return value: " + typeof retval);

            console.log("\t[-] Original Return Value: " + retval);

            newretval = ptr("0x0")

            retval.replace(newretval)

            console.log("\t[-] New Return Value: " + newretval)

          }

        });

    }

    catch(err)

    {

        console.log("[!] Exception2: " + err.message);

    }

}

else

{

    console.log("Objective-C Runtime is not available!");

}


一旦運行腳本,我們看到返回值已經修改



查看iOS的APP,可以看到設備顯示未越獄




---------------------------------------------------------

本文由Douglas編譯自attify,原文地址:https://blog.attify.com/2017/05/06/bypass-jailbreak-detection-frida-ios-applications/

更多移動安全類知識幹貨,請持續關注阿裏聚安全的博客

最後更新:2017-05-11 15:31:15

  上一篇:go  使用快照策略和鏡像備份數據
  下一篇:go  如何利用Redis擴展數據服務、實現分片及高可用?