web-dev-qa-db-fra.com

La «capture» d'un fichier peut-elle constituer un risque potentiel pour la sécurité?

J'utilise souvent cat sur la console pour afficher le contenu des fichiers, et de temps en temps je cat accidentellement un fichier binaire qui produit essentiellement du charabia et des bips système . Cependant, aujourd'hui, j'ai rencontré une situation où la sortie de l'utilitaire cat a été redirigée vers l'entrée de la console, j'ai donc obtenu des trucs comme celui-ci:

-bash: 2c: command not found
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c: command not found
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found

...
...

Cela m'a fait penser qu'un fichier binaire spécialement conçu pourrait créer tout un gâchis sur le système?! ... Maintenant, je me rends compte que l'utilisation imprudente de chat comme ceci n'est pas particulièrement intelligente, mais j'aimerais en fait savoir ce qui se passe ici. Quels caractères produisent l'effet du dumping soudain du contenu sur l'entrée standard ...

Remarque: j'étais dans le terminal Mac OS X en faisant cela, j'ai en fait appelé diff -a pour comparer deux images rom du firmware et imprimer les différences (Je pensais qu'il n'y aurait que quelques octets de différences, mais là où près de 8 Mo de différences étaient imprimés à l'écran) Plus tard, j'ai essayé, exprès, de capturer l'un des fichiers et d'obtenir le même effet que j'ai collé ici.

- MISE À JOUR - - MISE À JOUR - - MISE À JOUR -

J'ai posté ceci ici tard dans la nuit hier et ce matin, j'ai essayé de reproduire le comportement et je ne peux pas. Malheureusement, je ne peux pas être sûr si certains caractères d'échappement ont provoqué l'exécution automatique du charabia du binaire sur la console ou si à la fin du chat je n'ai plus qu'un tas de caractères (comme si je les ai collés) sur le ligne de commande et j'ai probablement appuyé sur accidentellement pour obtenir une ligne claire ...

Lorsque j'essaie de capturer le fichier en question maintenant, j'obtiens ceci lorsqu'il se termine (faites défiler vers la droite pour voir):

D?k(Fli9p?s?HT?78=!g??Ès3?&é??  =??7??K?̓Kü<ö????z(;???????j??>??ö?Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$ 1;2c1;2c1;2;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c;1;1;112;112;1;0x1;2c1;2c;1;1;112;112;1;0x1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c

Mon invite réelle est:

Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$

Où:

FI9826W-2.11.1.5-20140121 NA

est le répertoire de travail actuel. Comme vous le voyez, il était camouflé dans le charabia binaire et j'aurais pu appuyer sur Entrée par réflexe ou quelque chose. En soi, c'est un peu faux pour le chat car, évidemment, mon invite aurait pu être encore mieux "camouflée". Mais c'est moins grave que je ne le pensais au départ. Bien que je ne sois toujours pas sûr à 100% qu'il ne s'est pas exécuté automatiquement la nuit dernière lorsque j'ai essayé, car il y avait aussi une autre chose particulière qui s'est produite la nuit dernière, avant cela. J'ai appelé cat sur un autre fichier très similaire qui a entraîné la fermeture de l'application Terminal avec:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00007fcb9a3ffffa

Maintenant, je pense que peut-être une combinaison de ces deux événements a provoqué l'exécution automatique de charabia sur la console. Mais je ne peux pas reproduire ce comportement à nouveau.

Les fichiers en question sont des firmwares pour une caméra IP Foscam, voici les liens:

Site international: http://foscam.com/Private/ProductFiles/FI9826W-2.11.1.5-20140120.Zip
Et puis le fichier à l'intérieur: FI9826W_app_ver1.11.0.40_OneToAll.bin

appeler cat sur celui-ci entraînera la fermeture de Terminal.

Site américain: http://foscam.us/downloads/FI9826W-2.11.1.5-20140121%20NA.Zip
puis le fichier: FI9826W_app_ver1.11.0.40_OneToAll_A.bin

catcher que l'on provoquera cette pâte de 1; 2c1; 2c1; 2; 2c1; 2c1; 2c1; 2c1; 2c1; 2c1; 2c1; 2c .... caractères sur la ligne de commande

90
Ivan Kovacevic

Oui, c'est un risque potentiel, voir CVE-2003-006 , ou CVE-2008-238 ou CVE- 2010-271 , ou CVE-2012-3515 ou OSVDB 3881 , ou CVE-2003-002 ou l'un des similaires répertorié ici ... Un peu plus dans les commentaires ci-dessous également.

Mise à jour ce n'est pas seulement un risque potentiel, c'est un risque réel. rxvt-unicode (versions 2.7—9.19, corrigé en 9.20) permet un accès en lecture/écriture à propriétés de la fenêtre X , cela peut permettre l'exécution assistée par l'utilisateur de commandes arbitraires, ce problème a été attribué CVE-2014-3121 , plus de détails ici https://bugzilla.redhat.com/show_bug.cgi?id=1093287 .

Plus récemment (octobre 2019) iTerm2 versions jusqu'à la v3.3.5 se sont avérées avoir les mêmes classe de problème : l'affichage de contenu malveillant peut activer le tmux intégré et permettre l'exécution de commandes, voir CVE-2019-9535 .

Ce sujet a également une bonne couverture ici: https://unix.stackexchange.com/questions/73713/how-safe-is-it-to-cat-an-arbitrary-file et une analyse approfondie du problème sous-jacent de Gilles ici: https://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals .


Explication

Ce que vous observez est un effet secondaire du comportement de certaines séquences d'échappement: certains d'entre eux remplissent les caractères (contenant généralement également des séquences d'échappement) directement dans le tampon d'entrée du terminal. Le tout au nom de la rétrocompatibilité, bien sûr. Les échappements standard xterm qui sont décrits en utilisant le terme "Report <something>" le font. Ce comportement permet aux programmes d'interroger/définir des propriétés de terminal (ou autres) " en bande " plutôt que via ioctls ou une autre API.

Comme si cela ne suffisait pas, certaines de ces séquences peuvent contenir une nouvelle ligne, ce qui signifie que tout ce qui est lu depuis le terminal (votre Shell) verra ce qui semble être une commande utilisateur complète.

Voici d'une manière ordonnée pour l'utiliser, avec read de bash pour imprimer un échappement (en tant qu'invite), puis lisez immédiatement et divisez la réponse en variables:

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

Ces séquences peuvent varier selon le terminal, mais pour rxvt et dérivé, l'échappement graphics inclut une nouvelle ligne (exemple utilisant bash et $'' chaînes, voir doc/rxvtRef.txt dans la source) `:

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

Cette fuite envoie \033G0\n dans le tampon d'entrée du terminal (ou chiffre 1 au lieu de 0 si vous disposez d'un rxvt) compatible graphique.

Alors, combinez cette évasion avec d'autres séquences qui se comportent de la même manière:

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

pour moi, cela provoque 11 tentatives d'exécution de diverses commandes: 1, 2c82, 20710 (ma chaîne de version _ rxvt), 0c5, 3R (5 et 3 étaient les coordonnées du curseur), 112 et 0x0.

Exploitable?

Avec rxvt et les émulateurs de terminaux les plus récents, vous ne devriez "que" pouvoir créer un ensemble limité de séquences principalement numériques. Dans les anciens émulateurs de terminal, il était possible (certains CVE répertoriés ci-dessus) d'accéder au presse-papiers, à l'icône de la fenêtre et au texte de la barre de titre pour créer des chaînes plus malveillantes à invoquer (une exception légère actuelle est si vous définissez la chaîne de ressource answerbackString X , mais cela ne peut pas être défini directement à l'aide de cette méthode). La faille permet alors un accès en lecture arbitraire et en écriture à quelque chose qui passe pour l'état ou le stockage dans des séquences d'échappement qui bourrent les données dans le tampon d'entrée.

rxvt nécessite des changements de temps de compilation pour s'activer, mais urxvt possède utilement un -insecure option de ligne de commande qui active certaines des fonctionnalités les plus intéressantes:

$ 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

Les trois séquences sont:

  1. \e]2;...\x07 définir le titre de la fenêtre;
  2. \e[21;;t titre de la fenêtre de requête, place dans le tampon d'entrée;
  3. \eGQ capacité graphique de requête, qui ajoute \n pour entrer le tampon.

Encore une fois, selon le terminal, d'autres fonctionnalités telles que la taille de la police, les couleurs, la taille du terminal, le jeu de caractères, les tampons d'écran alternatifs et plus peuvent être accessibles via des échappements. La modification involontaire de ceux-ci est au moins un inconvénient, sinon un problème de sécurité pur et simple. Les versions actuelles de xterm limitent les fonctionnalités potentiellement problématiques via les ressources "Allow *".

CVE-2014-3121

Avant la v9.20, urxvt ne protégeait pas non plus l'accès en lecture et en écriture aux propriétés X ( principalement utilisé par les gestionnaires de fenêtres ). Écrire l'accès en lecture (ou plus précisément, l'accès aux séquences qui font écho à des chaînes potentiellement arbitraires) nécessite désormais le -insecure option.

$ 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

Cela peut être trivialement utilisé pour bourrer des chaînes arbitraires dans le tampon d'entrée du terminal. Lorsque la séquence d'échappement pour interroger une propriété est invoquée (avec utile \eGQ qui ajoute une nouvelle ligne):

 $ 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

Plusieurs commandes, préservant les espaces et les métacaractères Shell. Cela peut être exploité de diverses manières, en commençant par utiliser un binaire non fiable, bien sûr, d'autres idées dans court article de H.D. Moore (2003).


Suivre

Pour la séquence d'échappement, vous demandez: 1;112;112;1;0x1;2 C'est: Demander les paramètres du terminal (DECREQTPARM) et Envoyer les attributs de périphérique:

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

Le deuxième (\e[0c) est le même que ^E (en utilisant rxvt). Il y a aussi quelques séquences d'échappement. la séquence complète écrite pour chacun est respectivement:

\e[1;1;1;112;112;1;0x
\e[?1;2c
60
mr.spuratic

Oui.

Nouveau ajout 2020-01-25:

Depuis que je suis passé de LATIN-1 encodage en UTF-8 as encodage par défaut dans la plupart de mes systèmes, j'ai trouvé quelques fonctionnalités intéressants autour de cela ( il y a maintenant deux longueurs pour une chaîne ) ...

Par exemple, comme j'aime jouer avec bash, j'ai demandé pourquoi la localisation bash ne fonctionnera pas avec les chaînes multilignes . Cette fonctionnalité bash présente un bogue, où la solution consiste à utiliser eval. Si ce n'est pas un défaut de sécurité, cela pourrait devenir ou produire un ...

Dans toutes les évolutions de presque n'importe quoi (langages, bibliothèques, outils, protocoles, applications, matériel, installateurs, consoles, etc ...) comme de nouvelles fonctionnalités, avec potentiellement de nouveaux bugs ...

Heureusement, ils sont aussi peu nombreux que rapidement corrigés (près de un jour à partir de la révélation), mais ils le sont!

Alors définitivement oui, restez vigilants!

Utilisation correcte de la commande cat.

Comme vous semblez utiliser un émulateur de terminal moderne, certaines séquences d'échappement pourraient être utilisées pour modifier -- Tampon clavier.

Il pourrait y avoir des commandes Shell appropriées injectées.

Vous pouvez utiliser l'argument -e de cat pour un fonctionnement sûr, voir 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

Alors

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

ou sous bash :

less < <(cat -e suspectfile.raw)

ou même

which less cat
/usr/bin/less
/bin/cat
rawless() { /usr/bin/less < <(/bin/cat -e "$@");}

Addenda

En fait, cela était possible , dans le passé ... Comme cela devenait un problème, ce genre de fonctionnalités a été rapidement supprimé, mais...

Lorsque vous lisez command not found, cela implique que quelque chose a été effectivement injecté.

La principale caractéristique injection qui a été non supprimée est la séquence identifiez-vous, utilisé dans de nombreuses encapsulations VT-100.

Cette séquence est Escape Z qui va injecter la chaîne 1;2c dans votre tampon clavier, ce qui signifie VT-100 (dans la convention AVO).

En parlant de cat, vous pouvez essayer:

cat <<< $'\033Z'

et à la ligne suivante, vous verrez 1;2c (ou peut-être avec un autre numéro, selon le terminal utilisé) comme si vous les frappiez.

... et

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

-e => -vE, -v transformer \033 en ^[ et -E mettre un $ signe à la fin de la ligne (et rien ne sera mis sur la ligne suivante, vous tampon du clavier n'est pas affecté).

Vous pouvez trouver beaucoup de choses amusantes sur Guide de l'utilisateur VT1 (comme: cat <<< $'\033#8';)

(C'était terminal moderne! Dans un certain passé ...)

Essayer d'utiliser bash

Il existe une petite commande bash pour vider la mémoire tampon du clavier et obtenir son contenu:

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

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

Et une petite fonction pour tester n'importe quelle chaîne:

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"
}

Je pouvais donc essayer:

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'|<
...

(peut-être avec un certain effet sur votre console)

Échantillon pour le plaisir

Imaginez, certains pourraient mettre quelque chose comme ça dans votre environnement:

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

De là, si vous

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

 $ 65;1;9c_

Le curseur restera à la fin de la ligne d'invite de commande. De là, si vous frappez machinalement Return au lieu de Ctrl + c, vous lirez quelque chose comme:

 $ 65;1;9c
bash: 65: command not found
bash: 1: command not found
You've been hitted!
 $ _

Et maintenant?

De là, malheureusement, il n'y a pas standard.

Chaque implémentation terminal virtuel pourrait prendre en charge la norme ANSI complète et/ou DEC complète ...

Mais comme il y a des problèmes de sécurité, beaucoup ne le font pas ...

Vous pourriez observer un comportement en utilisant un terminal que vous n'observeriez pas en utilisant un autre ...

xterm, console linux, gnome-terminal, konsole, fbterm, Terminal (Mac OS) ... le liste des émulateurs de terminaux n'est pas si court!

Et chacun d'eux a ses propres bogues et limitations par rapport aux normes DEC et ANSI.

Dans Pactice, vous pouvez trouver une console virtuelle qui pourrait être plus en vedette que d'autres et où injection clavier pourrait briser votre sécurité.

C'est une des raisons parce que je préfère toujours utiliser le même (ancien) xterm plutôt que d'autres outils plus en vedette.

47
F. Hauri

Les "vrais" terminaux en verre avaient une séquence d'échappement pour imprimer l'écran sur une imprimante. Ils l'ont fait en exécutant une commande et en redirigeant le contenu de l'écran actuel vers le stdin de la commande d'impression.

La commande peut être configurée par une autre séquence d'échappement.

La manière classique d'exploiter cela était de créer des fichiers avec des noms qui incorporaient la séquence d'échappement pour définir la commande d'imprimante et la changer en un script de votre choix, puis avoir un deuxième fichier avec la séquence d'échappement d'impression.

Lorsque quelqu'un exécutait ensuite ls dans ce répertoire, il finissait par exécuter votre code. Ce qui était bien s'ils étaient l'utilisateur root!

En théorie, les émulateurs de terminaux modernes ne devraient plus faire ce genre de choses.

Terminal.app semble être basé sur le nsterm NeXTSTEP, il peut donc contenir toutes sortes de bizarreries.

Essayez peut-être de préciser quels octets exacts produisent le command not found messages?

On dirait qu'il y a des séquences d'échappement pour monter et descendre le terminal:

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

plus d'informations ici:

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

Si vous souhaitez envoyer du contenu vers le stdin d'un programme,

program -para meters < /path/file.ext
7
JasperWallace

En règle générale, il n'y a pas de vulnérabilité, mais évidemment, si vous l'utilisez mal, vous pouvez en créer une.

L'impression du contenu d'un fichier binaire produit des bips car le caractère 7 est l'ancienne commande de terminal pour faire bip de la machine, et certains programmes de terminal honorent toujours cette commande. Mais par conception, rien ne peut vous blesser. Dans le pire des cas, ouvrez simplement une nouvelle fenêtre de terminal pour annuler tout désordre qui aurait pu être créé.

Maintenant, si vous avez en quelque sorte redirigé le contenu d'un fichier vers un shell de commande, c'est une autre question. Vous pouvez le faire en canalisant la sortie de quelque chose vers /bin/bash (généralement mal vu du point de vue de la sécurité) ou vous auriez peut-être copié et collé par inadvertance dans votre terminal. Aussi généralement mal avisé.

Mais tant que vous ne le faites pas run la chose, vous allez bien.

6
tylerl

Ce que vous voyez est séquences de contrôle xterm .

Les séquences de contrôle sont activées lorsqu'elles sont vues en sortie dans le terminal; par exemple, lorsque vous récupérez un fichier avec des octets ASCII non imprimables.

Dans votre exemple, la séquence de contrôle est ESC Z (octets 1B 5A) qui renvoie l'ID du terminal - comme une commande dans le terminal.

Vous pouvez l'essayer vous-même:

echo -e '\x1BZ'

(Vous pouvez également écrire ESC comme \e ou Z comme \x5A).

Il y en a aussi d'autres amusants:

echo -e '\eF' # move the Prompt to the bottom of the terminal.
echo -e '\ec' # Reset the terminal
4
dr jimbob

Je vais ajouter cette information ici sans intention réelle de répondre à ma propre question. Les caractères qui peuvent être injectés sur la ligne de commande lors de l'impression d'autres caractères, mieux connus sous le nom de séquences d'échappement, sont très bien définis sur ce site (Merci F. Hauri, pour le mentionner):
http://vt100.net/docs/vt100-ug/chapter3.html

Sous le chapitre: Rapports


Rapport de position du curseur

Invoqué par ESC [6 n
La réponse est ESC [Pl; Pc R
Pl = numéro de ligne; Pc = numéro de colonne

Rapport d'état

Invoqué par ESC [5 n
La réponse est ESC [0 n (terminal ok)
ESC [3 n (terminal pas ok)

Que faites-vous

Appelé par ESC [c ou ESC [0 c
La réponse est ESC [? 1 ; Ps c

Ps est le paramètre "option présente" avec la signification suivante:

Ps Signification
0 Base VT100, aucune option
1 Options de processeur (STP)
2 Option vidéo avancée (AVO)
3 AVO et STP
4 Option de processeur graphique (GPO)
5 GPO et STP
6 GPO et AVO
7 GPO, STP et AVO

Appelé également par ESC Z (non recommandé). La réponse est la même.


ESC est ASCII décimal 27 ou octal 33 ou hexadécimal 1B.

Donc, pour obtenir par exemple la position actuelle du curseur imprimée, ou mieux injectée dans votre ligne de commande existante, vous appelleriez:

echo -e '\033[6n'

et la sortie serait quelque chose comme ceci:

7;1R

Vous pouvez déplacer la position du curseur avec la séquence d'échappement suivante

echo -e '\033[10;20H'

10 - rangée 10
20 - colonne 20

Cependant, il ne déplace pas la position de la colonne (il se déplace sur les lignes) car le terminal la réinitialise probablement au début de la ligne. Quoi qu'il en soit, si vous interrogez la position du curseur juste après cela, il va "coller" sur la console la position de colonne définie:

echo -e '\033[10;20H\033[6n'

production:

0;20R

C'est comme ça que vous pouvez injecter différentes sorties (`` collées '') sur la console, c'est loin d'être un véritable exploit car cela ne donnera que différentes combinaisons de nombres qui peuvent être sorties, mais encore une fois peut-être combiné avec autre chose. Qui sait.

Dans mon cas où j'ai cat-ed l'image du firmware, j'ai eu beaucoup de: 1; 2c Maintenant, je sais que c'est le "What Are You "rapport, de ce qu'est mon terminal, où 2 signifie: Option vidéo avancée (AVO).

Dans l'ensemble, il est certainement préférable d'éviter de manipuler n'importe quel fichier sans réfléchir ...
Comme déjà suggéré (également par F. Hauri), utilisez au moins chat -e

4
Ivan Kovacevic