셸 산술 평가에서 비위생 데이터 사용에 대한 보안 영향


17

A의 의견 A와 최근 질문 , 스테판 Chazelas가이 이중 괄호에 보안 문제는 같은 산술 것을 언급한다 :

x=$((1-$x))

대부분의 껍질에.

Google 기술이 녹슨 것 같고 찾을 수 없습니다. 이중 괄호 산술의 보안 영향은 무엇입니까?

답변:


22

문제는 내용 $x이 삭제되지 않았으며 쉘 코드가 권한 에스컬레이션 컨텍스트 (예 : setuid에 의해 호출 된 스크립트)에서 사용될 수있는 경우 공격자가 제어 할 수있는 데이터를 포함하는 경우입니다 응용 프로그램, sudoers 스크립트 또는 네트워크 외부 데이터 (CGI, DHCP 후크 ...)를 직간접 적으로 처리하는 데 사용).

만약:

x='(PATH=2)'

그때:

x=$((1-$x)))

설정 부작용 가지고 PATH2(잘 공격자가 제어 될 수있는 상대 경로). 당신은 대체 할 수 PATH와 함께 LD_LIBRARY_PATH또는 IFS동일로 발생 ... x=$((1-x))(대시도 단지 거기 변수에 숫자 상수를 받아 YASH되지 않음)의 bash, zsh을 또는 ksh에서.

참고 :

x=$((1-$x))

$x(POSIX에 따라 선택 사항) --(감소) 연산자 를 구현하는 일부 셸에서 음수 값에 대해 제대로 작동하지 않습니다 (와 같이 x=-1, 셸에 1--1산술 표현식 을 평가하도록 요청하는 것을 의미 합니다). 산술 평가의 일부로 확장되기 "$((1-x))"때문에 문제가 없습니다 x.

에서 bash, zsh그리고 ksh(안 dashyash) 경우가 x있습니다 :

x='a[0$(uname>&2)]'

그런 다음 해당 명령 의 확장 $((1-$x))또는 실행으로 $((1-x))인해 uname명령이 실행됩니다 (for zsh, a배열 변수 여야하지만 psvar예를 들어 사용할 수 있음).

요약하면, 하나는 초기화되지 않은 사용해서는 안 또는 산술 평가를 수행 할 수있는 외부 쉘에서 산술 표현식의 데이터 (주 비는 - 소독 $((...))(일명 $[...]에서 bash또는 zsh)뿐만 아니라에서 쉘에 따라 let, [/ test, declare/typeset/export..., return, break, continue, exit, printf, print내장, 배열 인덱스 ((..))[[...]]구성을 예로들 수 있습니다).

변수에 리터럴 10 진수 정수가 포함되어 있는지 확인하려면 POSIXly를 사용할 수 있습니다.

case $var in
  ("" | - | *[!0123456789-]* | ?*-*) echo >&2 not a valid number; exit 1;;
esac

조심하십시오 [0-9]일부 로케일 경기 이상 0123456789가 [[:digit:]]확인을해야하지만 그것에 내기하지 않을 것입니다.

또한 앞에 오는 0을 가진 숫자는 일부 상황에서 8 진수로 취급되며 ( 010때로는 10, 때로는 8 임) 위의 확인으로 시스템에서 지원하는 최대 정수 (또는 응용 프로그램이 지원하는 응용 프로그램)보다 큰 숫자를 사용할 수 있다는 점에 유의하십시오. 해당 정수를 사용하십시오. 예를 들어 bash는 18446744073709551616을 0으로 간주합니다 (2 64 ). 따라서 위의 경우에 다음과 같이 추가 검사를 추가 할 수 있습니다.

(0?* | -0?*)
  echo >&2 'Only decimal numbers without leading 0 accepted'; exit 1;;
(-??????????* | [!-]?????????*)
  echo >&2 'Only numbers from -999999999 to 999999999 supported'; exit 1;;

예 :

$ export 'x=psvar[0$(uname>&2)]'
$ ksh93 -c 'echo "$((x))"'
Linux
ksh93: psvar: parameter not set
$ ksh93 -c '[ x -lt 2 ]'
Linux
ksh93: [: psvar: parameter not set
$ bash -c 'echo "$((x))"'
Linux
0
$ bash -c '[[ $x -lt 2 ]]'
Linux
$ bash -c 'typeset -i a; export a="$x"'
Linux
$ bash -c 'typeset -a a=([x]=1)'
Linux
$ bash -c '[ -v "$x" ]'
Linux
$ mksh -c '[[ $x -lt 2 ]]'
Linux
$ zsh -c 'echo "$((x))"'
Linux
0
$ zsh -c 'printf %d $x'
Linux
0
$ zsh -c 'integer x'
Linux
$ zsh -c 'exit $x'
Linux

더 읽을 거리 :


x='P=3'; : $(($x + 5))설정합니다 P8 만 x='P=3'; : $((x + 5))설정됩니다 P3(에서 zsh, ksh또는 bash). "와 같은 일이 $((x + 1))..."은 현재 정확하지 않습니다. 옛날부터로 설정 PATH됩니다 2.
mosvy 2012 년

@mosvy, 감사합니다 (그리고 이전 편집에 감사드립니다). 지금 수정되었습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.