Verifica dei binari dei comandi prima dell'esecuzione


13

Esistono metodi per verificare ciò che si sta effettivamente eseguendo da uno script bash?

Di 'la tua script bash sta chiamando diversi comandi (per esempio: tar, mail, scp, mysqldump) e si è disposti a fare in modo che tarsia il reale, vero tar, che è determinabile dal rootutente ne sia il proprietario del file e la directory principale e l'unico con i permessi di scrittura e non alcuni /tmp/surprise/tarcon www-datao apache2essendo il proprietario.

Certo che conosco PATHe l'ambiente, sono curioso di sapere se questo può essere verificato ulteriormente da uno script bash in esecuzione e, in caso affermativo, come esattamente?

Esempio: (pseudo-codice)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...

2
Se sei così paranoico, usa i tuoi binari!
Ipor Sircer,

8
Oltre a whichnon dire correttamente cosa tarfarà, come ha risposto Xhienne, lspotrebbe essere hackerato per restituire informazioni false sui file, se presenti. Inoltre greppotrebbe essere hackerato per restituire informazioni false; ciò potrebbe essere evitato usando invece la corrispondenza della shell, ma la shell potrebbe essere hackerata. E la shell potrebbe essere hackerata per dare risultati errati typein primo luogo - o sostituita interamente poiché la sostituibilità della shell è stata un'importante innovazione di Unix rispetto ai sistemi operativi di 50 anni. Vedi l'indirizzo di Turing del 1984 di Ken Thompson. Sono le tartarughe fino in fondo.
dave_thompson_085,

2
Non posso rispondere a questa domanda per Linux - solo AIX - che ha un componente chiamato Trusted Execution ( TE) - che ha un database con firme (cioè più ampio di un checksum MD5. Quando TE è attivo E un file è nel database è possibile scegliere se il programma è in esecuzione - o avverte solo che non corrispondeva al database. Inoltre, ci sono altre due impostazioni: TEP(percorso di esecuzione sicuro) e TLP(percorso di biblioteca fidato). Solo i programmi in TEP possono essere eseguiti e le librerie possono essere caricate solo con la directory è inclusa in TLP. In Linux I c'è qualcosa chiamato 'AppArmor' che può esserti d'aiuto
Michael Felt

1
Puoi avere questo tipo di sicurezza, ma non da uno script: quando lo script viene eseguito in un ambiente non controllato, è troppo tardi. Per quanto ne sai, tutto ciò che puoi vedere è un chroot creato da un attaccante.
Charles Duffy,

2
... se vuoi avere un sistema affidabile fino in fondo, devi seguire l'approccio ChromeOS: avere il tuo firmware firmato con una chiave integrata nel tuo hardware; il tuo bootloader / kernel verificato dal firmware; la partizione del sistema operativo radice in sola lettura utilizzando le firme a livello di blocco per la verifica; ecc. Esistono anche approcci simili a ciò di cui parla @MichaelFelt - consulta l'architettura di misurazione dell'integrità - ma l'impatto sulle prestazioni è più elevato e il livello di integrità ridotto (poiché il controllo delle firme binarie non ti aiuta con attacchi non eseguibili soddisfare).
Charles Duffy,

Risposte:


24

Invece di convalidare i binari che eseguirai, potresti eseguire i binari giusti dall'inizio. Ad esempio, se vuoi assicurarti di non eseguire /tmp/surprise/tar, esegui semplicemente il /usr/bin/tartuo script. In alternativa, imposta il tuo $PATHsu un valore sano prima di eseguire qualsiasi cosa.

Se non ti fidi dei file /usr/bin/e di altre directory di sistema, non c'è modo di ritrovare la fiducia. Nel tuo esempio, stai controllando il proprietario con ls, ma come fai a sapere di cui ti puoi fidare ls? Lo stesso argomento si applica ad altre soluzioni come md5sume strace.

Laddove è richiesta la massima fiducia nell'integrità del sistema, vengono utilizzate soluzioni specializzate come IMA . Ma questo non è qualcosa che potresti usare da uno script: l'intero sistema deve essere impostato in un modo speciale, con il concetto di file immutabili in atto.


Ciò si interrompe quando diverse distribuzioni scelgono di inserire i binari /binanziché /usr/bin.
Damian Yerrick,

L'IMA è uno dei due approcci pronti per la produzione: l'altro è l'approccio dm-verity adottato da ChromeOS per eseguire la convalida a livello di blocco dei rootfs.
Charles Duffy,

Osservazione di @DamianYerrick Fair. Impostare $PATHsu entrambi quei percorsi, se è necessario il supporto per la distribuzione multipla.
Dmitry Grigoryev il

AIX TE (con o senza RBAC) sarebbe un terzo kernel incorporato "pronto per la produzione" che realizzerà questo - forse di più. TE, una volta abilitato a essere più che passivo, impedirà l'apertura dei file e / o l'esecuzione dei programmi. Inoltre, è possibile impostare l'utilizzo di applicazioni e librerie esclusivamente su TEP (percorso di esecuzione attendibile) o TLP (percorso di libreria attendibile). Vedi ibm.com/support/knowledgecenter/en/ssw_aix_61/… per informazioni di base
Michael Felt

6

Se un intruso ha ottenuto l'accesso al tuo sistema ed è in grado di modificare il tuo $PATH(che non dovrebbe includere /tmpin nessuna circostanza), allora è troppo tardi per iniziare a preoccuparti delle proprietà degli eseguibili.

Invece dovresti leggere su come gestire un'intrusione .

Meglio concentrarsi sull'evitare del tutto l'intrusione.

Se si dispone di un sistema in cui questo genere di cose è importante, potrebbe essere una buona idea isolare le parti di esso che devono essere pubbliche dalle parti che devono essere private, oltre a eseguire un controllo delle modalità di comunicazione tra questi.


4

È possibile in una certa misura verificando il md5sumdi un file. Quindi sui sistemi che usano la aptgestione dei pacchetti - nel mio caso particolare, Ubuntu 16.04 - c'è il file /var/lib/dpkg/info/tar.md5sums, che memorizza le somme md5 di tutti i file che provengono tardurante l'installazione. Quindi potresti scrivere una semplice istruzione if che controlla se l'output delle md5sum /bin/tarcorrispondenze è contenuto in quel file.

Ciò ovviamente presuppone che il file stesso non sia stato manomesso. Questo ovviamente può succedere solo quando un attaccante ha ottenuto l'accesso root / sudo, a quel punto tutte le scommesse sono disattivate.


8
Ma come convalidare /usr/bin/md5sum?
Dmitry Grigoryev il

Se un attaccante è in grado di sostituire /bin/taro /usr/bin/tar, è molto probabile che possano anche semplicemente sostituire md5sumo /var/lib/dpkg/info/tar.md5sums. Or $SHELL.
Jonas Schäfer,

1
Penso di aver già accennato nell'ultimo paragrafo, che affinché ciò accada, un utente malintenzionato dovrebbe ottenere l'accesso come root al sistema e, a quel punto, tutto è possibile. Nei casi in cui un utente malintenzionato non ha accesso come root, ma può modificare la variabile PATH per un utente o creare un alias in cui tarpunta a un diverso binario, funzionerà. Quando un sistema è compromesso a livello di radice, hai un'opzione quindi -
annulla

3

Sì, esiste un metodo: l'integrato type. Contrariamente al whichcomando che cerca solo nel tuo PERCORSO, typeti dirà se il nome del comando è in realtà una parola chiave riservata, un builtin, un alias, una funzione o un file su disco.

$ 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

Inoltre type -ati darà tutti i candidati per il tuo comando (dalla prima all'ultima scelta):

$ 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

Infine, se sei preoccupato solo per i file binari sul tuo disco, puoi usare type -Paper ottenere tutti i file binari nel tuo PERCORSO (stesso ordine come sopra):

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

Detto questo, typeda solo non ti dirà esattamente quale comando verrà chiamato alla fine. Ad esempio, se il tuo tarè un alias che chiama un binario (es. alias tar="/tmp/tar") Allora typeti dirà che questo è un alias.


type -ainclude tutti i moduli (ad es. alias e programma esterno)
dave_thompson_085

Grazie @dave, è davvero interessante, ho aggiornato la mia risposta
xhienne

1
typete lo dirò, come sa Bash, ma se siamo sotto il controllo di un malintenzionato malintenzionato, non c'è motivo di credere che ciò che Bash pensa di sapere rifletta la verità reale. Per quello che sai c'è un LD_PRELOADmodulo che intercetta ogni singola chiamata della libreria C che fai.
Charles Duffy,

1
@CharlesDuffy Hai ragione, ovviamente. Non volevo rispondere in termini di sicurezza. Sto solo proponendo una risposta alla domanda in alto: "Esistono metodi per verificare ciò che stai effettivamente eseguendo da uno script bash" e ho proposto un'alternativa a which.
Xhienne,

Non l'ho mai visto enableprima Ho usato il consiglio di queste risposte per type enablescoprire che è una shell integrata e poi help enableper vedere cosa fa.
Joe

3

Puoi controllare quali comandi vengono esattamente eseguiti da uno script usando strace. Per esempio:

strace -f -e execve ./script.sh

Con il seguente script:

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

straceti dirà il percorso esatto dei comandi eseguiti quando utilizzato con il -e execveparametro:

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 +++

Parametri (da strace man):

-f: Traccia i processi figlio mentre vengono creati dai processi attualmente tracciati a seguito delle chiamate di sistema fork (2), vfork (2) e clone (2). Si noti che -p PID -fcollegherà tutti i thread del processo PID se è multi-thread, non solo thread con thread_id = PID.

-e trace=file: Traccia tutte le chiamate di sistema che accettano un nome file come argomento. Puoi pensare a questo come un'abbreviazione per -e trace=open,stat,chmod,unlink,...cui è utile vedere a quali file fa riferimento il processo. Inoltre, l'uso dell'abbreviazione ti garantirà di non dimenticare accidentalmente di includere una chiamata come lstat nell'elenco.


3
Questo non è assolutamente utilizzabile da uno script per eseguire test automatici, e non vi è alcun motivo particolare per credere che stracenon sia stato sovvertito.
Charles Duffy,

0

Il sistema operativo Linux si basa su file e molti comandi eseguiti su Linux probabilmente risolveranno alcune modifiche ai file che si trovano sul tuo computer. Per questo motivo forse è la soluzione migliore per il tuo problema. È possibile testare i comandi per eventuali modifiche al file system prima che venga eseguito.

inserisci qui la descrizione dell'immagine

C'è un comando 'strace' che decompila il tuo comando in parti ...

inserisci qui la descrizione dell'immagine

Se vuoi davvero approfondire, devi controllare i decompilatori per gli script che verranno eseguiti. In altre parole, è necessario controllare l'interpretazione dell'assemblatore di quel comando. Per bash lì objdump -d. Gli script bin di Linux sono principalmente creati con Cun linguaggio di programmazione, quindi usa un buon Cdecompilatore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.