내 BASH_FUNC_foobar%% 환경 변수가 쉘 하위 프로세스에 설정되지 않은 이유는 무엇입니까?

내 BASH_FUNC_foobar%% 환경 변수가 쉘 하위 프로세스에 설정되지 않은 이유는 무엇입니까?

나는 setuid 바이너리의 보안을 만지작거리고 있습니다(분명히 내가 찾은 모든 것을 작성자에게 공개하기 위해). 쉘 스크립트를 호출하고 환경을 삭제하지 않기 때문에 임의의 코드 실행 취약점이 있다고 확신합니다. Bash를 생각했지만 export -f실제로 개념 증명을 수행할 수는 없습니다.

기본적인 문제는 어떤 이유로 BASH_FUNC_foobar%%( foobar내보낸 함수가 있는 경우) 일부 하위 프로세스의 환경에서 불가사의하게 사라진다는 것입니다. 쉘이 아닌 경우에도 작동합니다.

% env 'BASH_FUNC_foobar%%=() { echo pwd lol; }' env | grep BASH
BASH_FUNC_foobar%%=() { echo pwd lol; }

env | grep BASH그러나 실제 프로그램 이름으로 바꾸고 환경을 덤프하도록 수정하면 (기본적으로 system("env")C 소스 코드에서) 변수가 삭제됩니다. sh호출할 명령을 지정하면 동일한 일이 발생합니다. 하지만 이상하게도 지정하면 bash함수가 제대로 선택됩니다.

내 테스트 시스템 /bin/sh에서는 dash.

도대체 무슨 일이 일어난 걸까요? 이 변수는 왜 사라지나요?

답변1

많은 Linux 시스템에서 /bin/sh이는 실제로 /bin/dash.

이미 언급했듯이논평by @MichaelHomer는 /bin/dash환경을 정리하고 , for를 /^[a-zA-Z_][a-zA-Z_0-9]*=.*/포함하여 양식의 일부가 아닌 모든 문자열을 제거합니다 .BASH_FUNC_foo%%=...%%

이는 dashOpenBSD ksh(및 이에 기반한 것) mksh에만 적용됩니다 . 다른 쉘에서는 이 작업을 수행하지 않습니다.

예를 들어 Debian에서는 /bin/sh다음과 같습니다 dash.

$ env - '@#%=' 'foo%%=bar' /bin/sh -c /usr/bin/printenv
PWD=/your/cwd
$ env - '@#%=' 'foo%%=bar' /usr/bin/printenv
@#%=
foo%%=bar
$ env - '@#%=' 'foo%%=bar' /bin/bash -c /usr/bin/printenv
[...]
@#%=
foo%%=bar

소스 참조를 위해 확인할 수 있습니다src/var.cdash소스 에서 :

    initvar();
    for (envp = environ ; *envp ; envp++) {
            p = endofname(*envp);
            if (p != *envp && *p == '=') {
                    setvareq(*envp, VEXPORT|VTEXTFIXED);
            }
    }

dashexec가 또 다른 바이너리인 경우 , env여기에 전달된 인수는 execve변수 목록에서 ( listvars(VEXPORT, VUNSET, 0)매크로 호출을 통해 environment()) 동적으로 구성됩니다.

관련 정보