Web security

   Failles include, XSS, CRLF, injection SQL, bypass, etc…

Skip to: Content | Sidebar | Footer

logo

E-mails et anonymat

30 août, 2010 (09:27) | Scripts, Tutoriels | Rédigé par: Mathieu

* *       3 vote

Introduction

De nos jours, les e-mails ont remplacés les lettres manuscrites, la question que l’on peut se poser est comment reconnaitre l’identité de l’émetteur ?

Fausse identité

Il existe de nombreuses manieres d’envoyer un mail anonymement :

  • Utiliser une adresse e-mail jetable
  • Utiliser un logiciel spécialisé
  • Utiliser un site proposant d’envoyer des mails anonymes
  • Utiliser un compte de messagerie piraté
  • Pirater le système d’envoi de mail d’un site
  • etc …

Pour comprendre le concept d’anonymat dans le cas des envois d’e-mails, il faut comprendre la technologie SMTP ( Simple Mail Transfer Protocol ).

Script d’envoi de mails anonyme

Avant tout, si vous voulez comprendre et tester par vous meme ce procédé, voici un petit script de ma création.
J’ai épuré le code de toute notion d’objet, de design patterns et de MVC pour le rendre tres facilement comprehensible, si malgres ces effort vous ne parvenez toujours pas a comprendre, faites moi signe.

- E-mail anonyme -

From (de la forme "prenom nom ‹email›" ) ">
To (de la forme "prenom nom ‹email›, prenom nom ‹email›," ) ">
Cc (de la forme "prenom nom ‹email›, prenom nom ‹email›," ) "
Bcc (de la forme "prenom nom ‹email›, prenom nom ‹email›," ) ">
Reply To (de la forme "prenom nom ‹email›, prenom nom ‹email›," ) ">
Content type
SMTP
Subject "
Message
‹?php $smtpServer = "tls://nomDuServeurSMTP"; // pour Gmail : tls://smtp.gmail.com $port = "portUtiliseParLeServeurSMTP"; // 465 ou 587 pour gmail $timeout = "30"; $username = "******"; $password = "******"; $localhost = $_SERVER['REMOTE_ADDR']; $CRLF = "\r\n"; $dataLength = "515"; // 515 ou 4096, au choix if (isset($_POST["action"]) && ($_POST["action"]== "send")) { // Récupération des donnéees du formulaire $msg_From = $_POST['From']; $msg_To = $_POST['To']; $msg_Cc = $_POST['Cc']; $msg_Bcc = $_POST['Bcc']; $msg_ReplyTo = $_POST['ReplyTo']; ($msg_ReplyTo == "") ? $msg_ReplyTo=$msg_From : $msg_ReplyTo=$msg_ReplyTo; $msg_ContentType = $_POST['ContentType']; $msg_SMTP = $_POST['SMTP']; $msg_subject = $_POST['Subject']; $msg_message = $_POST['Message']; // Mail en HTML $headers = ""; if($msg_ContentType == "HTML"){ $msg_message = "".$msg_message.""; $headers = "MIME-Version: 1.0" . $CRLF; $headers .= "Content-type: text/html; charset=iso-8859-1" . $CRLF; } // En-tete pour envoi de mail simple (tout en spécifient l'adresse de retour ) $headers .= "From:$msg_From" . $CRLF . "Cc:$msg_Cc" . $CRLF . "Bcc:$msg_Bcc" . $CRLF . "Reply-To: $msg_ReplyTo" . $CRLF; if($msg_SMTP == "Default") { //envoie du mail au(x) destinataire(s) grace au serveur SMTP par defaut $reponse=mail($msg_To, stripslashes($msg_subject), stripslashes($msg_message), stripslashes($headers)); if($reponse){ echo "Email envoye"; } else{ echo "E-mail non envoye"; } } else { //envoie du mail au(x) destinataire(s) grace au serveur SMTP choisis preg_match_all("#<(.*)>#",$msg_From, $matches, PREG_PATTERN_ORDER); $rcpt_from = $matches[1][0]; $rcpt_to = array(); $rcpt_to_array = explode(",",$msg_To); foreach($rcpt_to_array as $nothing => $aRcpt) { preg_match_all("#<(.*)>#",$aRcpt, $matches, PREG_OFFSET_CAPTURE); array_push($rcpt_to,$matches[1][0][0]); } //envoie du mail a ou aux destinateurs par le SMTP choisis $smtpConnect = fsockopen($smtpServer, $port, $errno, $errstr, $timeout); $smtpResponse = fgets($smtpConnect, $dataLength); if(empty($smtpConnect)) { $output = "Failed to connect: $smtpResponse"; echo "".$output.""; } else { $logArray['connection'] = " Connected - $smtpResponse"; echo "Etat de la connexion :".$logArray['connection']." "; // Demande de connexion au serveur SMTP fputs($smtpConnect, "HELO $localhost" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "HELO $localhost[CRLF]"; echo "Reponse :"."$smtpResponse"." "; // Demande d'identification au serveur SMTP fputs($smtpConnect,"AUTH LOGIN" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "AUTH LOGIN[CRLF]"; echo "Reponse :"."$smtpResponse"." "; // Envoi du nom d'utilisateur fputs($smtpConnect, base64_encode($username) . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "Envoi du nom d'utilisateur en base64[CRLF] (".base64_encode($username).")"; echo "Reponse :"."$smtpResponse"." "; // Envoi du mot de passe fputs($smtpConnect, base64_encode($password) . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "Envoi du mot de passe en base64[CRLF] (".base64_encode($password).")"; echo "Reponse :"."$smtpResponse"." "; // Specification de l'emetteur fputs($smtpConnect, "MAIL FROM: <$rcpt_from>" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "MAIL FROM: $rcpt_from[CRLF]"; echo "Reponse :"."$smtpResponse"." "; // Specification des recepteurs foreach($rcpt_to as $nothing => $aReceiver) { fputs($smtpConnect, "RCPT TO: <$aReceiver>" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "RCPT TO: $aReceiver[CRLF]"; echo "mailtoresponse :"."$smtpResponse"." "; } // Specification des donnees fputs($smtpConnect, "DATA" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); echo "DATA[CRLF]"; echo "Reponse :"."$smtpResponse"." "; fputs($smtpConnect, "To: $msg_To".$CRLF . "From: $msg_From".$CRLF . "Subject: ".stripslashes($msg_subject)."".$CRLF."".stripslashes($headers)."".$CRLF."".$CRLF."".stripslashes($msg_message)."".$CRLF.".".$CRLF.""); $smtpResponse = fgets($smtpConnect, $dataLength); echo "To: $msg_To[CRLF]From: $msg_From[CRLF]Subject: ".stripslashes($msg_subject)."[CRLF]".stripslashes($headers)."[CRLF][CRLF] ".stripslashes($msg_message)."[CRLF][CRLF] "; echo "Reponse :"."$smtpResponse".""; // Say Bye to SMTP fputs($smtpConnect,"QUIT" . $CRLF); $smtpResponse = fgets($smtpConnect, $dataLength); $logArray['quitresponse'] = "$smtpResponse"; echo "Reponse :".$logArray['quitresponse'].""; } } } else { echo " Veuillez renseigner les champs "; } ?>

Le fonctionnement du protocol SMTP

Pour faire simple, lors d’un envoi d’e-mail, il y a 2 acteurs : le client et le serveur.
Le client va envoyer les données ( préalablement formatées ) du message au serveur qui va se charger d’executer le veritable envoi du mail.

Pour comprendre comment le procédé fonctionne, voici un exemple d’envoi de mail. S represente le Serveur ( qui traite la demande ) et C represente le Client ( qui fait la demande d’envoi ) :

S: 220 nomDuServeurSMTP Simple Mail Transfer Service Ready
C: HELO nomDuServeurSMTP[CRLF]
S: 250 nomDuServeurSMTP a votre service
C: AUTH LOGIN[CRLF]
S: 334 Réponse en base64
C: base64_encode(Identifiant)[CRLF]
S: 334 Réponse en base64
C: base64_encode(Mot de passe)[CRLF]
S: 235 Accepted
C: MAIL FROM:‹emetteur@serverName›[CRLF]
S: 250 OK
C: RCPT TO:‹recepteur01@serverName›[CRLF]
S: 250 OK
C: RCPT TO:‹recepteur02@serverName›[CRLF]
S: 550 No such user here
C: RCPT TO:‹recepteur03@serverName›[CRLF]
S: 250 OK
C: DATA[CRLF]
S: 354 Start mail input; end with [CRLF].[CRLF]
C: emetteur raconte sa vie ici
C: et ici aussi
C: [CRLF].[CRLF]
S: 250 OK
C: QUIT[CRLF]
S: 221 serverName Service closing transmission channel

les lignes qui vont nous intéresser sont évidemment les lignes que le client C envoi. Mais avant tout, il faut savoir que toutes les commandes se finissent par le signe [CRLF] ( Carriage Return Line Feed – \r\n ).

Bonjour

Pour informer un serveur SMTP qu’on veut utiliser ses services, on lui dit bonjour par la commande :

HELO nomDuServeur

Identification

Si l’on veut se connecter au serveur et que celui-ci demande une identification, on va utiliser la commande de demande d’identification :

AUTH LOGIN

Si la demande est approuvée, on va envoyer l’identifiant de connexion encodé en base 64, puis le mot de passe. Par exemple, si l’on veut envoyer un e-mail a partir du serveur SMTP de Gmail, on va utiliser les identifiants de connexion de sa propre adresse Gmail.

Emetteur

Une fois l’identification effectuée, on va pouvoir spécifier qui est l’émetteur de l’e-mail. On utilise pour cela la commande :

MAIL FROM: ‹adresseEmailDeEmetteur›

Attention : C’est ici que tout se joue, en effet, on peut changer l’émetteur comme on veut ici ! On peut ainsi se permettre d’envoyer un e-mail de la part de quelqu’un d’autre dans la mesure ou l’adresse de messagerie utilisée appartient au meme serveur ( Utiliser une adresse hotmail.fr sur le serveur SMTP de Gmail affichera que l’e-mail a été envoyé par Gmail… )

Récepteurs

Il faut a present désigner les destinataires du message, on utilise pour cela la commande :

RCPT TO: ‹adresseEmailDeEmetteur›

Cette commande est a exécuter autant de fois qu’il y a de destinataires.

Données

Pour envoyer des donnés ( titre, message, etc. ), il faut utiliser la commande suivante pour informer le serveur que l’on va transmettre des données :

DATA

Lorsque le serveur est bien informé de la transmission de données, on va pouvoir envoyer ces donnés :

To: nomDeDestinataire ‹adresseEmailDeDestinataire›[CRLF]
From: nomDeEmetteur ‹adresseEmailDeEmetteur›[CRLF]
Cc: nomDeDestinataire ‹adresseEmailDeDestinataire›[CRLF]
Bcc: nomDeDestinataire ‹adresseEmailDeDestinataire›[CRLF]
Reply-To: nomDeEmetteur ‹adresseEmailDeEmetteur›[CRLF]
Subject: titreDuMessage MIME-Version: 1.0[CRLF]
Content-type: text/html; charset=iso-8859-1[CRLF][CRLF]

‹html›‹head›‹title›titreDuMessage‹/title›‹/head› ‹body›contenuDuMessage‹/body›‹/html›[CRLF][CRLF]

Finalisation

Une fois les donnés envoyées, il faut bien entendu fermer la connexion avec le serveur. Pour cela, on utilise la commande :

QUIT

Détection d’incohérences :

Lorsque l’on reçoit un message et que l’on a des doutes quant au réel émetteur, on peut regarder les détails de l’e-mail, ce qui nous affichera quelque chose du genre :

Return-Path: 
Received: from adresseIP_UtiliseLorsDeL'envoi
        by mx.google.com with SMTP id w6sm12084721anb.3.2010.08.29.23.07.26
        (version=SSLv3 cipher=RC4-MD5);
        Sun, 29 Aug 2010 23:07:27 -0700 (PDT)
Message-ID: <4c7b4a9f.0663640a.4d04.7275@mx.google.com>
Date: Sun, 29 Aug 2010 23:07:27 -0700 (PDT)

On voit ici que l’adresse IP est renseignée, mais il est tres facile de cacher con adresse IP et meme de la choisir ! Donc on ne peut réellement se fier a cette information.

En revanche, le Return-Path est une information qui va être plus utile car on peut connaitre le reel identifiant de connexion utilise lors de l’envoi de l’email. Du coup, meme si l’émetteur a change l’information From, il ne pourra changer ses identifiants de connexion au serveur SMTP.

Ce sont la les seules informations autorisées au public, mais il faut savoir qu’un mail sauvegarde plus d’informations comme l’adresse Mac, etc. Les autorités affirment pouvoir remonter les sources d’emission de tout mail. Est-ce la vérité ou une tentative d’effet de peur sur quiconque voudrait tenter l’experience … ?

Article 434-23 du code pénal

Voici ce que dit le code pénal sur la substitution d’identité :

Le fait de prendre le nom d’un tiers, dans des circonstances qui ont déterminé ou auraient pu déterminer contre celui-ci des poursuites pénales, est puni de cinq ans d’emprisonnement et de 75.000 euros d’amende. [...]

Ainsi il semble légal, dans une certaine mesure, d’envoyer des e-mails anonyme ou de la part d’une autre personne , si cela l’est vraiment, je ne pense pas que cela le restera bien longtemps…

Liens externes

Lien vers la RFC 821 sur le protocole SMTP : lien
Lien vers la page Wikipedia sur le protocole SMTP : lien
Lien vers l’article 434-23 du code pénal : lien

Post to Twitter Post to Delicious Post to Facebook Post to MySpace

Partager : Post to Google Buzz Post to Twitter Post to Delicious Post to Facebook Post to MySpace