
免責事項: 本資料は教育目的のみに提供されています。対象システムの所有者の書面による同意なしにエクスプロイトを使用することは非倫理的であり、法的に訴追される可能性があります。
chmod +x build.sh。./build.sh。./mls_envp。root アクセスを取得できます。脆弱なバージョンの polkit (0.105) において、作者の David Zeuthen は pkexec が常にコンソールから呼び出されるものと想定していました。彼は argv[0] がプログラム自身の名前であるため、argc (引数の数) が常に 1 より大きいという前提に立っていました。しかし pkexec は、空の引数配列を渡してシステムコール execve を介して呼び出すことが可能です。これによりプログラムのロジックが破綻します。
pkexec のコードには、argv が少なくとも 1 つの要素を含むという前提がハードコードされています。argc が 0 の場合でも、プログラムは argv[1] にアクセスしようとします。これにより argv 配列の境界を越えて、envp 配列 (環境変数) の最初の要素を読み取ってしまいます。今回の場合、そこには "exp_exe" という文字列が格納されています。
pkexec は g_find_program_in_path 関数を使って exp_exe プログラムを探そうとします。この検索には PATH 変数が使用されます。私たちは PATH を GCONV_PATH=. に置き換えます。その結果、pkexec はローカルフォルダ内のダミーファイル exp_exe を見つけ、パス GCONV_PATH=./exp_exe を返します。argc のバグにより、このパスが envp[0] に書き戻され、GCONV_PATH 変数が「合法化」されます。
プログラムの起動前に、pkexec は環境変数 (SHELL を含む) をチェックします。私たちは存在しないシェル (SHELL=xyz) を渡してエラーを誘発します。エラー出力時に log_message が呼び出され、これが glibc の仕組みを利用します。glibc は CHARSET=bohemcavanna 変数を参照し、標準のコンバーターが見つからないため、GCONV_PATH で指定されたディレクトリ (私たちが仕込んだもの) にアクセスします。そこで gconv-modules ファイルを読み取り、私たちのライブラリ exploit.so をロードし、その内部のコードを root 権限で実行します。