《iOS 應用逆向與安全》讀後感

by 知識小集 · Lefe_x前端

最近各大「媒體」都在報道《iOS應用逆向與安全》這本書,這是自「小黃書」出版後的又一本關於逆向安全的書。而目前不少 iOS 開發者對逆向還很是「小白」,以致於盲目地以爲逆向很難、很厲害。而這本書的出現,無疑爲逆向這個世界打開了另外一扇窗,咱們一塊兒看看這扇窗裏究竟「藏」了什麼。本文並不打算介紹書中具體細節,只是說明每一章都講了哪些內容,點到爲止。ios

第一章 概述

本章主要對逆向總體進行描述,分別從應用中存在的風險、如何保護應用的安全、和開發工具的使用來介紹。而我以爲本章的核心是掌握逆向的流程和做用,瞭解 APP 開發中須要注意的安全問題。git

逆向流程: 逆向的整個流程基本是相同的,而這些流程能夠總結爲:github

  • 獲取應用的 ipa 包,解密(若是是越獄應用則不須要解密),導出頭文件;
  • 經過界面查看 APP 的佈局,從佈局中找到對應的頭文件,查看關鍵函數;
  • hook 相關函數,達到你的目的;
  • 靜態分析加動態調試分析關鍵函數;
  • 模擬或篡改原有 APP 的邏輯;
  • 達到本身的目的。

**應用場景:**掌握逆向確定很是有用,若是你想從事安全方面的工做,能夠深究,不然沒必要投入太多的精力,畢竟正向開發中不多用到逆向知識。學習逆向知識能夠總結爲:算法

  • 借鑑第三方 APP 的實現思路,好比某個功能是如何實現的、界面使用了哪一類型的 View,數據庫結構是什麼樣的等等;
  • 加深對正向開發的理解,好比 runtime;
  • 普及安全知識,瞭解逆向能夠作什麼後,在開發中你就會知道哪些信息會被別人獲取到,好比某個 APP 根據本地的數據判斷是否可使用付費的資源,這明顯使用逆向便可使用付費資源;

第二章 越獄設備

本章主要講解越獄在逆向中的做用及越獄工具的使用。這裏須要強調一點,逆向不必定須要越獄,而想要更好地掌握逆向的原理,一臺越獄設備是必不可少的。目前市面上不少越獄工具,也提供了一鍵越獄,讀者可自行搜索。數據庫

登陸越獄設備:小程序

手機越獄後,會安裝一個 Cydia 的軟件,它主要用來在越獄手機上安裝各類工具,至關於越獄中的 「App Store」 。想要讀取越獄設備中的資源文件,必須進行遠程登陸。搞服務器的同窗都知道使用 SSH 進行遠程登陸,而登陸越獄設備也可使用 SSH 登陸。經過 Cydia 搜索 OpenSSH 來安裝便可,安裝完後執行:安全

sudo ssh root@手機ip地址
複製代碼

登陸成功便可對越獄設備進行操做了。做者還介紹了其它登陸越獄設備的方式,使用公鑰匙登陸,USB 登陸。bash

文件目錄:服務器

若是想查看設備的文件系統,在 Mac 上可以使用 iFunBox,手機端須要安裝 Apple File Conduit 2 。安裝成功後,便可經過 iFunBox 查看手機的目錄結構,好比安裝的 APP 沙盒目錄,系統自代 APP 的沙盒目錄,各類 Frameworks 等等。

越獄必備工具

  • adv-cmds: 執行 ps 命令報錯,須要安裝這個工具;
  • appsync: 讓系統再也不驗證簽名,以避免安裝應用失敗;
  • iFile:在手機上查看文件目錄;
  • scp:終端命令,把遠程設備的文件複製到另外一個設備;
  • Cydia Substrate:容許第三方開發者在越獄系統的方法中打一些補丁或擴展方法。

第三章 逆向工具詳解

你可能僅僅停留在對這些工具(dumpdecrypted、Clutch、class-dump、Reveal、Cycript、Charles、Wireshark)的使用上,好比我。而做者卻給咱們講解了原理,可見他的功力很深。

dumpdecrypted

AppStore 中的應用都是通過加密的,而逆向的前提須要把加密的內容解密出來。dumpdecrypted 這個工具就是專幹這件事的。固然,若是你不想解密,能夠直接從越獄市場上下載被解密的 APP。不過有時候越獄市場上沒有你要的應用就不得不自行解密了。它的原理引用做者的原話:

dumpdecrypted 是一個開源的工具,它會注入可執行文件,動態地從內存中 dump 出解密後的內容。

Clutch

除了使用 dumpdecrypted 進行解密,Clutch 也能夠作到。不過做者提到使用這個常常會出錯,建議使用 dumpdecrypted。

class-dump

class-dump 的做用是從可執行文件中導出類、方法、屬性信息的工具,這裏須要強調一下可執行文件,被解密的 APP 應用中會有一個可執行文件(Mach-O)。能夠從 xxx.app 中的 info.plist 文件找到 Executable file 它的值便是 xxx.app 的可執行文件。使用 MatchOView 能夠查看 Mach-O 文件。

導出 We.app 的頭文件:

class-dump -H ~/Desktop/reverse/ipa/We.app -o ~/Desktop/reverse/header/we
複製代碼

Reveal

是用來查看APP界面的工具,查看第三方 APP 不必定非用越獄設備。

Cycript

Cycript 是一個容許開發者使用 Objective-C++ 和 JavaScript 組合語法查看及修改運行時 APP 的內存信息的工具。在逆向中主要用來驗證某些猜想是否正確,查看界面信息等。好比查看當前顯示的 VC,某個對象執行某個函數後的結果,動態修改某個 UI 的信息。

Charles、Wireshark

介紹了這兩個抓包工具的使用。

第四章 開發儲備

這一章主要介紹正向開發的一些知識,而這些知識對逆向開發很重要。

ipa 包

獲取應用的 ipa 包,主要能夠經過兩種方式獲取:

  • 從 iTunes 中獲取,目前的 iTunes 中已不支持,須要下載低版本的 iTunes。 下載
  • 直接從越獄設備獲取,其實直接從各類助手中無需越獄設備便可下載越獄應用,獲取到 ipa 包;

應用包的構建過程:

  • compile:使用 Clang 編譯源文件;
  • link:將編譯生成的目標文件連接成一個可執行文件;
  • storyboard:編譯項目中的 storyboard 文件;
  • plist:生成 plist 文件;
  • asset:將須要的資源文件複製到 App 目錄下;
  • dsym:生成符號文件;
  • codesign:對 App 進行簽名;
  • package:打包。

界面與事件傳遞

介紹了 iOS 中的 UI 、事件傳遞和事件響應。

類與方法

主要介紹了類的底層實現,OC 中的消息機制,runtime 的一些使用場景。

App簽名

正向開發中,每一個同窗都會經歷一次蘋果的證書配置。而做者在這裏主要講解了 App 簽名的原理,這樣爲逆向重簽名作好鋪墊。

第五章 分析與調試

前面四章主要爲後四章作一個鋪墊,從接下來的章節中正式開啓了逆向。本章主要從靜態分析和動態調試來介紹逆向。

靜態分析,指在不容許 App 的前提下對程序分析的一種方法。通常有如下幾種方式:

  • 基於 ipa 和 app 包;
  • 基於文件格式;
  • 基於二進制反彙編;

反彙編

反彙編主要有兩個工具:HopperIDA。而這兩個工具能夠查看源代碼實現的彙編代碼,關鍵還能夠查看僞代碼。之前一直以爲 Hopper 很差用就沒用,今天下載了一個用起來發現比 IDA 用着舒服。

Hopper 只支持 Mac 和 Linux,相對於 IDA 比較弱一些。而 IDA 支持 Windows 平臺。

靜態庫分析

有時候想看某個靜態庫的實現,其實也可使用 Hopper 查看他的彙編代碼。

➜  5.1 靜態分析 ls
Crashlytics UserLogin
➜  5.1 靜態分析 lipo -info Crashlytics
Architectures in the fat file: Crashlytics are: armv7 armv7s i386 x86_64 arm64
➜  5.1 靜態分析 lipo Crashlytics -thin arm64 -output Crashlytics_arm64
➜  5.1 靜態分析 mkdir Objects
➜  5.1 靜態分析 cd Objects
➜  Objects ar -x ../Crashlytics_arm64
➜  Objects grep "Upload" -rn ./
Binary file .//CLSReportsController.o matches
Binary file .//CLSCrashReportingController.o matches
Binary file .//CLSNetworkClient.o matches
➜  Objects otool -l Crashlytics.o|grep bitcode
  sectname __bitcode
➜  Objects ld -r -arch arm64 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -bitcode_bundle ./*.o -o ../output
複製代碼

動態調試

動態調試是在程序運行的時候執行一系列操做,好比獲取某個對象的值,執行上下文等。

LLDB 動態調試:正向開發中常會使用到 LLDB 來調試程序,而在逆向中它也發揮很大做用。

用 Xcode 調試第三方應用:使用 Xcode 在非越獄設備中調試第三方應用、進行符號的還原、查看帶符號的堆棧調用。不過調試的時候須要一個第三方應用。

Theos

越獄開發中除了 Thoes 外還有一個叫 iOSOpenDev 的工具,功能和 Thoes 是同樣的,不一樣點是iOSOpenDev 是整合到 Xcode 中使用的,而 MonkeyDev 和 iOSOpenDev 屬於同一類型的工具。

MonkeyDev

MonkeyDev 是做者開發的一個工具,主要用 Xcode 進行越獄開發。具體使用能夠查看 MonkeyDev 的 wiki 。

第六章 逆向進階

這一章,看着比較吃力。不少都沒接觸到,這裏簡單的作個介紹,若是之後用到這部份內容再繼續深究。

程序加載

在程序執行 Main 函數以前,都作了哪些事。

Mach-O 文件格式

對於每一個 ipa 包,都會包含一個可執行文件,而這個文件就是 Mach-O 文件。

ARM 彙編

逆向若是想看懂代碼,那麼必須學會彙編。

hook

hook 直譯爲 鉤子,經過 hook 能夠改變程序執行邏輯。hook 最多見的有如下三種方式:

  • MethodSwizzle:

經過 runtime 交換方法的實現。

  • fishhook:

fishhook 是 facebook 開源的一個庫。

A library that enables dynamically rebinding symbols in Mach-O binaries running on iOS.

  • Cydia Substrate:

動態庫

特色:

  • 存在形式有 .dylib,.framework 和連接符號 .tdb;
  • 它的格式和普通二進制文件沒有區別;
  • 它的好處是能夠只保留一份文件和內存空間,從而可以被多個進程使用,例如系統動態庫;
  • 可減少可執行文件的體積,不須要連接到目標文件。

在逆向中會常常用到動態庫,好比使用 Reveal 調試第三方應用時須要把 RevealServer. framework 注入到 APP 程序中。能夠經過引入頭文件的方式調用 和 dlopen 動態加載的方式調用動態庫。

第七章 實戰演練

這章主要應用前幾章學到的知識。而逆向開發能夠在越獄設備和非越獄設備中開發。

越獄設備

目標是給 WhatsApp 長按消息添加一個收藏菜單,並在設置中添加已收藏的消息。分別在越獄設備、非越獄設備進行分析。

  • 下載 WhatsApp 使用 dumpdecrypted 解密;
  • 使用 class-dump 導出頭文件,導出頭文件時加上 -A 參數能夠顯示方法在文件中的實現地址;
  • 符號還原,方便後續使用 lldb 進行調試;
  • 分析某個應用時,須要從界面入手,使用 Reveal 查看界面的層級結構,定位到具體的視圖控制器,從頭文件找到對應的方法;
  • 根據找到的方法,使用 lldb 添加斷點,驗證是否會調用對應的方法,以肯定是否爲須要找的方法;
  • 使用 Hopper 查看僞代碼,猜想具體的實現方式;

非越獄設備

目標是給 WhatsApp 添加自動回覆功能。越獄設備分析有諸多繁瑣的工做,好比導出頭文件,使用 Reveal,使用 LLDB 調試不方便等。因此做者把這些功能都集成到了 MonkeyDev 這個工具中,經過 MonkeyDev 新建工程將自動集成 class-dump、符號還原、Reveal、Cycript、注入動態庫、自動重簽名等一系列重複性的工做,能夠直接在非越獄設備上進行逆向分析。具體使用參考

Frida 實戰應用

Frida 是一款跨平臺的注入工具,經過注入 JS 與 Native 的 JS 引擎進行交互,從而執行 Native 的代碼進行 hook 和動態調用。這個工具能夠用於 Android 和 iOS,它能夠經過一段 JS 來調試應用。

第八章 安全保護

前面講了這麼多能夠調試別人的 App 如同調試本身的同樣,這就須要在開發的過程當中來保護咱們本身的 App 免受攻擊,重要的數據須要進行加密處理。而本章主要講有哪些手段能夠保護咱們的 App 儘量的不被破解。主要採用的手段有:

- 數據加密:靜態字符串、本地存儲及網絡傳輸加密

不論是本地的數據仍是網絡中傳輸的數據,對敏感數據須要採用加密算法進行加密處理,而經常使用的加密算法有 AES,RSA。對於網絡傳輸的數據可使用 AES+RSA 的方式對數據進行加密,若是使用 Https 的方式須要對證書進行校驗。而對於一些常量字符串有時候也須要加密處理,以防止被靜態分析。這裏做者提使用 libclang 方式,具體 源碼

- 靜態混淆:類名、方法名、屬性的混淆;

使用 class-dump 導出的頭文件很容易根據名字知道某個類,方法的做用,這時候須要對類名,方法名進行混淆。第一種方法:經過宏定義混淆,在 pch 文件中好比這樣寫 #define MyClass 89s343ss。網上有一個開源的庫 ios-class-guard。第二種方法:二進制修改,修改可執行文件的 __obj_classnameobjc_methname

- 動態保護:反調試、注入檢測、hook 檢測,越獄檢測、簽名檢測等;

雖然靜態混淆後不能猜到類名方法名的做用,可是若是採用動態的方式仍是能知道某些方法的參數、以及加密後的數據等。這就是要防動態調試。

  • 反調試:主要經過阻止調試去附加和檢測調試器是否存在。主要有 ptrace、sysctl、syscall、ARM 等方式;
  • 反反調試:過濾掉反調試機制;
  • 反注入:檢測當前有沒有其它模塊注入;
  • hook 檢測:檢測是否被惡意的 hook 掉了;
  • 完整性校驗:load command、代碼校驗、重簽名校驗;

- 代碼混淆:提升分析難度

未混淆的代碼能夠經過 Hopper 和 IDA 等彙編工具獲得彙編代碼,甚至能夠獲得對應的僞代碼。爲了提升分析難度,須要對代碼進行混淆。混淆主要經過 LLVM。

知識小集是一個團隊公衆號,主要定位在移動開發領域,分享移動開發技術,包括 iOS、Android、小程序、移動前端、React Native、weex 等。每週都會有 原創 文章分享,咱們的文章都會在公衆號首發。歡迎關注查看更多內容。

相關文章
相關標籤/搜索