Jak wyjaśnił @dessert , problem polega na tym, że twój skrypt nie ma linii shebang . Bez shebang, sudo
domyślnie będzie próbował uruchomić plik przy użyciu /bin/sh
. Nigdzie nie mogłem go udokumentować, ale potwierdziłem, sprawdzając sudo
kod źródłowy, w którym znalazłem następujące informacje w pliku pathnames.h
:
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
Oznacza to „ustaw, jeśli zmienna _PATH_BSHELL
nie jest zdefiniowana, ustaw ją na /bin/sh
”. Następnie w configure
skrypcie zawartym w źródłowym pliku archiwalnym mamy:
for p in "/bin/bash" "/usr/bin/sh" "/sbin/sh" "/usr/sbin/sh" "/bin/ksh" "/usr/bin/ksh" "/bin/bash" "/usr/bin/bash"; do
if test -f "$p"; then
found=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $p" >&5
$as_echo "$p" >&6; }
cat >>confdefs.h <<EOF
#define _PATH_BSHELL "$p"
EOF
break
fi
done
Pętla ta wygląda na /bin/bash
, /usr/bin/sh
, /sbin/sh
, /usr/sbin/sh
i /bin/ksh
, a następnie ustawia _PATH_BSHELL
się w zależności od tego stwierdzono pierwszy . Ponieważ /bin/sh
był pierwszy na liście i istnieje, _PATH_BSHELL
jest ustawiony na /bin/sh
. Wynikiem tego wszystkiego jest to, że domyślną powłoką jest sudo
chyba, że zdefiniowano inaczej /bin/sh
.
Tak więc sudo
domyślnie uruchomi się za pomocą, /bin/sh
a na Ubuntu, który jest dowiązaniem symbolicznym do dash
minimalnej powłoki zgodnej z POSIX:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 27 2015 /bin/sh -> dash
[[
Konstrukt funkcja atakujących, nie jest zdefiniowane przez standard POSIX i nie są rozumiane przez dash
:
$ bash -c '[[ true ]] && echo yes'
yes
$ dash -c '[[ true ]] && echo yes'
dash: 1: [[: not found
Szczegółowo w trzech wywołaniach, które próbowałeś:
./test.sh
Nie sudo
; w przypadku braku linii shebang, twoja powłoka spróbuje wykonać sam plik. Ponieważ działasz bash
, będzie to działać skutecznie bash ./test.sh
i działać.
sudo su
a następnie ./test.sh
.
Tutaj zaczynasz nową powłokę dla użytkownika root
. Będzie to dowolna powłoka zdefiniowana w $SHELL
zmiennej środowiskowej dla tego użytkownika, a na Ubuntu domyślną powłoką roota jest bash
:
$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
sudo ./test.sh
Tutaj pozwalasz sudo
na bezpośrednie wykonanie polecenia. Ponieważ jego domyślna powłoka jest taka, /bin/sh
jak wyjaśniono powyżej, powoduje to uruchomienie skryptu /bin/sh
, co jest dash
i kończy się niepowodzeniem, ponieważ dash
nie rozumie [[
.
Uwaga : szczegóły dotyczące sudo
ustawień domyślnej powłoki wydają się nieco bardziej złożone. Próbowałem zmienić pliki wymienione w mojej odpowiedzi, aby wskazywały, /bin/bash
ale sudo
nadal domyślnie /bin/sh
. Dlatego w kodzie źródłowym muszą znajdować się inne miejsca, w których zdefiniowana jest domyślna powłoka. Niemniej jednak główny punkt (który sudo
domyślnie jest sh
) nadal obowiązuje.
sudo su
. Po prostu uruchomsudo -i
lubsudo -s
zamiast tego.