GNU/Linux >> Tutoriels Linux >  >> Linux

Cat-ing un fichier peut-il être un risque potentiel pour la sécurité ?

Oui , il s'agit d'un risque potentiel, voir CVE-2003-0063, ou CVE-2008-2383 ou CVE-2010-2713, ou CVE-2012-3515 ou OSVDB 3881, ou CVE-2003-0020 ou l'un des similaires listés ici ... Un peu plus dans les commentaires ci-dessous également.

Mettre à jour ce n'est pas seulement un potentiel risque, c'est un risque réel .rxvt-unicode (versions 2.7—9.19, corrigées en 9.20) permet un accès en lecture/écriture aux 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 les versions jusqu'à la v3.3.5 se sont avérées avoir la même classe de problèmes :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 :certaines d'entre elles remplissent des caractères (contenant généralement également des séquences d'échappement) directement dans le tampon d'entrée du terminal . Tout cela au nom de la rétrocompatibilité, bien sûr. Le xterm standard les échappements qui sont décrits en utilisant le terme "Signaler " le font. Ce comportement permet aux programmes d'interroger/définir les propriétés du terminal (ou autre) "dans la 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 lit depuis le terminal (votre shell) verra ce qui semble être une commande utilisateur complète.

Voici une bonne façon de l'utiliser, avec le read de bash pour imprimer un échappement (en tant qu'invite) puis immédiatement lire et diviser 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ée, la requête graphique escape inclut une nouvelle ligne (exemple avec bash et $'' chaînes, voir doc/rxvtRef.txt dans les sources)` :

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

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

Alors, combinez cet échappement 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 (mon rxvt chaîne de version), 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 terminaux, 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 construire davantage de chaînes malveillantes à invoquer (une légère exception actuelle est si vous définissez le answerbackString Chaîne de ressource X, mais qui ne peut pas être définie directement à l'aide de cette méthode). La faille permet alors de lire arbitrairement et accès 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 a 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, placez-le dans le tampon d'entrée ;
  3. \eGQ capacité de requête graphique, qui ajoute \n au tampon d'entrée.

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 encore peuvent être accessibles via des échappements. La modification involontaire de ceux-ci est au moins un inconvénient, sinon un véritable problème de sécurité. Versions actuelles de xterm restreindre les fonctionnalités potentiellement problématiques via les ressources "Autoriser*".

CVE-2014-3121

Avant la v9.20, urxvt n'a pas non plus protégé 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 utilisé de manière triviale pour insérer 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 l'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

Commandes multiples, préservant les espaces blancs et les métacaractères du shell. Cela peut être exploité de différentes manières, en commençant par cat-ing un binaire non fiable bien sûr, d'autres idées dans H.D. Court article de Moore (2003).

Suivi

Pour la séquence d'échappement dont vous parlez :1;112;112;1;0x1;2 C'est :Demander les paramètres du terminal (DECREQTPARM) et Envoyer les attributs de l'appareil :

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

Le deuxième (\e[0c ) est identique à ^E (en utilisant rxvt ). Il y a aussi des 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

Certainement oui.

Nouvel ajout 2020-01-25 :

Depuis le temps que je suis passé de LATIN-1 encodage en UTF-8 comme encodage par défaut dans la plupart de mes systèmes, j'ai trouvé des fonctionnalités intéressantes autour de ça (il y a maintenant deux longueurs pour une corde)...

Pour exemple, comme j'aime jouer avec bash , j'ai demandé pourquoi la localisation bash ne fonctionnerait pas avec les chaînes multilignes. Cette fonctionnalité bash présente un bogue, où la solution consiste à utiliser eval . S'il ne s'agit pas d'une faille de sécurité , cela pourrait en devenir ou en produire un...

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

Heureusement, ils sont aussi peu nombreux qu'ils sont rapidement corrigés (presque un jour de la révélation), mais ils le sont !

Alors définitivement oui, restez prudents !

Utilisation correcte de cat commande.

Comme vous semblez utiliser un émulateur de terminal moderne , quelques séquences d'échappement pourrait être utilisé pour modifier le tampon du clavier .

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

Vous pouvez utiliser l'argument -e de cat pour un fonctionnement en toute sécurité, 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 "[email protected]");}

Remarques

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

L'injection principale fonctionnalité qui n'était pas supprimé 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 la mémoire tampon de votre clavier, ce qui signifie VT-100 (en convention AVO).

En parlant de cat , vous pouvez essayer :

$ cat <<< $'\033Z'

Ou une autre séquence ANSI :CSI c (Attributs de l'appareil ):

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

imprimera une ligne vide, mais sur la ligne suivante, vous verrez 1;2c (ou peut-être avec d'autres numéros, selon le terminal utilisé) comme si vous les a frappés :

$ 65;1;9c█

... mais avec -e commutateur :

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

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

Vous pouvez trouver beaucoup de choses amusantes dans le guide de l'utilisateur du VT100 (comme :cat <<< $'\033#8';)

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

Essayer d'utiliser bash

Il existe une petite commande bash pour vider le tampon du clavier et obtenir son contenu :

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

Et une petite fonction pour tester n'importe quelle chaine :

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

Alors je pourrais 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 quelques inoffensifs effets sur votre console;)

Petit exemple pratique

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

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

Ensuite, si vous

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

$ 65;1;9c█

Le curseur restera à la fin de la ligne d'invite de commande.

À partir de là, si vous appuyez machinalement sur Retour au lieu de Ctrl + c , vous lirez quelque chose comme :

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

Et maintenant ?

A partir de là, malheureusement, il n'y a pas de standard .

Chaque terminal virtuel l'implémentation pourrait prendre en charge la norme ANSI complète et/ou la norme 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)... la liste des émulateurs de terminaux n'est pas si courte !

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

En pratique, vous trouverez peut-être une console virtuelle qui pourrait être plus présentée que les autres et où l'injection de clavier pourrait briser votre sécurité.

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


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 pourrait être configurée par une autre séquence d'échappement.

La façon classique d'exploiter cela consistait à créer des fichiers avec des noms qui intégraient la séquence d'échappement pour définir la commande de l'imprimante et la remplacer par un script de votre choix, puis avoir un 2e fichier contenant la séquence d'échappement d'impression.

Quand quelqu'un a ensuite exécuté ls dans ce répertoire, ils finiraient par exécuter votre code. Ce qui était bien s'il s'agissait du root utilisateur !

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 réduire les octets exacts qui 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

quelques infos ici :

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

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

program -para meters < /path/file.ext

Linux
  1. Un script Bash peut-il être accroché à un fichier ?

  2. Les fichiers écrasés peuvent-ils être récupérés ?

  3. 4 façons de créer un fichier texte dans un terminal Linux

  4. Comment puis-je lier symboliquement un fichier sous Linux?

  5. Supprimer l'historique du terminal sous Linux

Déplacer des fichiers dans le terminal Linux

Comment imprimer un fichier JSON dans un terminal Linux

Téléavertisseurs de terminaux

Pourquoi Rm peut-il supprimer les fichiers en lecture seule ?

Comment rendre un fichier exécutable dans un terminal Linux ?

Pourquoi ne puis-je pas supprimer ce fichier en tant que root ?