Les applications Python utilisent beaucoup de scripts. C'est ce que les cybercriminels utilisent pour nous mettre un «cochon» - là où nous nous attendons le moins à le voir.
L'un des avantages de Python est sa facilité d'utilisation: pour exécuter un script, il suffit de l'enregistrer dans un
.py
fichier et d'exécuter la commande python (, python my_file.py)
. Il est également facile de casser notre fichier, comme les modules, my_app.py
et de my_lib.py
continuer à connecter les modules pour utiliser la conception import...from: import my_lib from my_app.py
.
Cependant, cette simplicité et cette légèreté ont un inconvénient: plus il vous est facile d'exécuter du code à partir de différents emplacements, plus il y a de possibilités pour un attaquant d'interférer.
Placez le code Python dans un endroit sûr
Le modèle de sécurité Python repose sur trois principes:
- , sys.path , .
- , (main), sys.path.
-
python
,-c
-m
.
Supposons que vous souhaitiez exécuter une application Python qui a été "correctement" installée sur votre machine. Dans ce cas, le seul emplacement (à part le dossier avec Python installé) qui sera automatiquement ajouté à votre sys.path par défaut est le dossier avec le script principal ou le fichier exécutable.
Par exemple, si
pip
est présent /usr/bin
et que vous exécutez /usr/bin/pip
, alors sys.path
seul sera ajouté /usr/bin
. Seul root peut écrire des fichiers dans / usr / bin, donc cet emplacement est considéré comme sûr.
Néanmoins, l' accord nous oblige à le faire:
/path/to/python -m pip
. Cela évite les problèmes $PATH
et les conflits avec la documentation Windows.
En général, tout ira bien de toute façon, si vous seul avez le pouvoir d'ajouter et de modifier des fichiers dans les répertoires à partir desquels Python prend les modules pour l'importation.
Dossier Téléchargements - emplacement vulnérable
Il existe de nombreuses façons de forcer les navigateurs (et parfois d'autres logiciels) à placer des fichiers au nom arbitraire dans le dossier Téléchargements à l'insu de l'utilisateur. Cette vulnérabilité est exploitée par une attaque appelée DLL Spoofing. Dans notre cas, nous parlerons des scripts Python, mais l'idée est la même.
Les navigateurs sont devenus plus sérieux à ce sujet et essaient progressivement de s'assurer que les sites visités par l'utilisateur ne peuvent pas transférer secrètement des fichiers dans son dossier Téléchargements.
Cependant, ce problème sera très difficile à résoudre complètement: par exemple, une option est toujours disponible
Content-Disposition HTTP header’s filename*
qui permet aux sites de choisir un répertoire pour placer les fichiers téléchargés.
Comment fonctionne l'attaque
Vous exécutez l'installation:
python -m pip
. Vous téléchargez un package Python à partir d'un site Web totalement digne de confiance, qui, pour une raison quelconque, propose cependant des téléchargements directs plutôt que PyPI. C'est peut-être une sorte de version interne, peut-être une version préliminaire - aucune différence. Alors ça va à vous totally-legit-package.whl
:
~$ cd Downloads
~/Downloads$ python -m pip install ./totally-legit-package.whl
Cela semble aller, mais il s'avère qu'il y a deux semaines sur un site complètement différent que vous avez visité, certains JavaScript XSS ont téléchargé pip.py avec des logiciels malveillants dans votre dossier Téléchargements à votre insu.
Boom!
Crash!
~$ mkdir attacker_dir
~$ cd attacker_dir
~/attacker_dir$ echo 'print("lol ur pwnt")' > pip.py
~/attacker_dir$ python -m pip install requests
lol ur pwnt
Comportement étrange PYTHONPATH
Quelques paragraphes ci-dessus, j'ai écrit:
le seul emplacement (autre que le dossier installé Python) qui sera automatiquement ajouté à votre sys.path par défaut est le script principal ou le dossier exécutable.
Alors, que fait "par défaut" ici? Quels autres emplacements pouvez-vous ajouter?
Fondamentalement,
$PYTHONPATH
vous pouvez écrire n'importe quoi dans une variable d'environnement . Mais vous n'écririez pas votre position actuelle $PYTHONPATH
, n'est-ce pas?
Malheureusement, il y a une situation où vous pourriez faire cela accidentellement.
Esquissons une application Python "vulnérable" à titre d'illustration:
# tool.py
try:
import optional_extra
except ImportError:
print("extra not found, that's fine")
Créons 2 répertoires:
install_dir
et attacker_dir
. Allons-y install_dir
, puis exécutons cd attacker_dir
et plaçons là notre code malveillant par le nom tool.py
:
# optional_extra.py
print("lol ur pwnt")
Il ne reste plus qu'à l'exécuter:
~/attacker_dir$ python ../install_dir/tool.py
extra not found, that's fine
Jusqu'à présent, tout va bien.
Mais maintenant, nous allons voir une erreur commune. Beaucoup de gens recommandent d'ajouter une
$PYTHONPATH
autre chose :
export PYTHONPATH="/new/useful/stuff:$PYTHONPATH";
À première vue, cela a du sens: si vous ajoutez le projet X à
$PYTHONPATH
, peut-être, selon le projet Y, quelque chose a été ajouté là aussi, ou peut-être pas; dans tous les cas, vous ne voudriez pas écraser les modifications associées à d'autres projets. Ceci est particulièrement important lorsque vous rédigez une documentation que de nombreuses personnes utiliseront.
Et maintenant, nous sommes confrontés à un comportement «étrange»
$PYTHONPATH
. S'il $PYTHONPATH
était vide ou non installé avant le premier lancement , une ligne vide y apparaîtra, qui sera reconnue comme le répertoire courant. Vérifions ceci:
~/attacker_dir$ export PYTHONPATH="/a/perfectly/safe/place:$PYTHONPATH";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt
Pour plus de sécurité, rendons-le
$PYTHONPATH
vide et réessayons:
~/attacker_dir$ export PYTHONPATH="";
~/attacker_dir$ python ../install_dir/tool.py
lol ur pwnt
Exactement, ce n'est pas du tout sûr!
Et encore une chose : il s'avère que les situations où une variable est
$PYTHONPATH
vide et lorsqu'une variable n'est $PYTHONPATH
pas définie sont deux histoires différentes:
os.environ.get("PYTHONPATH") == ""</code> <code>os.environ.get("PYTHONPATH") == None.
Si vous voulez être sûr de nettoyer
$PYTHONPATH
, utilisez la commande unset
:
~/attacker_dir$ python ../install_dir/tool.py
extra not found, that's fine
En général, l'écriture dans une variable
$PYTHONPATH
était le moyen le plus courant de configurer l'environnement pour exécuter des applications Python. Heureusement, il s'est démodé avec l'avènement des environnements virtuels et virtualenv. Si vous avez une ancienne configuration dans laquelle quelque chose écrit $PYTHONPATH
, mais que vous pouvez vous en passer, le moment est venu de le supprimer.
Si pour une raison quelconque vous ne pouvez pas faire cela, utilisez un hack de vie :
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_1"
export PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}new_entry_2"
Dans bash et zsh, cela donnera cette sortie:
$ echo "${PYTHONPATH}"
new_entry_1:new_entry_2
Eh bien, maintenant, il n'y a plus de deux-points ni d'entrées vides.
Et enfin: si vous travaillez toujours avec
$PYTHONPATH
, utilisez des chemins absolus. Est toujours!
Le problème est bien plus grave
Il existe plusieurs options pour le développement dangereux d'événements associés au lancement de fichiers Python à partir du dossier Téléchargements:
- Exécution de python
~/Downloads/anything.py
(même s'ilanything.py
est lui - même sûr). Votre dossier Téléchargements sera ajouté àsys.path
. - Une fois lancé, le
jupyter notebook ~/Downloads/anything.ipynb
dossier Téléchargements sera également ajoutésys.path
.
Par conséquent, il est préférable de supprimer les fichiers .py et .ipynb de ce dossier avant d'exécuter.
L'exécution
cd Downloads
et le lancement ultérieur python -c
avec des instructions à l' import
intérieur ou le lancement interactif python
avec l'importation ultérieure ne résout pas complètement le problème si les fichiers importés se trouvent dans le dossier Téléchargements.
Malheureusement, ce n'est
~/Downloads/
pas le seul emplacement qui peut contenir des fichiers malveillants. Par exemple, si vous administrez un serveur sur lequel les utilisateurs peuvent télécharger des fichiers, assurez-vous que personne ou rien ne peut démarrer cd public_uploads
avant d'exécuter la commande python
.
Dans ce cas, il peut être intéressant de considérer que le code qui gère le téléchargement des fichiers est ajouté à leurs noms
.uploaded
. Cela aidera à éviter l'exécution non planifiée du script .py
.
Précautions
Si vous avez des applications écrites en Python que vous souhaitez utiliser dans votre dossier Téléchargements, définissez une règle pour entrer le chemin vers le script (
/ path / to / venv / bin / pip
), pas le module ( / path / to / venv / bin / python -m pip
).
En général, évitez simplement d'utiliser Téléchargements comme répertoire de travail actuel et déplacez les scripts que vous souhaitez utiliser vers un emplacement plus approprié avant de commencer.
Il est important de comprendre d'où Python obtient le code à partir duquel il s'exécutera. Laisser quelqu'un exécuter ne serait-ce qu'une seule ligne du script Python de gauche revient à donner le contrôle complet de votre ordinateur!
Par nécessité
En lisant un tel article avec des "trucs et astuces de vie" sur la sécurité, il est très facile de supposer que l'auteur est très intelligent, connaît un tas de petites choses que les autres devraient savoir et y penser constamment. Mais en fait, ce n'est pas entièrement vrai. Je vais expliquer.
Au fil des ans, j'ai observé avec une fréquence enviable comment les utilisateurs ne comprenaient pas d'où Python télécharge du code. Par exemple, les gens placent leur premier programme utilisant Twisted dans un fichier appelé twisted.py. Mais dans ce cas, l'importation de la bibliothèque est tout simplement impossible!
Les cybercriminels se réjouissent beaucoup plus s'ils ont réussi à attaquer les administrateurs système ou les développeurs. Si vous piratez un utilisateur, vous obtiendrez les données de cet utilisateur. Mais si vous piratez un administrateur ou un développeur et que vous le faites correctement, vous pouvez accéder à des milliers d'utilisateurs dont les systèmes sont sous le contrôle d'un administrateur, voire à des millions d'utilisateurs qui utilisent des logiciels de développement.
Par conséquent, «soyez prudent tout le temps» n'est pas une recette fiable. Les professionnels de l'informatique responsables de produits avec un grand nombre d'utilisateurs doivent vraiment être plus prudents. À tout le moins, ils devraient être informés des particularités du travail de certains outils de développement.
Bug ou fonctionnalité ...
Rien de ce que j'ai décrit ci-dessus n'est en fait un véritable "bug" ou "vulnérabilité". Je ne pense pas que les développeurs Python ou Jupyter aient fait quoi que ce soit par erreur. Le système fonctionne comme il est conçu et cela peut probablement être expliqué. Personnellement, je n'ai aucune idée de la façon dont quelque chose peut y être changé sans réduire la puissance de Python pour laquelle nous l'apprécions tellement.
L'une de mes inventions préférées est SawStop, un système de sécurité unique pour les scies à table. Il vous permet d'arrêter la rotation de la lame de scie dans les 5 millisecondes - au contact du corps humain. Avant l'invention de ce système, les scies à table étaient des outils extrêmement dangereux, mais elles remplissaient une fonction de production importante. Beaucoup de choses très utiles et importantes ont été faites sur les scies à table. Cependant, il est également vrai que les scies à table représentaient une part disproportionnée des accidents dans les ateliers de menuiserie. SawStop économise désormais beaucoup de doigts chaque année.
Donc, en détaillant les complexités des scripts Python, j'espère aussi réfléchir à certains ingénieurs en sécurité. SawStop peut-il être amené à exécuter du code arbitraire pour les interpréteurs interactifs? Quelle solution pourrait éviter certains des problèmes ci-dessus?
Restez en sécurité avec vos amis.
La publicité
VDSina propose des serveurs sécurisés sous Linux ou Windows - choisissez l'un des systèmes d'exploitation préinstallés ou installez à partir de votre image.