バッファーオーバーラン攻撃でDNSのbindがcore*1を吐いて落ちていたのだが、権限昇格攻撃でサーバー全体が乗っ取られた後であった…と言う前世紀の思い出を聞いた人は多いと思いますが、最近のLinuxには脆弱なサーバーが攻撃されても被害を限定する仕組みLSMがあります。
LSMによる強制アクセス制御 (MAC) をbindに設定していたら、bindがbindユーザーで実行されているときはもちろん、rootユーザーに権限昇格した後でも、ディスクの読み書きやネットワーク制限が有効なので、適切に設定されていれば、サーバー全体を乗っ取るのは困難になります。LSMはSELinuxがその代表的な実装ですが、Ubuntu LinuxはAppArmorが採用されています。試しに設定してみましょう。
日本語の紹介記事は多い*2ので、細かい説明は割愛と言うか、コマンドを並べていきます。
Ubuntu 24は標準ではAppArmorの設定ツールが含まれていないので、追加します。
sudo apt install apparmor-utils
二つの実行ファイルのソースファイルを用意しました。ダウンロードしてコンパイルします。
cd /var/tmp mkdir AAexample cd AAexample wget https://wh.anlyznews.com/src/learn-apparmor.tgz tar zxvf learn-apparmor.tgz make
rnw.exeとcrnw.exeができます。rnw.exeは、与えた1番目の引数のファイルの中身を、2番目の引数のファイルにコピーします。crnw.exeは、与えた引数をつけて、rnw.exeを呼び出します。
echo "AppArmor" > a.txt ./rnw.exe a.txt b.txt ./crnw.exe b.txt c.txt
外形的には同じように動きますね。AppArmorの設定を変えてみましょう。
# 今回用意したプロファイルをコピー sudo cp profiles/var.tmp.AAexample /etc/apparmor.d/ # Daemonにプロファイルを読み込ませる sudo apparmor_parser -r /etc/apparmor.d/var.tmp.AAexample
sudo service apparmor reloadとしても良いのですが、既存のプロファイルをすべて読み直す必要はないので、apparmor_parserを使いました。
コピーしたファイルvar.tmp.AAexampleの中身は、以下のようになっています。
abi <abi/3.0>,
include <tunables/global>
/var/tmp/AAexample/rnw.exe {
include <abstractions/base>
/var/tmp/AAexample/rnw.exe mr,
/var/tmp/AAexample/*.txt rw,
}
/var/tmp/AAexample/crnw.exe {
include <abstractions/base>
/var/tmp/AAexample/crnw.exe mr,
/etc/ld.so.cache r,
/var/tmp/AAexample/rnw.exe mrix,
/usr/bin/dash mrix,
/var/tmp/AAexample/ r,
/var/tmp/AAexample/a.txt r,
/var/tmp/AAexample/b.txt rw,
}rnw.exeに*.txtへの読み書き権限を与えている一方、crnw.exeにはa.txtの読み込み、b.txtへの読み書きの権限しか与えていません。
なお、aa-genprofと言うツールが用意されており、引数でプログラムを指定して起動すると、セキュリティーログの引数のプログラムの動きから、自動でプロファイルを構成してくれます。最初、aa-genprofで空ファイルを/etc/apparmor.d/以下につくり、aa-complainで強制アクセス制御を警告は出るが規制はオフにして、プログラムを作動させてセキュリティーログをつくり、aa-enforceで規制をオンにするようなことができます。
さて、強制アクセス制御を体感してみましょう。
./rnw.exe a.txt b.txt ./crnw.exe b.txt c.txt
rnw.exeは変わらず、crnw.exeはc.txtが開けないとrnw.exeがエラーになったと思います。
./rnw.exe couldn't open the file: [2] c.txt
子プロセスの強制アクセス制御は、ドメイン遷移の設定なしでは親プロセスの設定を引き継ぎます。rnw.exeを直接呼び出した場合と、crnw.exeからrnw.exeを呼び出した場合で、挙動が変わるわけです。
また、
sudo ./crnw.exe b.txt c.txt
と、root権限で実行しても同様にエラーになります。chmodで設定する所有者による任意アクセス制御(DAC)とは独立した制御であることが分かります。
*1:プログラム異常終了時のメモリーの状態を記録するファイル
*2:「第798回 Ubuntuのセキュリティを支えるAppArmor入門 | gihyo.jp」「第799回 UbuntuでAppArmorのプロファイルを作ってみる | gihyo.jp」などを参考にしました。