0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TryHackMe Room「Linux PrivEsc」Task16〜18 詳細 WriteUp

Posted at

🔥 TryHackMe「Linux PrivEsc」Task16〜18 詳細 WriteUp

〜 パスワードと秘密鍵は、人間が最後に残す“痕跡”である 〜
image.png
Linux PrivEsc
TryHackMe / WriteUp


■ はじめに

前回の Task11〜15 では、

  • SUID 実行ファイルが「所有者の権限(例: root)」で動く仕組み
  • その周辺にある PATH / 共有ライブラリ / Bash の仕様 を揺さぶることで
    root まで落とし込むテクニック

を通じて、

「OS が“当たり前”だと思っている前提を壊すと、そのまま権限境界が崩れる」

という世界観を見てきました。

今回の Task16〜18 は、角度がガラッと変わります。

システムの穴より、**人間の痕跡(history・config・鍵管理)**のほうが危険

という、かなり現実的なテーマです。

  • Task16: history に漏れたパスワード
  • Task17: Config ファイルに埋め込まれた認証情報
  • Task18: world-readable な SSH 秘密鍵

それぞれについて、

  1. どうやって見つけるか(手順)
  2. OS / ミドルウェア的には何が起きているのか
  3. 実務だとどう防ぐか

という3段階で深掘りしていきます。


■ Task16:History Files

〜 “1回ミスって入力したパスワード” は永遠に残る 〜

● 何をしたか(手順)

問題文どおり、まずはユーザの history を一括で眺めます。

cat ~/.*history | less

これで、

  • ~/.bash_history
  • ~/.mysql_history
  • ~/.psql_history
  • など、ドットで始まる history 系ファイルがまとめて表示されます。

その中に、次のような行が見つかります。

mysql -u root -pPASSWORD123

ポイントはここです。

  • -p PASSWORD123(間にスペースあり)なら「パスワード入力プロンプト」が出る
  • -pPASSWORD123(スペースなし)だと「オプションの値」として扱われる
    → そのまま history に記録される

あとは、このパスワードで su するだけです。

su root
Password: PASSWORD123
whoami
# root

Exploit もコンパイルも不要。
**「history を見て、コピペで root」**という雑さです。


● 裏側で何が起きているか(技術的な話)

1. bash history の仕組み

bash は、対話セッション終了時に、実行したコマンドを ~/.bash_history に追加します。

  • 記録されるのは「入力した文字列そのもの
  • どの引数が「パスワードなのか」は一切理解していない
  • 「見られたら困るものかどうか」も当然考慮されない

つまり、CLI から見れば

mysql -u root -pPASSWORD123

は単なる「文字列」でしかなく、

  • mysql 側も
  • bash 側も

「これは秘密情報だから特別扱いしよう」とはしない、ということです。

2. mysql クライアントの挙動

-p オプションは 2通りの使われ方ができます。

  • -p だけ → パスワードを非表示入力(プロンプトで)
  • -p<password> → その文字列をパスワードとして使う

後者を使うと、mysql のプロセス引数 (ps aux など) にも -pPASSWORD123 が見えてしまうので、本来はセキュリティ的に推奨されません。

✔ つまりこの Task は、
安全でない mysql の使い方」+「bash history の仕様」
の掛け合わせが root 奪取に直結する例です。


● 実務だとどう防ぐか?

現場で守るべきはだいたいこのあたりです。

  • CLI オプションにパスワードを書かない

    • mysql -p とだけ打ってプロンプト入力する
    • 環境変数や .my.cnf(権限600)などを使う
  • HISTCONTROL / HISTIGNORE を活用する

    • 例えば HISTCONTROL=ignorespace にしておき、
      先頭にスペースを付けたコマンドは履歴に残さないようにする運用など
  • 「history を定期的に削除する」のは根本対策にならない
    「そもそも載せない」文化を作るほうが重要


■ Task17:Config Files

〜 Config は設定ファイルではなく、認証情報の“集積所” 〜

● 何をしたか(手順)

ホームディレクトリを確認すると、VPN の設定ファイルっぽいものが見つかります。

ls /home/user
myvpn.ovpn

中身を見てみると:

cat /home/user/myvpn.ovpn
client
dev tun
proto udp
remote 10.10.10.10 1194
...
auth-user-pass /etc/openvpn/auth.txt
...

ここで重要なのは auth-user-pass ディレクティブです。

  • OpenVPN クライアントは、このパスにあるファイルから
    ユーザ名1行目 / パスワード2行目 を読み取る
  • つまり 認証情報の「置き場」がハードコードされている

指定されている /etc/openvpn/auth.txt を見ると:

cat /etc/openvpn/auth.txt
root
PASSWORD123

はい、また root の生パスワード。

su root
# → root シェル

● OpenVPN 的には何が起きているか?

auth-user-pass の挙動を整理するとこうなります。

  • auth-user-pass だけ → 実行時にユーザへ username/password を対話入力させる
  • auth-user-pass /path/to/file → 指定ファイルから username/password を読み込む

今回は後者。

OpenVPN 側は「/etc/openvpn/auth.txt は安全に管理されているはず」という前提で動いているため、OS レベルで world-readable になっていようが知ったこっちゃありません。

つまりこの Task は、
「ミドルウェアの“信頼前提”が、OS のファイル権限設計と噛み合っていない」
例として見るとわかりやすいです。


● ファイル権限の観点

本来やるべきなのはこういう設計です。

  • /etc/openvpn/auth.txt のパーミッションを 600 にする

    chmod 600 /etc/openvpn/auth.txt
    chown root:root /etc/openvpn/auth.txt
    
  • OpenVPN プロセスを root もしくは専用ユーザで動かし、
    「そのユーザだけが読める」状態にしておく

Task の VM ではここがザルなので、

  • ローカルの低権限ユーザが cat /etc/openvpn/auth.txt できる
  • そのまま su root が通ってしまう

という状態になっています。


● 実務での「あるある」&対策

よくあるやらかし

  • VPN・DB・API クライアントの設定ファイルに
    ID/PW を平文で放り込む
  • しかも /etc や 共有ディレクトリなど、
    他ユーザも読める場所に置いてしまう

現実的な防御

  • 平文で置かざるを得ない場合は「読めるユーザを厳密に制限」
    600 + 所有者適切設定は最低ライン
  • そもそも ID/PW ではなく、
    証明書ベース認証やトークンベース認証への移行を検討する
  • 設定ファイルを Git にそのまま突っ込まない
    .gitignore / 環境変数 / Secret Manager などで分離する

Task17 は、

「Config ファイルは“動かすためのメモ”ではなく、
最悪の場合 root 直行の鍵束になる」

という意識を持つきっかけになります。


■ Task18:SSH Keys

〜 鍵が落ちていたら、その家はもう所有者のものではない 〜

● 何をしたか(手順)

/ 直下に 不自然な隠しディレクトリがあるのに気付くところからスタートです。

ls -la /
drwxr-xr-x   2 root root 4096 ...  .ssh

中身を確認すると:

ls -l /.ssh
-rw-r--r-- 1 root root 1679 ... root_key
  • root_key というファイル名
  • サイズ的にも「典型的な RSA 秘密鍵」

しかもパーミッションが 644 (rw-r--r--) で、
誰でも読み取り可能になっています。


● SSH 秘密鍵のフォーマット

中身を cat してみると、おなじみのやつが出てきます。

cat /.ssh/root_key
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----

もしくは古い形式だと:

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

SSH 的にはこれは クライアント側に置くべき秘密鍵であり、

  • サーバ側:~/.ssh/authorized_keys公開鍵 を置く
  • クライアント側:~/.ssh/id_rsa(秘密鍵)を所持し、ssh -i で使う

という役割分担になっています。

この VM では「サーバ側に“秘密鍵”が落ちっぱなし」という完全アウトな状態です。


● 権限 600 が必須な理由

手元にコピーしたあと、まずはパーミッションを直します。

chmod 600 root_key

なぜかというと、ssh クライアントは

「権限が甘い秘密鍵は危険」と判断して使うのを拒否する

という安全機構を持っているからです。

  • 他ユーザに読み取り可能 = 秘密鍵とは呼べない
  • なので、クライアント側で 600 以外なら文句を言う

これは逆に言うと、

「秘密鍵を world-readable にしているサーバ」は
もはやセキュアとかそういう次元にいない

ということでもあります。


● ログインコマンドとオプションの意味

問題文の SSH コマンドはこうなっています。

ssh -i root_key \
  -oPubkeyAcceptedKeyTypes=+ssh-rsa \
  -oHostKeyAlgorithms=+ssh-rsa \
  root@MACHINE_IP

ここで指定しているのは、いわゆる レガシー暗号スイートの許可です。

最近の OpenSSH は、

  • ssh-rsa(SHA-1 ベース)の鍵種別・ホスト鍵を
    デフォルトでは拒否するようになっている

ため、古い VM に接続する際には、

  • PubkeyAcceptedKeyTypes=+ssh-rsa
    → クライアント認証として ssh-rsa を許可
  • HostKeyAlgorithms=+ssh-rsa
    → サーバホスト鍵として ssh-rsa を許可

といったオプションが必要になることがあります。

Task としては

「鍵そのものは有効だが、暗号スイートが古くてそのままでは弾かれる」

という **“実務でも割と遭遇する問題”**もついでに体験させている形です。


● なぜこれが一番ヤバいのか?

パスワード漏洩と秘密鍵漏洩は、重さがそもそも違います。

  • パスワード
    → 変えればまだ巻き返せる
  • 秘密鍵
    → すでに「署名」「認証」のベースに載ってしまっている
    → PKI 全体を張り替える必要が出てくることも

SSH の世界観では、

「秘密鍵を持っている=本人そのもの」

なので、

  • root の秘密鍵が world-readable
  • さらに authorized_keys に対応する公開鍵が登録済み

という状況は、そのサーバの root という人格そのものが盗まれているのと同じです。


● 実務での対策

  • root で SSH ログインさせない(PermitRootLogin no
    → そもそも「root に対する鍵認証」という概念を消す
  • 鍵ペアをユーザごとに発行し、authorized_keys をユーザ単位で管理
  • .ssh ディレクトリの権限を定期チェック(700 / 600 以外を検出)
  • 古い ssh-rsa の整理(ED25519 / ECDSA などへの移行)

Task18 は、そういう「鍵運用全体をどう見るか」という視点まで含めて考えるとかなりおいしいタスクです。


■ Task16〜18 総括

〜 “人間の痕跡”は Exploit より強力な攻撃面になる 〜

3つを並べて整理するとこうです。

Task 起点 技術要素 実際の侵入パス
16 history に残ったコマンド bash の履歴機能 / CLI オプションの扱い ~/.bash_history → パスワード → su root
17 Config ファイルの設定 OpenVPN の auth-user-pass / ファイル権限 myvpn.ovpn/etc/openvpn/auth.txtsu root
18 秘密鍵の雑な管理 SSH 鍵・権限600制約 / レガシー ssh-rsa /.ssh/root_keyssh -i root_key root@…

共通しているのは、

  • 攻撃者は 難しい Exploit コードを投げていない
  • やっているのは「ファイルを読む/そのまま使う」だけ

という点です。

権限昇格は「カーネル Exploit のエンドゲーム」だけではなく、
人間が残した痕跡と、“まあいいか”の積み重ねからも普通に起きる。

Task1〜15 が「OS/バイナリ/権限の仕組み」を揺さぶる回だとすると、
Task16〜18 は

「日々の運用・作業ログ・Config 設計」の甘さ
どれだけ root 直結かを叩きつける回

になっています。


■ おわりに

Task16〜18 を技術的に分解すると、こんな教訓が残ります。

  • history はログではなく“証拠”
    → パスワードを CLI オプションに乗せない
  • Config ファイルは設定ではなく“リスク資産”
    → 認証情報を書くなら、権限と保管場所を本気で設計する
  • 秘密鍵は「本人そのもの」
    → world-readable な鍵があった時点で、そのアカウントは終わっている

次の Task19〜21 では、
人間ではなく NFS / Kernel / 自動化ツールを軸に

  • 「ファイル所有者」
  • 「カーネルの安全性」
  • 「ツールが拾いきれない前提の穴」

といった、OS レベルの信仰を壊していくフェーズに入ります。


ここまで読んでくれた方へ
「人のミス × Linux の仕様」がどう root 直行になるかのイメージが
少しでもクリアになっていたら嬉しいです。
特に今回の章は理解しやすい内容を、さらにLinux的にはどうなっている?
という観点を記載したつもりです。

この次の Task19〜21 は、一つ一つが重ためなので、
それぞれを記事にしたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?