setuid 스크립트에서 `ln /path/to/file -i`는 무엇을 합니까?

setuid 스크립트에서 `ln /path/to/file -i`는 무엇을 합니까?

setuid 권한으로 Bash 스크립트를 만들고 있는데 작동하지 않습니다. 그래서 여기에서 내 해결책을 찾았습니다.

이제 내 스크립트는 잘 작동합니다(cpp를 사용하여 다시 작성했습니다).

순수 Bash 쉘이 작동하지 않는 이유에 대한 호기심을 충족시키기 위해 다음 링크를 읽었습니다.http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html(이 답변을 참고하세요:https://unix.stackexchange.com/a/2910). 해당 사이트에서 다음을 발견했습니다.

        $ echo \#\!\/bin\/sh > /etc/setuid_script
        $ chmod 4755 /etc/setuid_script
        $ cd /tmp
        $ ln /etc/setuid_script -i
        $ PATH=.
        $ -i

네 번째 줄을 이해하지 못합니다 ln /etc/setuid_script -i.

이 명령은 무엇을 합니까?

매뉴얼에서 ln이것은 -i단지 "대화형" 플래그(기존 파일을 덮어쓸지 묻는 메시지)라는 것을 읽었습니다. 그렇다면 왜 내 쉘을 ln /etc/setuid_script -i실행 PATH=.하고 실행하게 합니까 ?-i/bin/sh -i

답변1

이 코드는 현재 디렉터리에서 호출되는 파일에 대한 하드 링크를 ln /etc/setuid_script -i생성하도록 설계되었습니다 . GNU 도구를 사용하는 경우 작동하려면 이렇게 -i말해야 할 수도 있습니다 .ln -- /etc/setuid_script -i

쉘은 3가지 다른 방법으로 실행할 명령을 얻을 수 있습니다.

  1. 문자열에서. sh -c "mkdir /tmp/me"로고와 함께 사용됩니다 -c.
  2. 파일에서. 사용sh filename
  3. 터미널에서는 sh -i또는 를 사용합니다 sh.

foo역사적으로 "커널에서 시작"이라는 쉘 스크립트가 있는 경우 명령을 읽는 두 번째 방법을 사용하라고 지시하는 #!/bin/sh파일 이름으로 이를 호출했습니다 . /bin/sh foo파일 이름을 지정하면 -i커널이 이를 호출 /bin/sh -i하고 세 번째 방법을 얻게 됩니다.

경쟁 조건도 있습니다. 이것은 이용되었습니다.

  1. exec스크립트를 시작하려면 시스템 호출을 수행하십시오 .
  2. 커널은 파일이 SUID임을 확인하고 이에 따라 프로세스의 권한을 설정합니다.
  3. 커널은 파일의 처음 몇 바이트를 읽어 파일이 어떤 유형의 실행 파일인지 확인하고 해당 #!/bin/sh파일이 /bin/sh 스크립트라고 생각합니다.
  4. 공격자는 스크립트를 교체했습니다.
  5. 커널은 현재 프로세스를 /bin/sh로 대체합니다.
  6. /bin/sh는 파일 이름을 열고 명령을 실행합니다.

이것은 고전이다TOCTTOU(사용시간 확인)공격. 2단계의 확인은 6단계(공개 호출에서)에 사용된 파일과 다른 파일에 대해 수행됩니다.

이제 두 버그가 모두 일반적으로 수정되었습니다.

답변2

링크한 문서(http://www.faqs.org/faqs/unix-faq/faq/part4/section-7.html)은 (아마도) UNIX 시스템에서의 동작을 설명하고 있으며 ln, Linux 시스템(또는 더 정확하게는 GNU/Linux)의 매뉴얼을 살펴보세요. GNU는 여기서 관련 부분입니다. GNU에는 ln당신이 언급한 옵션이 있습니다:

   -i, --interactive
          prompt whether to remove destinations

그러나 이것은 GNU 확장이며 GNU 확장의 일부가 아닙니다.POSIX 표준다음 옵션 플래그만 정의됩니다.

-f
    Force existing destination pathnames to be removed to allow the link.
-L
    For each source_file operand that names a file of type symbolic link, create a (hard) link to the file referenced by the symbolic link.
-P
    For each source_file operand that names a file of type symbolic link, create a (hard) link to the symbolic link itself.
-s
    Create symbolic links instead of hard links. If the -s option is specified, the -L and -P options shall be silently ignored.

따라서 -i은 유효한 옵션이 아니므 로 ln이 명령은 실제로 를 가리키는 ln /etc/setuid_script -i이라는 하드 링크를 생성합니다 . 다음으로 명령어는 현재 디렉터리에 있는 실행 파일만 검색하도록 변수를 재정의하는데 , 이는 현재 디렉터리에 지정된 파일이 실행된다는 뜻이고, 하드링크이므로 스크립트가 실행된다는 뜻이다. 그러나 이는 쉘 스크립트이므로 실제 명령 실행은 입니다.-i/etc/setuid_scriptPATH=.PATH-i-i/etc/setuid_script/bin/sh -i

관련 정보