在未root的裝置上使用frida
轉自:https://bbs.pediy.com/thread-229970.htm
在這篇教程中我們可以學會怎麼在未root裝置上使用Frida gadget。
指令碼和工具在這裡:materials
作者Romain Thomas - @rh0main
最近幾年,Frida已經成為這一行業進行hook的首選工具。它使用起來快速,靈活,且支援跨平臺。
大部分時候在root過後的裝置上使用Frida並沒有什麼限制,但某些場景中有些app可能會檢測執行環境。
@ikoz在他的博文Using Frida on Android without root中提到了一種修改Dalvik位元組碼的方法,以實現在未root裝置上使用Frida。在這篇教程中我們提出了一種不需要修改Dalvik位元組碼的新方法。(即classes.dex
Frida Gadget
在預設模式下,Frida需要在目的應用程式中注入一個代理以訪問目標進行的記憶體空間。
在Android和Linux中這種注入使用到了ptrace
。它通過附加或啟動一個程式,然後注入對應的代理程式。在代理程式被注入後,它通過管道和伺服器進行通訊。
有些注入需要許可權。比如,我們不能使用普通使用者呼叫ptrace
。為了解除這個限制,Frida提供了另一種模式,叫作“embedded”。在這一模式中,使用者需要注入frida-gadget庫。
這種注入需要:
- 環境變數:
LD_PRELOAD
,DYLD_INSERT_LIBRARIES
... - 使用
dlopen
- 在開源的目標中,使用linker連結frida-gadget.
-
...
要獲取關於Frida gadget的更多資訊,可以看官方文件:frida-gadget
Frida和LIEF
有一種不那麼出名但非常古老的注入技術是通過修改ELF格式。Mayhem 在Phrack詳細解釋了這一技術的原理,而LIEF(譯者注:LIEF,本文作者實現的一個庫)提供了一種使用者友好的API來實現。
簡而言之,可執行檔案格式包含了連結在可執行檔案上的庫。我們可以使用ldd
或readelf
(Unix)列出這些庫,或者是使用elf_reader.py(Linux, Windows, OSX):
1 2 3 4 5 6 7 |
|
在這裡/bin/ls
有兩個依賴:
libcap.so.2
libc.so.6
當可執行檔案載入的時候,載入器會遍歷這些庫,並把它們對映到程序到的記憶體空間中去,並在載入之後呼叫它的構造方法。
這一想法的原理是新增frida-agent.so
作為APK的native庫的依賴。
新增這個依賴的程式碼非常簡單,像下面這樣:
1 2 3 4 5 |
|
Telegram
為了解釋這個程序,我們會注入frida gadget到Telegram這個應用中。Telegram是個好玩的目標,因為:
- 它只包含一個native庫,這樣庫就會早點被載入。
- 它表明了LIEF修改LEF檔案的可靠性
- 這是個真實的app
關於環境,軟體是Telegram的4.8.4-12207
版本(2018.2.18),系統是在Android 6.0.1上,架構是Samsung Galaxy S6的AArch64架構。
注入LIEF
正如上面解釋的,注入過程只需要在libtmessages.28.so
上呼叫lief.ELF.Binary.add_library()
。
在注入之前,libtmessages.28.so
與下列庫相連結:
1 2 3 4 5 6 7 8 9 10 11 |
|
在執行了telegram.add_library("libgadget.so")
這條語句後,在第一個位置上,我們有了一條新的依賴。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
配置Frida Gadget
根據文件我們可以知道,Frida Gadgets可以使用配置檔案作為引數來進行互動。
- Listing:互動和frida-server一樣
- Script:使用配置檔案中指定的JS指令碼進行互動
- ScriptDirectory:和Script一樣,但可以指定多個應用和多個指令碼
Listing互動方式需要android.permission.INTERNET
許可權。我們可以通過修改manifest檔案新增這個許可權。不過,如果我們使用的是Script這種互動方式就不需要這一許可權。
Frida payload會定位到/data/local/tmp/myscript.js
檔案,gadget配置檔案的配置如下:
1 2 3 4 5 6 7 |
|
使用配置配置檔案必須遵循兩個條件:
- 檔案必須和gadget庫同名(例如:
libgadget.so
和libgadget.conf
) - 配置檔案必須和gadget庫位於同一目錄中
第二個要求也就意味著在裝置中安裝之後,gadget庫會會在/data/app/org.telegram.messenger-1/lib
目錄中尋找配置檔案。
在安裝app之後,當滿足下述條件時,Android包管理器會從APK的lib/
目錄中複製檔案:
- 名字具有
lib
字首 - 名字具有
.so
字尾 - 名字是
gdbserver
Frida 實現這些要求的原始碼如下。因此我們只需要給libgadget.conf
新增.so
字尾就行了。
1 2 3 4 5 6 7 8 9 10 |
|
最終,新的Telegram的.apk
的lib
目錄結構如下:
1 2 3 4 5 6 |
|
libtmessages.28.so
連結到了libgadget.so
執行
在滿足下述要求後:
- 對
libtmessages.28.so
的注入完成 - gadget庫及其配置檔案放在
/lib/ABI
目錄下 - 應用程式重新簽名
安裝new.apk
這個重新打包的APK,並把myscript.js
放在/data/local/tmp
目錄下:
1 2 3 |
|
這篇教程中用到的Frida指令碼myscript.js
只實現了一個對Android log函式呼叫的功能:
1 2 3 4 5 6 7 8 |
|
myscript.js
最後,我們就可以執行telegram程式並檢視它的Android日誌了。
1 2 3 4 |
|
總結
在這篇教程中我們看到了靜態插樁和動態插樁的結合方法。
下面是這一技術的優/缺點
優點:
- 不需要root
- 不依賴frida-server
- 可用於繞過anti-frida
- 不需要修改
AndroidManifest.xml
和DEX檔案
缺點:
- 需要向APK裡新增檔案
- 需要程式有至少一個native庫
- 注入進去的庫的載入順序不能控制
API
lief.ELF.Binary.add_library()
原文連結:https://lief.quarkslab.com/doc/latest/tutorials/09_frida_lief.html
編譯:看雪翻譯小組 夢野間
校對:看雪翻譯小組 lumou