Sì , è 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
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:
\e]2;...\x07
imposta il titolo della finestra;\e[21;;t
titolo della finestra di interrogazione, posto nel buffer di input;\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