web-dev-qa-db-ja.com

rootユーザーを他のすべてのユーザーと正確に区別するものは何ですか?

任意のアカウントとrootの基本的な違いは何ですか? UIDがゼロ以外のものであるだけですか?

それで、suバイナリdoは正確に何をし、それはどのように上昇しますかルートするユーザー? /etc/sudoersで見つけたものを通じて、ユーザーは最初にSudoグループの一部である必要があることを私は知っています。

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group Sudo to execute any command
%Sudo   ALL=(ALL:ALL) ALL

su実行可能ファイルのアクセス許可を見てみると-rwsr-xr-x、または 4755(つまり、setuidが設定されます)。

この構成ファイルを読み取り、root権限を要求しているユーザーがいずれかのグループの一部であるかどうかを確認するのはsuバイナリですか須藤またはadmin?もしそうなら、ユーザーが期待されるグループの一部であり、適切なユーザーのパスワードを知っていると仮定して、バイナリはルートとして別のシェルを生成しますか(setuidビットを考慮)それは置き換えられようとしています(たとえば、root)?


tl; dr特権昇格の動作は、suバイナリのsetuidビットに依存しますか、または現在のプロセスのUIDを変更する他のメカニズムはありますか?前者の場合、EUIDのみが変更され、UID!= EUIDが残るようです。これは今までに問題ですか?

relatedこれらすべてがAndroid環境でどのようにエミュレートされますか?私が読んだ限りでは、rootへのアクセスは完全に削除されています-プロセスはまだこれで実行されていますが特権レベル。

Sudosuを削除した場合、特権の昇格を防ぐのに十分でしょうか、それともAndroidさらに手順を踏んだでしょうか?

6
sherrellbc

ルートはユーザー0です

重要なのはユーザーID0です。カーネルには、呼び出しプロセスのユーザーIDをチェックし、ユーザーIDが0の場合にのみ何かを実行する許可を与える場所がたくさんあります。

ユーザー名は関係ありません。カーネルはユーザー名についてさえ知りません。

Androidの権限メカニズムは、カーネルレベルでは同じですが、アプリケーションレベルでは完全に異なります。 Androidにはrootユーザー(UID 0)があり、Linuxカーネルに基づく他のシステムと同じです。Androidにはユーザーアカウントがありませんが、ほとんどのセットアップでは、ユーザーが(デバイスを操作および所有している人間のように)rootユーザーとしてアクションを実行することはできません。「root化された」Androidは、デバイスの所有者を許可するセットアップです。/userは、rootとしてアクションを実行します。

Setuidのしくみ

setuid 実行可能ファイルは、実行可能ファイルを所有するユーザーとして実行されます。たとえば、suはsetuidであり、rootが所有しているため、いずれかのユーザーがそれを実行すると、suを実行しているプロセスがrootユーザーとして実行されます。 suの仕事は、それを呼び出すユーザーがrootアカウントの使用を許可されていることを確認し、この確認が成功した場合は指定されたコマンド(または、コマンドが指定されていない場合はシェル)を実行し、終了した場合は終了することです。この検証は失敗します。たとえば、suは、rootパスワードを知っていることを証明するようにユーザーに求める場合があります。

より詳細には、プロセスには つのユーザーID有効なUIDがあり、セキュリティチェックに使用されます。 realUID。これはいくつかの特権チェックで使用されますが、主に元のユーザーIDと保存されたユーザーIDのバックアップとして役立ちます。有効なUIDを一時的に実際のユーザーIDに切り替えてから、以前の有効なUIDに戻すプロセス(これは、たとえば、setuidプログラムが元のユーザーとしてファイルにアクセスする必要がある場合に役立ちます)。 setuid実行可能ファイルを実行すると、有効なUIDが実行可能ファイルの所有者に設定され、実際のUIDが保持されます。

Setuid実行可能ファイル(および同様のメカニズム、たとえばsetgid)を実行することが、プロセスの特権を昇格させる唯一の方法です。他のほとんどすべては、プロセスの特権を減らすことしかできません。

従来のUnixを超えて

これまで、従来のUnixシステムについて説明してきました。これはすべて、最新のLinuxシステムに当てはまりますが、Linuxにはいくつかの追加の問題があります。

Linuxには capability システムがあります。カーネルには、ユーザーID 0として実行されているプロセスのみが許可される多くのチェックがあると言ったことを覚えていますか?実際、各チェックには独自の機能があります(まあ、完全ではありませんが、一部のチェックは同じ機能を使用します)。たとえば、rawネットワークソケットにアクセスする機能と、システムを再起動する別の機能があります。各プロセスには、ユーザーとグループに加えて一連の機能があります。プロセスは、ユーザー0として実行されている場合、またはチェックに対応する機能がある場合、チェックに合格します。特定の特権を必要とするプロセスは、root以外のユーザーとして実行できますが、必要な機能を備えています。これにより、プロセスにセキュリティホールがある場合の影響が制限されます。実行可能ファイルは、1つ以上の機能にsetcapすることができます。これはsetuidに似ていますが、プロセスのユーザーIDではなくプロセスの機能セットで機能します。たとえば、pingには生のネットワークソケットのみが必要なので、setcap CAP_NET_RAW setuidrootの代わりに。

Linuxにはいくつかの セキュリティモジュール があり、最もよく知られているのは SELinux です。セキュリティモジュールは、rootとして実行されているプロセスにも適用できる追加のセキュリティチェックを導入します。たとえば、SELinuxを次のように設定することは可能です(簡単ではありません!) ユーザーID 0としてプロセスを実行しますが、実際には何もできないほど多くの制限があります

Linuxには ユーザー名前空間 があります。カーネル内では、ユーザーは実際には単なるユーザーIDではなく、ユーザーIDと名前空間で構成されるペアです。名前空間は階層を形成します。子名前空間は、その親内のアクセス許可を調整します。全能のユーザーは、ルート名前空間のユーザー0です。名前空間内のユーザー0は、その名前空間内でのみ権限を持ちます。たとえば、ユーザー名前空間のユーザー0は、その名前空間のすべてのユーザーになりすますことができます。ただし、外部からは、その名前空間内のすべてのプロセスが同じユーザーとして実行されます。

Linuxには4つのUIDがあります:[〜#〜] ruid [〜#〜](real)、[ 〜#〜] euid [〜#〜](有効)、[〜#〜] suid [〜#〜](保存済み)、[〜#〜] fsuid [〜#〜](ファイルシステム)。

これらは単なる数字であり、プロセスのプロパティであり、カーネルのプロセステーブルの制御ブロックに格納されます。

UID _'0'_は、一般的に無制限のアクセス権を持つユーザーrootを示すため、特別な特性を持っています。

suおよびSudoは、suのSetUIDビットを介してEUIDを新しいUIDに設定して新しいサブプロセスを開始することにより、ユーザーの有効なアクセス権を変更するプログラムです。次に、このsuプロセスは、4つのUIDが新しいUID値に設定された状態で、新しいサブプロセスで新しいシェルを再度生成します。

次の例はこれを示しているはずです。ユーザーrdaがssh端末を介してログインしているとしましょう。 _ps fax_は、関連する次のプロセスを示します。

_472 ?        Ss     0:00 /usr/sbin/sshd -D
9151 ?        Ss     0:00  \_ sshd: rda [priv]
9153 ?        S      0:00  |   \_ sshd: rda@pts/1
9154 pts/1    Ss+    0:00  |       \_ -bash
_

4つのプロセス、sshデーモン、sshセッション(およびターミナル?)用の2つのプロセス、最後のプロセスはログインシェルです(bashの前に_-_で示されます)

_ps faw -eo euser,ruser,suser,fuser,f,comm_は、プロセスのUIDを表示します。

_EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash
_

suを呼び出してから認証が成功すると、次のようになります。

_EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash
root     rda      root     root     4  |           \_ su
root     root     root     root     4  |               \_ bash
_

'bash'プロセスは、SetUIDビットによって_'0'_(root)に設定されたEUIDを使用して新しい 'su'子プロセスを開始します。RUIDはこの時点でもrdaのUIDに設定されています。 'su'プロセスは、新しいシェルで新しい子プロセスを再び開始し、ユーザーにルートアクセスを許可します(RUIDも_'0'_に設定されます)。ユーザーは作業ディレクトリに留まり、新しいシェルは親シェルと同じ環境を使用します。次に例を示します。

_server:/home/rda# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:/home/rda# pwd
/home/rda
_

シェルはexitで閉じることができ、ユーザーは元のアクセス権を持つ親シェルになります。

'su'がハイフン_'-'_パラメーターで呼び出された場合、状況は異なります。

_rda@server:~$ su -
Password:
server:~# echo $PATH
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:~# pwd
/root
_

新しいシェルはログインシェルであるため、シェル環境が変更されました。_'-su'_を参照してください。これにより、いくつかの追加の構成スクリプトが実行されます。

_ 9151 ?        Ss     0:00  \_ sshd: rda [priv]
 9153 ?        S      0:00  |   \_ sshd: rda@pts/1
 9154 pts/1    Ss     0:00  |       \_ -bash
 9613 pts/1    S      0:00  |           \_ su -
 9614 pts/1    S+     0:00  |               \_ -su
_

ログインシェルはlogoutで閉じる必要があります。

理論的には、Sudosuを削除することで、ユーザーが昇格された特権を取得するのを防ぎ、システムに直接(ターミナル、sshなどを介して)ログオンすることはできないと思いますデバイスに物理的にアクセスすることはできません。

更新:Androidでのルート化プロセス

詳細に説明されているように ここ 、Androidデバイスをルート化するための可能な方法はブートローダーおよびAndroidシステムプロパティ_ro.secure_。

ターゲットは常に同じで、suバイナリを_/system_にインストールし、それをsetuid(0)にします。

ロックされていないブートローダーを備えたデバイス:

デバイスからストックROM with ddをプルし、suを追加し、再パッケージ化(またはそのような変更されたROMをダウンロード)し、フラッシュモードでデバイスを再起動してフラッシュ変更されたROM。

ro.secure = 0のデバイス:

このシステムプロパティは、_adb Shell_に入力されたコマンドをルート(_ro.secure=0_)として実行するか、非特権ユーザー(_ro.secure=1_)として実行するかを制御します。_ro.secure_の値は起動時に設定されますrootディレクトリの_default.prop_ファイルから。このファイルにはユーザーrootのみがアクセスできるため、安全です。

ほとんどの場合、この_ro.secure_は_1_に設定されていますが、一部のメーカーはこれを_0_に設定しています。これは、デバイスのターミナルエミュレータまたはadbシェルでコマンド_getprop ro.secure_を実行することで確認できます。 _0_に設定されている場合、ルート化は非常に簡単です。コンピューターに接続し、adbを実行し、_/system_を読み取り/書き込みとしてマウントし、suをインストールします。

ロックされたブートローダーを備えたデバイス:

このようなデバイスには、製造元によって署名されていないカスタムROMをフラッシュできないリカバリがあります。この状況でrootアクセスを取得する唯一の方法は、特権モードで実行されている実行中のシステムプロセスの1つでセキュリティの脆弱性を悪用し、それをハッキングして「任意のコード」の実行を許可することです。このコードは通常、_/system_をマウントし、suを永続的にインストールします。

5
rda

一般に、有効なuidが0であるだけです。実行可能ファイルの「setuid」ビットは、実際にはプロセスの有効 uidを設定します。有効なuidがゼロでなく、実際のuidがゼロでない場合、プログラムは「非特権」ユーザーとして実行されています。以下が適用されます。

特権のないプロセスは、実効ユーザーIDを実際のユーザーID、実効ユーザーID、または保存されたset-user-IDにのみ設定できます。非特権ユーザーは、実ユーザーIDを実ユーザーIDまたは実効ユーザーIDにのみ設定できます。

Androidに関する限り、いいえ、Sudosuを削除するだけでは十分ではないと思います-いずれかのプログラムでseteuidビットを設定できる場合、そのプログラムはuid = 0で実行できる可能性があります。いつでもrootとして内部ファイルシステムにアクセスできる可能性がある場合は、そのようなプログラムが導入される可能性があり、rootアクセスが可能です。

2
Otheus