command_not_found_handle() Skript gefährlich und kleine Hilfe

  • Thread starter Thread starter Deleted member 11691
  • Start date Start date
D

Deleted member 11691

Guest
Hallo,

Edit: Oh, falsches Forum. Bitte moven!

ich habe mir die Mühe gemacht und folgendes kleine Script zusammengeschrieben:

Code:
command_not_found_handle() {
	if [ -d "$@" ]
	then
		cd "$@" && export PWD="$PWD/$@"
	elif [ -x "$@" ]
	then
		"./$@"
	elif [ -x "$1" ]
	then
		./$@
	elif [ -f "$@" ]
	then
		less "$@"
	else
		printf "%s: command not found\n" "$1" 1>&2
		return 127
	fi
}

1. Frage: Seht ihr dabei irgendeine Gefahr?
2. Frage: Meine "cd"-Funktion (erste IF-Abfrage) möchte nicht so, wie ich das eigentlich vorhabe. Ich hoffe, dass von euch hier jemand eine Lösung hat, warum das nicht funktioniert :(
3. Frage: Fallen euch sonst irgendwelche Fehler auf?

Danke!
 
Last edited by a moderator:
Ich finde augenfällig, dass du $@ immer gequotet hast. Das kommt mir komisch vor und ist mindestens unnötig.

Gefahren:
- Das Current-Dir ist absichtlich nicht in PATH enthalten. [1]
- Du gewöhnst dich an eine Magie, die es so nicht per default auf beliebigen Systemen gibt. Und diese Magie macht noch nicht mal was besonders. Sie nimmt dir im besten Fall einige wenige Tastendrücke ab, die einem geübten Konsolenbenutzer quasi automatisch aus den Fingern rutschen.

Edit: Dem letzten Punkt mag ich noch kurz etwas hinzufügen: Du nimmst der Shell ihren Determinismus. Normalerweise gibst du etwas ein und diese Eingabe hat exakt ein Ergebnis. Indem du einen determinierten Fall (command not found) abfängst und durch eine Heuristik ersetzt, wird dieser Determinismus durch ein nicht in jedem Fall vorhersagbares Ergebnis ersetzt.

Schau dir mal zsh an. Die kann auch einige schöne Sachen.

[1]: Imaging you write a script and call it "ls" then save it in a folder where you have access, let's say /tmp. Now if you get your admin to run "ls" in /tmp as root and have "." in the PATH, that will run your script instead of running the real "ls". This way you can do some nasty trick. This is why "." is not in your PATH.
 
Last edited by a moderator:
WIe sieht es dann mit einer Abfrage beim vor dem Executen aus, ähnlich wie
Code:
read -p "Do you really want to run $@?" answ
if [ "$answ" == "y" ]
then
...
fi
aus?

Zu den Quotes bei den $@ kann ich nur folgendes sagen:

Code:
touch file\ name
file name -> less "file name"

Es gibt hier auch noch NTFS-Platten, die, wie es Windows so an sich hat, noch Leerzeichen im Namen haben.
 
WIe sieht es dann mit einer Abfrage beim vor dem Executen aus, ähnlich wie
Code:
read -p "Do you really want to run $@?" answ
if [ "$answ" == "y" ]
then
...
fi
aus?
Das Schicken eines Reply kostet Script-Kiddies ein müdes Lächeln, ein fortgeschrittener Angreifer fällt vor Lachen vom Stuhl ;)
Ernsthaft: Was Du da vorhast ist das absichtliche Öffnen einer gravierenden Sicherheitslücke. Don't do it!
 
Naja.... So gesehen, ist es ja garkeine Sicherheitslücke, weil der Angreifer dann ja auch "./" vor den Dateinamen stellen könnte und das wäre dann genau das gleiche (nur ohne Abfrage).
 
Die Sicherheitslücke ist, dass du etwas machst, von dem du eine bestimmte Aktion erwartest, dann aber etwas anderes passiert. Weil eben z.B. das Current-Dir im Pfad steht und ein ausführbare Datei, die du eigentlich unter /usr/sbin vermutest plötzlich in deinem current-dir liegt aber was anderes macht. Eben z.B. in /tmp wo jeder schreiben darf.

Aber wie ich schon schrieb, finde ich es bedenklich, den Determinismus der für ein Feature Shell zu opfern, dass dir ein ./, ein less oder ein cd abnimmt.

Wenn du cd, ./ oder less schreibst, dann drückst du damit der Shell einen bewussten Wunsch nach Funktionalität aus. Wenn du nur den Dateinamen eingibst und dann von der Shell das automatisch richtige erwartest, dann externalisierst du die finale Entscheidung, was dein Kommando letztendlich bewirken soll. Und eine Abfrage hilft da auch nicht viel. Denn das Bestätigen jeder Aktion erfordert von dir die exakt selbe Eingabe. Und das ist etwas, das sehr schnell zu einer unbewusst ausgeführen Routine wird.

Du ersetzt also verschiedene Eingaben für verschiedene Kommandos durch gleichförmige Eingaben für verschiedene Kommandos. Egal ob es durch die Bestätigung zwei gleichförmige Eingaben werden.

Sowas halte ich für bedenklich. Das sieht im vorliegenden Fall vielleicht nicht sonderlich gefährlich aus. Aber es befördert eine Grundeinstellung wie User-Interaction funktioniert.

Es geht im Endeffekt darum, dem Benutzer eine bewusste Entscheidung für ein Kmmando abzuverlangen anstatt es ihm leicht zu machen, flüchtig eine ungewollte Aktion auszulösen. Deshalb halte ich die Idee, ein command-not-found in dieser Art abzufangen für keine gute Idee.
 
Naja.... So gesehen, ist es ja garkeine Sicherheitslücke,
Lies das mal quer: https://www.google.com/search?num=5...&q=ld_library_path+current+directory+security
Du implementierst jetzt absichtlich eine Funktion, welche alle Sicherheitsexperten weltweit eindeutig als eine Sicherheitslücke bezeichnen und das auch noch in nicht sonderlich gutem Shellscript. Denk mal drüber nach.

weil der Angreifer dann ja auch "./" vor den Dateinamen stellen könnte und das wäre dann genau das gleiche (nur ohne Abfrage).
Nein, es macht einen sehr grossen Unterschied, ob ich ein Kommando absichtlich, oder unabsichtlich ausführe.

Damit Du das Problem nachvollziehen kannst:
Bringe Deine Funktion in Stellung und führe folgende Befehlszeile aus und poste hier das Directorylisting wie es ls ausgibt:
Code:
wget http://www.rootservice.org/joeuser/ssf/SSF_TEST.tar.bz2 && \
tar xjf SSF_TEST.tar.bz2 && cd SSF_TEST/ && ls

Für alle Anderen zum Nachvollziehen diese Version nehmen und sich anschliessend das "./" wegdenken (macht seine Funktion nämlich):
Code:
wget http://www.rootservice.org/joeuser/ssf/SSF_TEST.tar.bz2 && \
tar xjf SSF_TEST.tar.bz2 && ./cd SSF_TEST/ && ./ls
 
Last edited by a moderator:
Damit Du das Problem nachvollziehen kannst:
Bringe Deine Funktion in Stellung und führe folgende Befehlszeile aus und poste hier das Directorylisting wie es ls ausgibt:
Code:
wget http://www.rootservice.org/joeuser/ssf/SSF_TEST.tar.bz2 && cd SSF_TEST/ && ls
Code:
root@node1 ~ # wget http://www.rootservice.org/joeuser/ssf/SSF_TEST.tar.bz2 && cd SSF_TEST/ && ls
--2012-10-13 09:48:54--  http://www.rootservice.org/joeuser/ssf/SSF_TEST.tar.bz2
Resolving www.rootservice.org... 5.9.14.236
Connecting to www.rootservice.org|5.9.14.236|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 696 [application/x-bzip2]
Saving to: “SSF_TEST.tar.bz2”

100%[==============================================================================================================================>] 696         --.-K/s   in 0s      

2012-10-13 09:48:55 (115 MB/s) - “SSF_TEST.tar.bz2” saved [696/696]

-bash: cd: SSF_TEST/: No such file or directory

/Edit:

Das ganze 'mal entpackt ausgeführt:

Code:
root@node1 ~/SSF_TEST # cd SSF_TEST
root@node1 ~/SSF_TEST/SSF_TEST #
/Edit
Code:
root@node1 ~/SSF_TEST # ls
cd  ls  SSF_TEST  SSF_TEST.tar.bz2
root@node1 ~/SSF_TEST # cd SSF_TEST
root@node1 ~/SSF_TEST/SSF_TEST # ls
cd  ls
Und wie Du siehst: command_not_found_handle() wird nur ausgeführt, wenn "cd" nicht gefunden wurde ;-)
 
Last edited by a moderator:
Code im vorherigen Post gefixt.

Das Sicherheitsproblem bleibt trotzdem, nimmt Angreifer halt andere/erfundene Befehle, irgendein User fällt schon drauf rein.
 
Gut, werde das erstmal auf Eis legen. Wie sieht es aber mit dieser Frage aus?
2. Frage: Meine "cd"-Funktion (erste IF-Abfrage) möchte nicht so, wie ich das eigentlich vorhabe. Ich hoffe, dass von euch hier jemand eine Lösung hat, warum das nicht funktioniert :(
Wäre toll zu wissen, weil mir das schon sehr oft Steine am Weg gelegt hatte (mir fällt hier gerade kein Beispiel ein).
 
PWD ist eine interne von der Shell selbst verwaltete Variable. Diese kannst Du nicht (neu) setzen.
Ansonsten auf die && verzichten und gegebenenfalls den Rückgabewert von cd abfragen und darauf reagieren.
 
Back
Top