인터프리터가 무한 반복되도록 하는 것이 가능합니까?

인터프리터가 무한 반복되도록 하는 것이 가능합니까?

스크립트가 자신을 인터프리터로 재귀적으로 호출하여 시스템 리소스를 중단시키는 서비스 거부 공격 시나리오에 대해 생각하고 있습니다.

원칙은 다음과 같습니다.

#!스크립트는 자체 인터프리터로서 첫 번째 줄에 샤방 형식으로 자체 절대 경로를 지정합니다 .

시스템 커널은 execve지원에 따라 시스템 호출 중에 인터프리터를 자동으로 호출하고 인터프리터를 인수 벡터 앞에 추가합니다.

{ARG_MAX}이러한 호출은 시스템에 설정된 program_parameters()의 크기 제한을 소진하여 (아마도 격리된) 오류를 발생시킵니다.

실험

저는 두 가지 공격 벡터 세트를 만들었습니다.

  • 첫 번째는 자신을 호출합니다.

    #!/usr/local/bin/recurse
    
  • 둘째, 서로 전화하세요.

    #!/usr/local/bin/recurse-1
    
    #!/usr/local/bin/recurse-2
    

저는 macOS Big Sur 11.5.2에서 이 2가지 공격 벡터를 테스트했습니다. 종료 상태 확인을 사용하면 echo $?프로세스가 성공적으로 완료되었음을 의미하는 0이 표시됩니다.

질문.

이러한 유형의 공격에 대해 최신 운영 체제에 패치가 적용되어 있습니까? 이에 대한 연구 논문이 있나요?

답변1

Linux에서는 다음을 얻습니다.

hashbang 라인에 존재하지 않는 인터프리터에 대한 스크립트가 있습니다( execve()주어진 ENOEXEC):

$ cat brokenhashbang.sh
#!/bin/nonexisting
echo hello
$ ./brokenhashbang.sh
bash: ./brokenhashbang.sh: /bin/nonexisting: bad interpreter: No such file or directory

재귀적 hashbang()을 사용한 스크립트 ELOOP:

$ cat /tmp/recursivehashbang.sh 
#!/tmp/recursivehashbang.sh
echo hello
$ /tmp/recursivehashbang.sh 
bash: /tmp/recursivehashbang.sh: /tmp/recursivehashbang.sh: bad interpreter: Too many levels of symbolic links

기존이지만 실행할 수 없는 인터프리터가 있는 스크립트( EACCESS):

$ cat noexechashbang.sh 
#!/etc/passwd
echo "hello?"
$ ./noexechashbang.sh 
bash: ./noexechashbang.sh: /etc/passwd: bad interpreter: Permission denied

Bash만이 아닙니다. Dash, ksh 및 zsh도 비슷한 오류를 발생시킵니다.

스크립트에 해시뱅이 없거나 해시뱅이 실행 불가능한 다른 파일을 가리키는 경우(하나가 있어야 +x얻을 수 있음 ENOEXEC) 동작이 약간 달라집니다. Bash는 파일 자체를 쉘 스크립트로 실행하는 반면, zsh는 hashbang 라인 내부를 살펴본 다음 해당 인터프리터를 시작하거나 /bin/sh.쉘에 대한 POSIX 지정 동작그리고execlp()/ execvp()기능 에 대한.

(인터프리터가 없으면 Dash는 dash: 1: ./brokenhashbang.sh: not found스크립트 자체가 존재하지 않는 것처럼 혼란을 줍니다. 하지만 기본 시스템 호출에서 오는 것과 동일한 오류라고 생각하며 Dash는 어떤 파일이 누락되었는지 확인하기에는 너무 간단합니다.)

어쨌든, 여기서 공격이 무엇인지 알 수 없습니다. 그들이 선택한 명령을 실행하면 이미 원하는 대로 무엇이든 할 수 있기 때문입니다. 존재하지 않는 스크립트 해석기를 통해서가 아니라 작동하는 해석기를 통해서입니다.

답변2

노트다음은 macOS Big Sur 11.5.2에서 테스트되었습니다.

표준(및 기존 관행)에 따르면,껍데기exec함수 호출이 실패하고 반환되면 파일을 해석하고 그 안에 있는 명령을 실행하려고 시도합니다.

세 번째 공격 벡터는 다음과 같습니다.

#!/usr/local/bin/recurse

eval 'printf "%s\n" xxx'

파일 이름을 지정 /usr/local/bin/recurse하고 실행한 후 문자열은 xxx표준 출력에 인쇄됩니다. 단, 인터프리터 루프로 인해 명령이 평가되지 않아야 합니다.

C 프로그램을 사용하여 함수를 통해 스크립트를 호출하는 경우 execv함수 errno호출 설정 값은 입니다 ENOEXEC.

관련 정보