Überprüfung der Befehls-Binärdateien vor der Ausführung

13

Gibt es Methoden, um zu überprüfen, was Sie tatsächlich aus einem Bash-Skript ausführen?

Sagen Sie Ihr Bash - Skript mehrere Befehle ruft (zum Beispiel: tar, mail, scp, mysqldump) , und Sie sind bereit , um sicherzustellen , dass tardie tatsächliche ist, real tar, was durch die bestimmbar rootBenutzer der Datei und übergeordnetes Verzeichnis Eigentümer und der einzige mit Schreibberechtigungen zu sein und nicht einige /tmp/surprise/tarmit www-dataoder apache2als Eigentümer.

Klar, ich weiß über PATHund über die Umgebung Bescheid , ich bin gespannt, ob dies zusätzlich mit einem laufenden Bash-Skript überprüft werden kann und wenn ja, wie genau?

Beispiel: (Pseudocode)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...
Miloš Đakonović
quelle
2
Wenn Sie so paranoid sind, dann verwenden Sie Ihre eigenen Binärdateien!
Ipor Sircer
8
Zusätzlich dazu, dass whichnicht korrekt angegeben wird, was getan tarwird, wie von xhienne beantwortet, lskönnte gehackt werden, um falsche Informationen über die Datei (en) zurückzugeben, falls vorhanden. Auch grepkönnte gehackt werden, um falsche Informationen zurückzugeben; Das könnte vermieden werden, indem stattdessen ein Shell-Matching verwendet wird. Dann könnte die Shell gehackt werden. Und Shell könnte gehackt werden, um von typeAnfang an falsche Ergebnisse zu liefern - oder komplett ersetzt werden, da die Austauschbarkeit der Shell eine wichtige Innovation von Unix im Vergleich zu 50-jährigen Betriebssystemen darstellt. Siehe Ken Thompsons Turing-Adresse von 1984. Es ist Schildkröten den ganzen Weg nach unten.
Dave_thompson_085
2
Ich kann dies nicht für Linux beantworten - nur für AIX, das eine Komponente namens Trusted Execution ( TE) mit einer Datenbank mit Signaturen hat (dh umfangreicher als eine MD5-Prüfsumme). Wenn TE aktiv ist UND sich eine Datei in der Datenbank befindet, können Sie wählen ob das Programm ausgeführt wird - oder nur warnt, dass es nicht mit der Datenbank übereinstimmt. Außerdem gibt es zwei weitere Einstellungen: TEP(Trusted Execution PATH) und TLP(Trusted LIBrary PATH). Es dürfen nur Programme in TEP ausgeführt und Bibliotheken nur mit geladen werden Das Verzeichnis ist in TLP enthalten. In Linux I gibt es etwas namens "AppArmor", das Ihnen helfen könnte.
Michael Filz
1
Sie können diese Art von Sicherheit haben, aber nicht von einem Skript aus - bis Ihr Skript in einer unkontrollierten Umgebung ausgeführt wird, ist es zu spät. Nach allem, was Sie wissen, ist alles, was Sie sehen können, eine Chroot, die von einem Angreifer erstellt wurde.
Charles Duffy
2
... wenn Sie ein System haben möchten, dem Sie von Anfang an vertrauen, müssen Sie den ChromeOS-Ansatz wählen: Lassen Sie Ihre Firmware mit einem in Ihre Hardware eingebetteten Schlüssel signieren. Ihr Bootloader / Kernel von der Firmware überprüft; Ihre Root-Betriebssystempartition ist schreibgeschützt und verwendet zur Überprüfung Signaturen auf Blockebene. etc. Es gibt auch Ansätze ähnlich dem , was @MichaelFelt diskutiert verfügbar - die Integrity Measurement Architecture sehen - aber die Auswirkungen auf die Leistung ist höher und das Niveau der Integrität reduziert (da die Überprüfung binären Signaturen nicht , dass Sie über nicht-ausführbare Datei mit Angriffen hilft Inhalt).
Charles Duffy

Antworten:

24

Anstatt die auszuführenden Binärdateien zu validieren, können Sie auch die richtigen Binärdateien von Anfang an ausführen. Wenn Sie beispielsweise sicherstellen möchten, dass Sie nicht ausgeführt werden /tmp/surprise/tar, führen Sie einfach /usr/bin/tarIhr Skript aus. Stellen Sie alternativ $PATHeinen vernünftigen Wert ein, bevor Sie etwas ausführen.

Wenn Sie Dateien /usr/bin/und anderen Systemverzeichnissen nicht vertrauen , gibt es keine Möglichkeit, das Vertrauen wiederzugewinnen. In Ihrem Beispiel überprüfen Sie den Eigentümer mit ls, aber woher wissen Sie, dass Sie vertrauen können ls? Das gleiche Argument gilt für andere Lösungen wie md5sumund strace.

Wenn ein hohes Vertrauen in die Systemintegrität erforderlich ist, werden spezielle Lösungen wie IMA verwendet. Dies ist jedoch nichts, was Sie von einem Skript aus verwenden könnten: Das gesamte System muss auf eine spezielle Weise eingerichtet werden, wobei das Konzept der unveränderlichen Dateien vorhanden ist.

Dmitry Grigoryev
quelle
Welches bricht ab, wenn verschiedene Distributionen Binärdateien /binanstelle von einfügen /usr/bin.
Damian Yerrick
IMA ist einer der beiden produktionsbereiten Ansätze, der andere ist der von ChromeOS verfolgte dm-verity-Ansatz für die Block-Level-Validierung der Rootfs.
Charles Duffy
@ DamianYerrick Fair Bemerkung. Stellen Sie $PATHdann beide Pfade ein, wenn Unterstützung für mehrere Verteilungen benötigt wird.
Dmitry Grigoryev
AIX TE (mit oder ohne RBAC) wäre ein dritter "produktionsbereiter" Kernel, der dies bewerkstelligt - vielleicht sogar mehr. TE, einmal aktiviert, um mehr als passiv zu sein - verhindert, dass Dateien geöffnet und / oder Programme ausgeführt werden. Darüber hinaus können Anwendungen und Bibliotheken ausschließlich über TEP (Trusted Execution Path) oder TLP (Trusted Library Path) verwendet werden. Grundlegende Informationen finden Sie unter ibm.com/support/knowledgecenter/en/ssw_aix_61/…
Michael Felt
6

Wenn ein Angreifer Zugriff auf Ihr System hat und Ihr System ändern kann $PATH(was /tmpunter keinen Umständen möglich sein sollte), ist es zu spät, um sich Gedanken über die Eigentümerschaft der ausführbaren Dateien zu machen.

Stattdessen sollten Sie lesen, wie Sie mit einem Eindringen umgehen .

Konzentrieren Sie sich besser darauf, Einbrüche zu vermeiden.

Wenn Sie ein System haben, in dem solche Dinge wichtig sind, ist es möglicherweise eine gute Idee, die Teile davon, die öffentlich sein müssen, von den Teilen zu isolieren, die privat sein müssen, und eine Prüfung der Kommunikationsmodi durchzuführen zwischen diesen.

Kusalananda
quelle
4

Es ist bis zu einem gewissen Grad möglich, md5sumeine Datei zu überprüfen . Auf Systemen mit aptPaketverwaltung - in meinem speziellen Fall Ubuntu 16.04 - gibt es also die Datei /var/lib/dpkg/info/tar.md5sums, in der die md5-Summen aller Dateien gespeichert sind, die tarwährend der Installation erstellt wurden. Sie könnten also eine einfache if-Anweisung schreiben, die prüft, ob die Ausgabe von md5sum /bin/tarmit der in dieser Datei übereinstimmt.

Das setzt natürlich voraus, dass die Datei selbst nicht manipuliert wurde. Dies kann natürlich nur passieren, wenn der Angreifer root / sudo-Zugriff hat. Zu diesem Zeitpunkt sind alle Wetten deaktiviert.

Sergiy Kolodyazhnyy
quelle
8
Aber wie validieren Sie /usr/bin/md5sum?
Dmitry Grigoryev
Wenn ein Angreifer in der Lage ist, /bin/taroder zu ersetzen /usr/bin/tar, ist es sehr wahrscheinlich, dass er auch einfach md5sumoder ersetzen kann /var/lib/dpkg/info/tar.md5sums. Oder $SHELL.
Jonas Schäfer
1
Ich glaube, ich habe bereits im letzten Absatz erwähnt, dass ein Angreifer dazu Root-Zugriff auf das System erhalten muss und zu diesem Zeitpunkt alles möglich ist. In Fällen, in denen der Angreifer keinen Root-Zugriff hat, aber die PATH-Variable für einen Benutzer ändern oder einen Alias ​​erstellen kann, in dem auf eine tarandere Binärdatei verwiesen wird, funktioniert dies. Wenn ein System auf der Root-Ebene kompromittiert ist, haben Sie eine Option: - Nuke es aus der Umlaufbahn
Sergiy Kolodyazhnyy
3

Ja, es gibt eine Methode: die eingebaute type. Im Gegensatz zu dem whichBefehl, der nur in Ihrem PFAD sucht, typewird Ihnen mitgeteilt, ob der Befehlsname tatsächlich ein reserviertes Schlüsselwort, eine eingebaute Datei, ein Alias, eine Funktion oder eine Festplattendatei ist.

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

Außerdem erhalten type -aSie alle Kandidaten für Ihr Kommando (von der ersten bis zur letzten Wahl):

$ type -a echo
echo is aliased to `/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

Wenn Sie sich nur Gedanken über die Binärdateien auf Ihrer Festplatte machen, können Sie type -Paalle Binärdateien in Ihrem PATH abrufen (in derselben Reihenfolge wie oben):

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

Das heißt, typealleine sagt Ihnen nicht genau, welcher Befehl am Ende aufgerufen wird. Wenn Sie tarbeispielsweise einen Aliasnamen haben, der eine Binärdatei aufruft (z. B. alias tar="/tmp/tar"), typewerden Sie darauf hingewiesen, dass es sich um einen handelt alias.

xhienne
quelle
type -a
Umfasst
Vielen Dank @ Dave, es ist in der Tat interessant, ich habe meine Antwort aktualisiert
xhienne
1
typeIch werde es Ihnen sagen, soweit Bash weiß, aber wenn wir von einem böswilligen Angreifer kontrolliert werden, gibt es keinen Grund zu der Annahme, dass das, was Bash glaubt, dass es weiß, die tatsächliche Wahrheit widerspiegelt. Nach allem, was Sie wissen, gibt es ein LD_PRELOADModul, das jeden einzelnen C-Bibliotheksaufruf abfängt, den Sie ausführen.
Charles Duffy
1
@CharlesDuffy Du hast natürlich recht. Ich wollte nicht auf den Sicherheitswinkel antworten. Ich schlage nur eine Antwort auf die Frage oben vor: "Gibt es Methoden, um zu überprüfen, was Sie tatsächlich aus einem Bash-Skript ausführen", und schlug eine Alternative zu vor which.
Xhienne
Ich habe noch nie gesehen enable. Ich habe die Ratschläge aus diesen Antworten verwendet, um type enableherauszufinden, ob es sich um eine integrierte Shell handelt, und um help enablezu sehen, was sie bewirkt.
Joe
3

Mit können Sie überprüfen, welche Befehle von einem Skript genau ausgeführt werden strace. Beispielsweise:

strace -f -e execve ./script.sh

Mit folgendem Skript:

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

stracezeigt den genauen Pfad zu den Befehlen an, die bei Verwendung mit -e execveparameter ausgeführt werden:

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

Parameter (von strace man):

-f: Verfolgen Sie untergeordnete Prozesse, wie sie von aktuell verfolgten Prozessen aufgrund der Systemaufrufe fork (2), vfork (2) und clone (2) erstellt werden. Beachten Sie, dass -p PID -falle Threads der Prozess-PID angehängt werden, wenn es sich um Multithread-Threads handelt, und nicht nur Thread mit thread_id = PID.

-e trace=file: Verfolgt alle Systemaufrufe, die einen Dateinamen als Argument verwenden. Sie können sich dies als eine Abkürzung vorstellen, für -e trace=open,stat,chmod,unlink,...die nützlich ist, um festzustellen, auf welche Dateien der Prozess verweist. Durch die Verwendung der Abkürzung wird außerdem sichergestellt, dass Sie nicht versehentlich vergessen, einen Anruf wie lstat in die Liste aufzunehmen.

Zumo de Vidrio
quelle
3
Dies ist keineswegs für ein Skript verwendbar, um automatisierte Tests durchzuführen, und es gibt keinen besonderen Grund zu der Annahme, dass stracedas Skript selbst nicht untergraben wurde.
Charles Duffy
0

Linux OS basiert auf Dateien und viele Befehle, die unter Linux ausgeführt werden, werden wahrscheinlich einige Änderungen an Dateien auf Ihrem Computer bewirken. Aus diesem Grund ist es vielleicht die beste Lösung für Ihr Problem. Sie können Ihre Befehle auf Änderungen am Dateisystem testen, bevor es ausgeführt wird.

Bildbeschreibung hier eingeben

Es gibt einen 'strace'-Befehl, der Ihren Befehl in Teile zerlegt ...

Bildbeschreibung hier eingeben

Wenn Sie wirklich tief gehen möchten, möchten Sie Dekompilierer für die Skripte auschecken, die ausgeführt werden sollen. Mit anderen Worten, Sie müssen die Assembler-Interpretation dieses Befehls überprüfen. Für Bash dort objdump -d. Linux bin-Skripte werden hauptsächlich mit CProgrammiersprache erstellt, verwenden Sie also einen guten CDekompiler.


quelle