NewbieContest

Général => Proposition de tutoriaux => Discussion démarrée par: Lord357 le 04 Septembre 2011 à 14:10:11



Titre: Injection de Code Episode #1
Posté par: Lord357 le 04 Septembre 2011 à 14:10:11
0. Sommaire

1. Pré-requis
2. Qu'est ce qu'une injection de code ?
3. Principe de fonctionnement
4. Exemple !
5. Connaître son ennemi
6. Quelques liens

1. Pré-requis

Pour comprendre ce papier vous aurez besoin des éléments suivants:
  • Un minimum de programmation sous Windows (API)
  • Un language de programmation (n'importe quel language compilé pour l'injection, ne pas confondre avec le code à injecter)
  • Comprendre un peu l'ASM pour le POC mais ça reste vraiment basique

2. Qu'est ce qu'une injection de code ?

Une injection de code consiste à placer du code exécutable dans un processus distant pour l'exécuter. Pour imager, c'est un peu à la programmation ce que le BOF est au hacking.

Quelle est l'utilité d'injecter du code ? Sincèrement je n'en vois pas d'autres que le developpement de code malveillant, dans le but de bypasser les firewalls personnels. Les antivirus l'ont d'ailleurs bien compris, et il y a de fortes chances que les moteurs d'analyse heuristique vous renvoie dans vos 15 mètres (heureusement d'ailleurs) si un tel comportement est detecté.

Il existe plusieurs méthodes, certaines sont excessivement simples (dont celle que nous voyons dans ce papier), d' autres sont en revanche bien plus complexe (notamment la méthode de "Ghost Writing"). Le niveau de difficulté dans l'implémentation est bien sur lié à la volonté de passer inaperçu.
 
3. Principe de fonctionnement

La méthode expliquée ici repose sur l'utilisation intensive d'API windows dont la liste est présentée ci-dessous. Les différentes étapes de mises en place sont les suivantes :
  • Allouer un espace dans la mémoire du processus distant. La taille de cet espace est bien évidemment celle du code à injecter.
  • Ecrire le code dans l'espace précédemment récupéré
  • Créer une thread pour exécuter le code

Voici la fameuse liste d'API :

Code:
LPVOID WINAPI VirtualAllocEx(
  __in      HANDLE hProcess,
  __in_opt  LPVOID lpAddress,
  __in      SIZE_T dwSize,
  __in      DWORD flAllocationType,
  __in      DWORD flProtect
);

Cette API sert à allouer de la mémoire dans le processus distant, dont le handle aura au préalable été récupéré.


Code:
BOOL WINAPI WriteProcessMemory(
  __in   HANDLE hProcess,
  __in   LPVOID lpBaseAddress,
  __in   LPCVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T *lpNumberOfBytesWritten
);

Cette API nous permet d'écrire dans la mémoire d'un processus (local ou distant).


Code:
HANDLE WINAPI CreateRemoteThread(
  __in   HANDLE hProcess,
  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in   SIZE_T dwStackSize,
  __in   LPTHREAD_START_ROUTINE lpStartAddress,
  __in   LPVOID lpParameter,
  __in   DWORD dwCreationFlags,
  __out  LPDWORD lpThreadId
);

Cette API va créer la thread en pointant sur le code à executer.

4. Exemple !

Il n'y a pas grand chose à dire de plus c'est vraiment simple. Des liens sont fournis à la fin du billet pour expliquer plus en détails les API utilisées. Nous passons donc directement à l'exemple en ... ASM (FASM) évidemment ! Pour notre POC, nous allons simplement injecter l'instruction "ret" (0x3C) qui aura pour effet de sortir immédiatement de la thread que nous aurons précédemment créée.

Vous ne pourrez peut-être pas constater l'injection sans debugger (pour des question de priorité des threads, parce qu'un ret sur une thread fait sortir la thread et pas le programme entier, etc). Il vous faudra donc potentiellement attacher la cible de l'injection avec votre debugger favori pour jouer avec.

Code:
format PE GUI 4.0
entry start

include 'win32a.inc'

;section de code
section '.text' code readable executable

start:
   ;alloc du buffer sur la pile pour la création du process
   push ebp
   mov ebp, esp
   sub ebp, 84 ;processinfo + startupinfo
   mov esi, ebp
   lea edi, [esi + 16]

   ;on monte la cible de l'injection en mémoire
   push esi
   push edi
   push 0
   push 0
   push 0
   push 0
   push 0
   push 0
   push szTarget
   push 0
   call [CreateProcess]

   ;on récupère un handle
   mov esi, dword[esi]
   mov [hwnd], esi

   ;on rétablit la pile
   add ebp, 84
   pop ebp

  ;alloc de la mémoire dans le process distant
   push PAGE_EXECUTE_READWRITE
   push MEM_COMMIT
   push [dwSize]
   push 0
   push [hwnd]
   call [VirtualAllocEx]
   mov [pBuffer], eax ;on récupere un pointer sur le buffer alloué
    
   ;écriture du code :)
   push [dwByteWritten]
   push [dwSize]
   push CodetoInject
   push [pBuffer]
   push [hwnd]
   call [WriteProcessMemory]

   ;finalement on crée la thread qui va éxécuter notre code
   push 0
   push 0
   push 0
   push [pBuffer]
   push 0
   push 0
   push [hwnd]
   call [CreateRemoteThread]

CodetoInject:
   ret

sizeOfCode = $ - CodetoInject


;données !
section '.data' data readable writeable
   hwnd dd ?
   dwByteWritten dd ?
   pBuffer dd ?
   dwSize dd sizeOfCode
   szTarget db "C:\test\test.exe", 0

   PAGE_EXECUTE_READWRITE equ 040h
   MEM_COMMIT equ 1000h



;les imports !
section '.idata' import data readable writeable

;on importe kernel32.dll !
library kernel,'KERNEL32.DLL'

;notre trio infernal d'API + le CreateProcess pour lancer la cible
import kernel,\
   CreateProcess, 'CreateProcessA',\
   VirtualAllocEx,'VirtualAllocEx',\
   WriteProcessMemory, 'WriteProcessMemory',\
   CreateRemoteThread, 'CreateRemoteThread'

Bien évidement dans la vraie vie, injecter un ret n'a aucun intérêt. Laissez libre court à votre créativité ! Il y a aussi quelques embûches liées au système d'exploitation, le plus gros étant d'avoir les permissions sur le processus cible.

5. Connaître son ennemi

Vous aurez surement une impression de déja-vu si vous lisez ces quelques lignes, et si vous avez lu un autre de mes documents sur l'inline hook. C'est normal. Si vous avez retenu, vous comprendrez facilement pourquoi.
Pour se protéger des injections de code intampestive, il convient se se prémunir en amont à l'aide de logiciels spécifiquement conçus dans l'objectif de protéger la mémoire du système. Process Guard en est l'exemple, il est d'ailleurs particulièrement efficace s'il est correctement configuré. Les antivirus (performance mise à part) vont également (en général) vérifier les comportements de ce type à l'aide d'analyse heuristique. Les firewall personnels (comme BlackIce ou ZoneAlarm) fournissent quant à eux une protection en temps réel en crochetant (et oui) les API (userland ou kernel) servant ce but, et offre ainsi une protection relativement efficace.

Vous pouvez également analyser l'anatomie du code injecté avec Ollydbg, il vous suffirait d'attacher le processus infecter et de regarder du coté des threads en cours. Ce sujet appartient au reverse engineering, ça ne sert à RIEN de le traiter ici.

Ceci dit, si vous n'avez aucune protection et que ces utilitaires vous donne un résultat positif, vos données vous ont probablement déja été dérobées, vous êtes déjà sous surveillance !

6. Quelques liens

  • VirtualAllocEx : http://msdn.microsoft.com/en-us/library/aa366890(v=vs.85).aspx
  • WriteProcessMemory : http://msdn.microsoft.com/en-us/library/ms681674(v=vs.85).aspx
  • CreateRemoteThread : http://msdn.microsoft.com/en-us/library/ms682437(v=vs.85).aspx


Titre: Re : Injection de Code Episode #1
Posté par: the lsd le 04 Septembre 2011 à 23:06:39
Bon comme d'hab hein, c'est oui pour moi, sans souci !

Niveau faute, j'ai été choqué par le éxiste, il n'y a pas d'accent sur le e. J'ai pas regardé en détail, mais j'en ai pas vu.
Au niveau du fond, ça me parait correct, j'ai pas vu d'erreur (j'ai pas regardé l'ASM par contre).

Moi en tout cas, j'adore, c'est un sujet qui n'existe quasiment pas sur NC, ca change des bêtes tutos xss/sql, ca va beaucoup plus loin.

Enjoy

The lsd


Titre: Re : Injection de Code Episode #1
Posté par: Lord357 le 05 Septembre 2011 à 09:47:55
merci :)

Ne publiez pas de suite, je vais ajouter quelques éléments de prévention (comme demandé sur le tuto TLS).


Titre: Re : Injection de Code Episode #1
Posté par: Asteriksme le 05 Septembre 2011 à 13:39:32
Effectivement ça change des autres tutos ! et des autres propositions aussi, vu que dans les tiennes y a peu de fautes :)
Moi j'y connais pas grand chose en assembleur (pour comprendre le code faut que je réfléchisse vachement, j'ai aucune pratique :p) et encore moins en API donc niveau contenu, je peux pas vraiment donner d'avis pertinent ! Mais au niveau de la forme, c'est toujours bien présenté, on comprend ce que tu dis, et c'est relativement pédagogique (enfin, surtout si on a un background dans le domaine j'imagine ^^)
Donc pour moi c'est bon aussi !


Titre: Re : Injection de Code Episode #1
Posté par: Lord357 le 06 Septembre 2011 à 18:17:26
Vous pouvez aussi balancer celui ci. Vous noterez qu'a deux lignes pret, c'est la même chose que pour le inline hook, c'est normal vu que le inline hook est placé via une injection, et que se prémunir d'une injection c'est se prémunir d'un inline hook :-) (c'est redondant, mais c'est vraiment comme ça)


Titre: Re : Injection de Code Episode #1
Posté par: s3th le 06 Septembre 2011 à 21:56:26
bon tuto  =)

Code:
4. Exemple !...   Pour notre POC, nous simplement injecter l'instruction "ret" (0x3C) qui aura pour effet de sortir immédiatement de la thread que nous aurons précédemment créée. 

il manque un verbe (allons) entre nous et simplement.



Titre: Re : Injection de Code Episode #1
Posté par: Lord357 le 06 Septembre 2011 à 22:07:06
Mis à jour. Désolé pour ce genre de faute, sans dec j'ai honte. Pour ma défense, je travaille d'un portable et le touchpad avec mes gros doigts... des fois je ne vois pas les fausses manip' (mais je pourrais mieux me relire, j'avoue :))