/etc/passwd は、システム上の全ユーザーの名簿。1行が1ユーザーで、: 区切りの7つのフィールドでできています。この構造と「UID=0 が管理者」という一点を押さえると、権限昇格の急所が見えてきます。
/etc/passwd を cat すると、こんな行が並びます。左から : で区切られた7項目を順に読みます。
| # | フィールド | rootの値 | 意味 |
|---|---|---|---|
| ① | ユーザー名 | root | ログイン名 |
| ② | パスワード | x | 「実体は /etc/shadow にある」の目印 |
| ③ | UID | 0 | ユーザーID。0 なら管理者(root) |
| ④ | GID | 0 | プライマリグループID |
| ⑤ | コメント | root | 説明欄(フルネームなど) |
| ⑥ | ホーム | /root | ホームディレクトリ |
| ⑦ | シェル | /bin/bash | ログイン時に起動するシェル |
⑦が /usr/sbin/nologin や /bin/false になっている行は「ログインさせないアカウント」(サービス用など)。systemd-coredump のような行がそれです。
Linuxが「この操作を許すか」を判断する材料は、ユーザー名ではなく UID です。そしてカーネルは UID が 0 のユーザーを無条件に管理者として扱います。名前が root でも hacker でも taro でも関係ない——UIDが0でありさえすれば、それはrootです。
だから「/etc/passwd に UID 0 の行を1つ書き足す」ことができれば、rootと同格の別アカウントを新設できる。既存のrootを乗っ取る必要すらありません。パスワードは自分で決めるので当然わかる → 堂々とroot権限でログインできてしまう。
x なのか昔は②のパスワード欄にハッシュを直接書いていました。ところが /etc/passwd は全員が読めるファイル。ハッシュが見えると、オフラインでゆっくりクラックされてしまいます。
そこでハッシュは /etc/shadow(rootしか読めない)へ移し、/etc/passwd 側は「shadowを見てね」の目印として x を置くようになりました。
ただし②にハッシュを直接書く古い方式は今でも有効です。x の代わりにハッシュ文字列を書けば、そのパスワードでログインできてしまう。攻撃者が突くのはまさにこの後方互換の抜け道です。
/etc/passwd は全員が参照する必要があるので「誰でも読める」のは正常。でも書き込みは root だけであるべきです。ここが緩んでいると、一般ユーザーが名簿を改ざんできてしまいます。
所有者(root)=読み書き、グループ=読むだけ、その他=読むだけ。一般ユーザーは書き換えられない。
その他にも w が付いている=一般ユーザーでも書き換え可能。UID 0 の行を追記できてしまう。重大な脆弱性。
$ ls -la /etc/passwd -rw-rw-rw- 1 root root 1398 Aug 16 2021 /etc/passwd # 誰でも書ける!
パーミッション数字の読み方は「所有者/グループ/その他」×(read 4+write 2+execute 1)。644=6(rw-)/4(r--)/4(r--)、666=6/6/6。.bashrc のときにやった読み方と同じです。
「書き込める /etc/passwd」を悪用した権限昇格の流れです。
cp /etc/passwd ./。壊すと全員ログイン不能になり得るので、慎重な攻撃者は必ず退避する。
その場にある openssl で、自分の決めたパスワードのハッシュを生成する(次項)。
例:hacker:$1$usersalt$AdRP...NT/:0:0:root:/root:/bin/bash を追記。③④を 0 にするのがポイント。
su hacker → 決めたパスワードを入力 → UID 0 = root を掌握。権限昇格成功。
openssl passwd$ openssl passwd -1 -salt usersalt Password: # "pass" と入力 $1$usersalt$AdRPkkbvjFipmAjyOm.NT/ # ← これを②欄に書く
-1 は MD5形式(-6 なら SHA512、本来はこちらが推奨)。-salt でソルトを指定。出てきたハッシュはこう分解できます。
ハッシュを作るときに混ぜるランダムな追加文字列。無いと同じパスワードは必ず同じハッシュになり、事前計算した対応表(レインボーテーブル)で一発逆引きされてしまう。ソルトを混ぜると同じ "pass" でも毎回違うハッシュになり、事前計算が効かなくなる。
※今回は攻撃者が自分でハッシュを作る側なので、ソルトは usersalt と適当に固定しているだけ。守る側の技術を悪用している構図です。
/etc/passwd は 644 から絶対に緩めない。書き込み可能になっていないか定期的に確認する。パスワードは /etc/shadow(640/root専有)で管理する。
侵害調査では UID 0 のアカウントが root 以外に無いかを必ず確認する。root 以外に UID 0 の行があれば、まずバックドアを疑う。
$ awk -F: '($3==0){print}' /etc/passwd # UID(3番目)が0の行だけ抽出 root:x:0:0:root:/root:/bin/bash hacker:$1$usersalt$...:0:0:root:/root:/bin/bash # ← root以外にUID 0!要調査
/etc/passwd は全ユーザーの名簿。1行 = :区切りの7フィールド。x — ハッシュ本体は /etc/shadow(root専有)へ。ただし②に直書きする古い方式も有効。644。-rw-rw-rw- だと一般ユーザーが名簿を改ざんできる。openssl passwd でハッシュ生成 → root化。awk -F: '($3==0)' で UID 0 を洗い出す。root以外があれば黒。