web-dev-qa-db-ja.com

android apkとsuidバイナリ

Androidアプリ(APK)を(外部の "su"ネイティブ実行可能ファイルなしで)単独でroot権限で実行する方法はないと私が想定するのは正しいですか? NDKネイティブコードを使用していますか?

Androidアプリはネイティブ実行可能ファイルではなく、Dalvikランタイムで実行されるため、APKに「suidビット」を設定する方法がないため、 NDK seteuid(0)を呼び出して、特権をrootにエスカレートしますか?

私が理解しようとしているのは、ルート化されたAndroidデバイスが常に「su」ネイティブ実行可能ファイルの存在を必要とするため、何らかの特権操作を実行する必要がある他のアプリがそうすることができるようにするためですsystem()やexec()などを呼び出しますか?

私の仮定/理解のいずれかが間違っている場合は、遠慮なく指摘してください。

2
wei

Androidは、権限分離メカニズムとして、インストールされているアプリケーションごとに異なるユーザーIDを割り当てます。これは、アプリケーションに署名するために使用される証明書( https://source.Android.com/security/overview/app-security.html#application-signing )とともに、アプリケーションのAndroidManifest.xmlファイルのAndroid:sharedUserId属性:

Android=デバイスにアプリケーション(APKファイル)がインストールされると、パッケージマネージャーは、APKがそのAPKに含まれる証明書で正しく署名されていることを確認します。証明書(または、より正確には、証明書の公開鍵)は、デバイス上の他のAPKの署名に使用される鍵と一致します。新しいAPKには、他の同様に署名されたAPKとUIDを共有することをマニフェストで指定するオプションがあります。

エンドユーザーが起動したAndroidアプリケーションはすべてZygoteプロセスから生成されます(これは、Zygoteがアプリケーションコードをフォークしてロードでき、一連のシステムライブラリをリロードする必要がないため、アプリケーションの起動を高速化するのに役立ちます)。これを書いている時点では、Zygoteサービス構成は次のようになっています。

  service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/Android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks

このファイルの構文の概要は次のとおりです: https://Android.googlesource.com/platform/system/core/+/master/init/readme.txt 、これは特権について言っているデフォルトでサービスに割り当てられたレベル(デフォルトでは、Zygoteはrootとして実行されていることがわかります):

user <username>
  Change to username before exec'ing this service.
  Currently defaults to root.  (??? probably should default to nobody)
  Currently, if your process requires linux capabilities then you cannot use
  this command. You must instead request the capabilities in-process while
  still root, and then drop to your desired uid.

ZygoteはforkAndSpecializeという名前のJNIメソッド(「com_Android_internal_os_Zygote.cpp」を検索)を使用して、パッケージマネージャーがマニフェストとインストールされたアプリケーションに基づいて割り当てたUIDにsetuid()を呼び出すというプラットフォーム固有のタスクを処理します。そのsetuid呼び出しが失敗した場合に適切に終了できないことは、Android特権昇格の脆弱性の過去の脆弱性の原因でした(興味がある場合は、RygagainstTheCageエクスプロイトを参照してください。

これが、ルートレベルの特権を使用してアプリケーションを起動するために別の特権/ setuidバイナリが必要になる主な理由です。独自のカスタムシステムイメージを構築した場合、おそらくroot権限を保持するようにPackageManager/Zygoteを変更できますが、そうすると基本的にAndroidセキュリティモデルが壊れます。

4
Phil Ames