コンテンツにスキップ

Linux

HTB攻略のためのcheatsheet。Linux 環境の初期調査と、侵入後に次の調査先を決めるための技術ノート。writeup で確認した事実と、Linux に共通する仕組みを区別して記録する。

これらのコマンドには、認証情報の取得、リレー、リモート実行、永続化など、対象システムへ大きな影響を与える機能があります。検証環境または明示的な許可を得た環境だけで使用してください。

この節の記事では、次の4種類を分ける。

  • 確認済み: writeup、ログ、コード、コマンド出力で裏付けがある内容。
  • 推定: 証拠から合理的に考えられるが、直接の出力が残っていない内容。
  • 一般論: Linux やセキュリティの一般的な仕組み。
  • 未確認: 本来確認すべきだが、手元の証跡には残っていない内容。

一般コマンドは、writeup で実行ログが残っていない限り 追加確認例 として扱う。追加確認例 は実行済みの証跡ではない。

初期侵入の前後で、次の関係を1枚のメモにする。

外部公開サービス
↓
初期アクセスの実行ユーザー
↓
読める設定・資格情報・内部サービス
↓
別ユーザーまたは別プロセスへの入力経路
↓
sudo / systemd / cron / daemon / socket / container / SUID などの権限境界
↓
高権限処理が読むファイル・環境変数・引数・IPC
↓
root または目的ファイルへの影響

確認済み として最低限残す情報は次のとおり。

  • 現在の uid, gid, supplementary groups。
  • ログイン可能ユーザー、サービスユーザー、ホームディレクトリ。
  • 外部公開ポートと、侵入後にだけ見える localhost / Unix socket。
  • 実行中プロセスのユーザー、起動コマンド、親子関係。
  • sudo ルール、SUID / SGID、capabilities、systemd unit、cron / timer。
  • 自分が書けるファイル・ディレクトリと、それを高権限プロセスが読むか。
  • 独自コードの入力元、検証、保存、IPC、危険な処理。
  • 状態変更を行ったファイル、プロセス、トンネル、アップロード物。

外部から調べる場合は外部公開サービスを先に見る。シェルを得たあとは、次の順で実行ユーザーと権限境界を確認する。

  1. ユーザーと sudo
  2. プロセスと systemd
  3. ネットワークと IPC
  4. ファイルとディレクトリ権限
  5. 定期実行
  6. 資格情報と設定
  7. コンテナと名前空間

見つけた境界の読み方は、権限境界の各ページに分けている。

操作の痕跡と防御側の見方はログと検知。

  1. id; whoami; groups で現在の権限と補助グループを見る。
  2. sudo -l で root 実行できる完全パス、引数、環境制約を見る。
  3. ss -lntup または /proc/net/tcp で localhost と内部サービスを探す。
  4. ps auxww と /proc/<PID>/cmdline でサービスの実行ユーザーと起動引数を見る。
  5. systemctl cat <service> と EnvironmentFile で実設定を確認する。
  6. /opt、/srv、/var/www、/home/<user> で書き込み可能なパスと親ディレクトリの権限を見る。
  7. root や別ユーザーが読む入力ディレクトリ、ログ、ソケット、チェックポイント、プラグインを探す。
  8. コンテナ内なら /proc/1、マウント情報、capability、Docker ソケット、内部ネットワークを確認する。
  9. 独自コードは入力元から処理結果まで、データの流れを追う。
  10. 状態を変更する前に、後片付けの対象と確認するログを記録する。記録方法はログと検知を参照する。

侵入直後に手元へ置くコマンド:

ターミナルウィンドウ
id; whoami; groups
sudo -l
ss -lntup
ss -lxnp
ps -eo user,pid,ppid,group,cmd --forest
systemctl cat <service>
systemctl show <service>
tr '\0' ' ' < /proc/<PID>/cmdline
tr '\0' '\n' < /proc/<PID>/environ
ls -l /proc/<PID>/fd
namei -l <path>
stat <path>
findmnt -no TARGET,OPTIONS <path>
getfacl <path>
getcap -r / 2>/dev/null
find /opt /srv /var/www /usr/local -maxdepth 5 -writable -ls 2>/dev/null
cat /proc/self/status | grep Cap
cat /proc/self/mountinfo
  • id / groups: 実行ユーザーと補助グループ。
  • sudo -l: 明示された権限境界。
  • ss と /proc/net/tcp: 外部で見えない内部サービス。
  • ps と /proc: 実行ユーザー、起動引数、環境変数、ファイルディスクリプタ。
  • systemctl cat / show: 実際に使われる unit、環境ファイル、作業ディレクトリ。
  • namei / stat / getfacl: 親ディレクトリを含めた書き換え可能性。
  • findmnt: nosuid、bind mount、名前空間の差。
  • getcap: ファイルに設定された capability。SUID/SGID はファイルとディレクトリ権限の find -perm で調べる。
  • プロセス、ファイル、IPC、サービス設定の関係を確認してから、既知の脆弱性を調べる。
  • localhost のサービスには、同一ホスト、SSH トンネル、コンテナの共有ネットワークから接続できる場合がある。実行ユーザーと接続可能なユーザーを確認する。
  • root 権限の処理が低権限ユーザーの書けるデータを読む箇所が権限境界になる。
  • コンテナ内、模擬クラウド環境、ホスト上の root 権限は区別する。マウント、capability、ソケット、実ファイルの変化で境界を確認する。
  • shell=True、安全でないデシリアライズ、シンボリックリンク、モジュール検索パス、アーカイブ展開は、低権限ユーザーの入力を高権限で処理する場合に問題になる。
  • エラー応答だけで処理が失敗したとは判断しない。作成・変更されたファイル、コールバック、ログを確認する。
  • sudo で実行するコマンドが、root 権限でどの低権限ユーザーの入力を信頼するかを調べる。
  • /etc/passwd のログインシェルだけでなく、サービスユーザーのホームディレクトリとグループも見る。
  • sudo -l で許可されたコマンドが直接シェルを起動しなくても、そのスクリプトが読むデータを調べる。
  • systemctl cat で実際の unit を確認し、サンプル設定と本番設定を区別する。
  • ファイル名からディレクトリ部分を除くだけでは、後続処理が絶対パスや別のファイルを読む問題は防げない。
  • シンボリックリンクの検査を1段だけで終えると、2段目以降を見落とす。
  • /proc/<PID>/environ と fd が読めないこと自体が、権限境界の情報になる。
  • Docker ソケットがない環境でも、bind mount や内部サービスが横移動の入口になり得る。
  • プロンプトが root でも、コンテナ内の root 権限とホストの root 権限を分けて考える。
  • 自動列挙ツールが示す CVE 候補は、カーネル、capability、名前空間、実行条件を確認してから評価する。

最終ルート以外も、証跡から妥当なら残す。未実施なら 代替調査案 または 未確認 と書く。

  • systemd unit から実行ユーザー、環境ファイル、設定パスを特定する。
  • ps と /proc/<PID>/cmdline で、サンプル設定と実際の設定を区別する。
  • localhost のサービスは SSH トンネルやポート転送で管理 UI を確認する。
  • find <app-dir> -writable で、root が読むプラグイン、チェックポイント、ログを探す。
  • Unix ドメインソケットは stat と所属グループから接続可能なユーザーを確認し、実装を読んでから接続する。
  • コンテナ内では Docker ソケットに加え、bind mount と内部サービスを確認する。
  • 脆弱性名だけで判断せず、バージョン、capability、名前空間、マウントオプション、失敗時のログを確認する。