物語の起源:Ratel,重打包沙箱
当時、私は VirtualXposed が VA に基づいてサンドボックス環境 + 神モードのフック能力を実現できると考えていました。
多くの人が考えたことだと思いますが、実現できたのは virjar だけで、これが大物ということでしょう。
理解しやすくするために、平頭哥を 太極 、アプリ転生の PRO バージョンと考えることができ、機能がより強力で、エコシステムがより良く、私たちの使用に適しています。
この種のツールはすべて免 rootであり、ターゲットアプリを再パッケージすることでサンドボックスでの実行を実現します。
文中関連ファイル:https://github.com/runtimed/useRatel
Ratel Manager#
まず、Ratel Manager をコンパイルする必要があります。RM は平頭哥の本体であり、このものは太極とアプリ転生のメインプログラムと理解できます。ターゲットアプリの二次パッケージング、サンドボックス環境の提供、xposed プラグイン管理などに使用されます。
渣総のリポジトリには完成品が見つからなかったので、自分でコンパイルする必要があります。
RM の構築にはスクリプトを使用する必要があり、そうでなければアプリ側の再パッケージをサポートできません。
git clone https://github.com/virjarRatel/ratel-core
cd ratel-core
# コンパイルを開始
./script/build_ratel_manager.sh
次はエラー処理の時間です!
Connection refused
IO exception while downloading manifest:
java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
at java.net.Socket.connect(Socket.java:606)
at java.net.Socket.connect(Socket.java:555)
at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient$1.run(HttpClient.java:515)
at sun.net.www.http.HttpClient$1.run(HttpClient.java:513)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.http.HttpClient.privilegedOpenServer(HttpClient.java:512)
プロキシの問題で、以前 gradle にプロキシを設定しましたが、今は外しました(家でソフトルーターを設置したため)。
## プロキシ関連の部分を削除
vim .gradle/gradle.properties
トラブルシューティングの過程で、ほとんどが NDK 関連の問題であることがわかりました。
ANDROID_HOMEを環境変数に追加するのを忘れないでください。私の Mac では次のようになっています:
export ANDROID_HOME="/Users/{UserName}/Library/Android/sdk/"
最後に、ndk 21.1.6352462
を使用してコンパイルに成功しました。
皆さんがうまくコンパイルできることを願っています:
基本用法#
下の脱壳実験のターゲット《网上国网》を使ってデモを行います(使用したことはありませんが、Anti Root と加壳があるためです)。
1. ターゲットアプリを感染させる#
ターゲットを感染させるとは、ターゲットを二次パッケージングすることを意味し、サンドボックス環境で実行されます。
感染可能なリストから選択:
ここには少し役に立つ情報があります。gda はこの apk のパッケージ名を認識できないため、ここを直接見ることもできます。
選択後、自動的に再パッケージングされます。
感染成功:
以前にインストールしたオリジナル apk をアンインストールし、感染したアプリをインストールすれば大丈夫です。
2. 新しいプラグインを作成#
https://github.com/virjarRatel/ratel-module-template 平頭哥のプラグインモジュールテンプレートで、プラグインプロジェクトを迅速に生成するために使用されます。
プラグインを生成するための 2 つの方法をサポートしています:
./template.sh -a ~/Downloads/wsgw.apk -m crack-wsgw # -aはターゲットapkを指します(自動的にパッケージ名を認識します)
./template.sh -p com.sgcc.wsgw.cn -m crack-wsgw # -pはパッケージ名
as で開くと、プラグインは緑色で、エラーがないことを示しています:
このプラグインの構造は、xposed モジュールと同じで、扱いやすいです:
xposed に不慣れな方は、私が若い頃に書いた記事を見てください https://www.freebuf.com/articles/terminal/248675.html。
脱壳#
このターゲットアプリは加壳されており、anti root があり、Magisk Hide を有効にしないと辛うじて実行できません。
そのため、frida-dexdump を使用するのは難しいです...
直接逆コンパイルすると、加壳されていることがわかります:
次に脱壳が必要です。脱壳プラグインのコード:
public class HookEntry implements IRposedHookLoadPackage {
private static final String tag = "DEMO_HOOK";
@Override
public void handleLoadPackage(final RC_LoadPackage.LoadPackageParam lpparam) {
if (lpparam.packageName.equals("com.sgcc.wsgw.cn")) {
Unpack.entry(lpparam);
}
}
}
public class Unpack {
public static final String tag = "TR_HOOK";
public static void entry(RC_LoadPackage.LoadPackageParam lpparam) {
// TODO 抽出するにはこのオプションを有効にする必要があります
UnPackerToolKit.autoEnable(true);
UnPackerToolKit.unpack(new UnPackerToolKit.UnpackEvent() {
@Override
public void onFinish(File file) {
try {
FileUtils.copyFile(file, new File("/sdcard/wsgw-unpack.apk")); // 脱壳後に生成されたapk
} catch (IOException e) {
Log.e(tag, "unpacked error", e);
e.printStackTrace();
}
}
});
}
}
コードを編集した後、実行ボタンをクリックします:
ターミナルで adb logcat -s unpack
と入力すると、脱壳の状態を確認できます。
モジュールが有効になっていることを確認します。
感染アプリの中でターゲットアプリをクリック -> プロセスを強制終了し、再度ターゲットアプリを実行します。
脱壳プロセスの constructUnpackedApk ステップで、常にエラーが発生します:
しかし最終的に、apk が生成されました:
adb pull /sdcard/wsgw-unpack.apk ./
gda にドラッグして開くと、正直なところ、この脱壳効果は本当に良いです...:
パケットキャプチャ#
vpn を利用してパケットキャプチャを行うと、証明書検証異常の警告が表示され、ssl ピニングまたは https 双方向認証が使用されている可能性があります:
Ratel には内蔵の socketMonitor があります(肉絲の R0Cpature より 3 年前に登場し、初期にはスレッドジャンプ追跡をサポートしていました。非同期問題を解決するために使用されます)
パケットキャプチャプラグインの作成
public class HookEntry implements IRposedHookLoadPackage {
private static final String tag = "DEMO_HOOK";
@Override
public void handleLoadPackage(final RC_LoadPackage.LoadPackageParam lpparam) {
if (lpparam.packageName.equals("com.sgcc.wsgw.cn")) {
//Unpack.entry(lpparam);
Monitor.entry(lpparam);
}
}
}
public class Monitor {
public static void entry(RC_LoadPackage.LoadPackageParam lpparam) {
SocketMonitor.setPacketEventObserver(new FileLogEventObserver(new File(RatelToolKit.whiteSdcardDirPath, "socketMonitor")));
// 対応するパスは /sdcard/ratel_white_dir/com.sgcc.wsgw.cn/socketMonitor
}
}
プラグインをインストールした後、必要なパケットキャプチャ機能を実行し、その後 pull します:
adb pull /sdcard/ratel_white_dir/com.sgcc.wsgw.cn/socketMonitor ./
見たところ、リクエスト、レスポンス、コールスタックがすべてあり、各ファイルは 1 つのリクエストに対応しています:
OS: ファイルの作成日からリクエストを特定するのに役立つかもしれません。
警告: ここではネイティブに対する処理が行われているかどうかはテストしていません。また、証明書のエクスポートがサポートされているかどうかもテストしていません。ドキュメントは非常に少ないです。
ターゲットアプリのプライベートファイルを読み取る#
このようなニーズもよくあります。個人的には、すべての免 root ソリューションはこの問題を考慮すべきだと思います。Ratel がどのように使用されるか見てみましょう。
リポジトリのアドレス:https://github.com/virjarRatel/sshdroid
ドキュメントは Readme と http://ratel-doc.virjar.com/04_ecology/SSHdroid.html を参照してください:
git clone https://github.com/virjarRatel/sshdroid.git
cd sshdroid
cp app/src/main/assets/config.template.properties app/src/main/assets/config.properties
as で開いて設定ファイルを作成し、設定が完了したら直接実行します:
RM のモジュールでこのモジュールを有効にし、ターゲットアプリを起動します。
# ポート転送
adb forward tcp:3478 tcp:3478
# sshログイン
ssh 127.0.0.1 -p 3478
現在のシェルコマンドのインタラクション表示はまだ最適化されていません。
確かに最適化されていませんが、使用可能です。
TIPS:パスワードはそのまま Enter を押してください。
scp もサポートされており、体験はかなり良好です。
1. フォルダを取得
2. 単一ファイルを取得
cat もサポートされています。
その他のコマンドは必要なときに言及しますが、確かに人間工学的ではありません。しかし、このシェルは自動化スクリプトに非常に適しており、余計な情報がなく、自動補完を考慮する必要がありません。
フック#
適当な関数をフックして、以前のパケットキャプチャのコールスタックの中から 1 つの関数net.security.device.api.SecurityUtil.httpPost
を見つけました:
その関数をフックするためのプラグインを作成します:
@Override
public void handleLoadPackage(final RC_LoadPackage.LoadPackageParam lpparam) {
Log.i(tag, "start");
//Ratelが提供するAPIで、ターゲットクラスのclassloaderを自動的に選択します。
ClassLoadMonitor.addClassLoadMonitor("net.security.device.api.SecurityUtil", new ClassLoadMonitor.OnClassLoader() {
@Override
public void onClassLoad(Class<?> clazz) {
Log.i(tag, "find class: " + clazz.getName());
RposedHelpers.findAndHookMethod(clazz, "httpPost",
String.class,
Map.class,
Map.class,
new RC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String arg1 = (String) param.args[0];
String arg2 = (String) param.args[1].toString();
String arg3 = (String) param.args[2].toString();
Log.i(tag, "args1:" + arg1);
Log.i(tag, "args2:" + arg2);
Log.i(tag, "args3:" + arg3);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
String res = (String) param.getResult();
Log.i(tag, "result:" + res);
Log.i(tag, "-------------------------");
}
});
}
});
Log.i(tag, "end");
}
フックの効果を見てみましょう:
ネイティブのフックはテストしていません、私はできません。
後記#
Ratel は非常に強力ですが、もちろん銀の弾丸ではありません:
しかし、非常に優れたものであり、二次開発を考慮する価値があります。今後の Anti に対処するために。
参考記事: