banner
Silas

REAO

Be a better man
github

Ratel 初体験

物語の起源: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を使用してコンパイルに成功しました。

皆さんがうまくコンパイルできることを願っています:

image

image

基本用法#

下の脱壳実験のターゲット《网上国网》を使ってデモを行います(使用したことはありませんが、Anti Root と加壳があるためです)。

1. ターゲットアプリを感染させる#

ターゲットを感染させるとは、ターゲットを二次パッケージングすることを意味し、サンドボックス環境で実行されます。

感染可能なリストから選択:

image

ここには少し役に立つ情報があります。gda はこの apk のパッケージ名を認識できないため、ここを直接見ることもできます。
image

選択後、自動的に再パッケージングされます。

感染成功:

image

以前にインストールしたオリジナル 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 で開くと、プラグインは緑色で、エラーがないことを示しています:

image

このプラグインの構造は、xposed モジュールと同じで、扱いやすいです:

image

xposed に不慣れな方は、私が若い頃に書いた記事を見てください https://www.freebuf.com/articles/terminal/248675.html

脱壳#

このターゲットアプリは加壳されており、anti root があり、Magisk Hide を有効にしないと辛うじて実行できません。
そのため、frida-dexdump を使用するのは難しいです...

直接逆コンパイルすると、加壳されていることがわかります:

image

次に脱壳が必要です。脱壳プラグインのコード:

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();
                }
            }
        });
    }
}

コードを編集した後、実行ボタンをクリックします:

image

ターミナルで adb logcat -s unpack と入力すると、脱壳の状態を確認できます。

image

モジュールが有効になっていることを確認します。

image
感染アプリの中でターゲットアプリをクリック -> プロセスを強制終了し、再度ターゲットアプリを実行します。

image

脱壳プロセスの constructUnpackedApk ステップで、常にエラーが発生します:

image

しかし最終的に、apk が生成されました:

image

adb pull /sdcard/wsgw-unpack.apk ./

gda にドラッグして開くと、正直なところ、この脱壳効果は本当に良いです...:

image

パケットキャプチャ#

vpn を利用してパケットキャプチャを行うと、証明書検証異常の警告が表示され、ssl ピニングまたは https 双方向認証が使用されている可能性があります:

image

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: ファイルの作成日からリクエストを特定するのに役立つかもしれません。

image

警告: ここではネイティブに対する処理が行われているかどうかはテストしていません。また、証明書のエクスポートがサポートされているかどうかもテストしていません。ドキュメントは非常に少ないです。

ターゲットアプリのプライベートファイルを読み取る#

このようなニーズもよくあります。個人的には、すべての免 root ソリューションはこの問題を考慮すべきだと思います。Ratel がどのように使用されるか見てみましょう。

リポジトリのアドレス:https://github.com/virjarRatel/sshdroid

ドキュメントは Readme と http://ratel-doc.virjar.com/04_ecology/SSHdroid.html を参照してください:

image

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 で開いて設定ファイルを作成し、設定が完了したら直接実行します:

image

image

RM のモジュールでこのモジュールを有効にし、ターゲットアプリを起動します。

# ポート転送
adb forward tcp:3478 tcp:3478

# sshログイン
ssh 127.0.0.1 -p 3478

現在のシェルコマンドのインタラクション表示はまだ最適化されていません。

確かに最適化されていませんが、使用可能です。

image

TIPS:パスワードはそのまま Enter を押してください。​

scp もサポートされており、体験はかなり良好です。

1. フォルダを取得

image

2. 単一ファイルを取得

image

cat もサポートされています。

image

その他のコマンドは必要なときに言及しますが、確かに人間工学的ではありません。しかし、このシェルは自動化スクリプトに非常に適しており、余計な情報がなく、自動補完を考慮する必要がありません。

フック#

適当な関数をフックして、以前のパケットキャプチャのコールスタックの中から 1 つの関数net.security.device.api.SecurityUtil.httpPostを見つけました:

image

その関数をフックするためのプラグインを作成します:

@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");
  }

フックの効果を見てみましょう:

image

ネイティブのフックはテストしていません、私はできません。

後記#

Ratel は非常に強力ですが、もちろん銀の弾丸ではありません:

image

しかし、非常に優れたものであり、二次開発を考慮する価値があります。今後の Anti に対処するために。


参考記事:

  1. app 逆向 平頭哥実戦(某農产品 app)
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。