vendredi 25 janvier 2008

Sniffer TCP with Raw Sockets

Plop all :)
aujourd'hui je me penche un peu sur les raw sockets et je vous propose ce petit code qui permet de sniffer les trames TCP entrentent. Bon ici je montre que les bases mais le code ne demande qu'à être renchérit.

Le principe est simple, on créé un socket qui va écouter et intercepter toutes les données qui passent notre réseau. La création du socket se fait presque normalement, si ce n'est qu'il ne faut pas oublier d'activer le mode promiscuous de la carte réseau, à savoir grace à la fonction WSAIoctl().

Référence de la fonction : http://msdn2.microsoft.com/en-us/library/ms741621(VS.85).aspx

Prototype de la fonction WASIoctl() :

int WSAIoctl(
__in SOCKET s,
__in DWORD dwIoControlCode,
__in LPVOID lpvInBuffer,
__in DWORD cbInBuffer,
__out LPVOID lpvOutBuffer,
__in DWORD cbOutBuffer,
__out LPDWORD lpcbBytesReturned,
__in LPWSAOVERLAPPED lpOverlapped,
__in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine


Ensuite on fait un simple recv() et le tour est joué, on peux récupérer la trame TCP.
Viens ensuite le traitement, il faut récupérer les données dont nous avons besoin.
Voyons ces deux schémas issuent de www.frameip.com


Entête IP:





Entête TCP:





De là on peut en déduire deux structures, une qui contiendra l'entete IP et l'autre l'entete TCP. Toutefois ceci reste minimaliste.
typedef struct iphdr //Entete IP
{
unsigned char IHL:4;
unsigned char Version :4;
unsigned char TypeOfService;
unsigned short TotalLength;
unsigned short ID;
unsigned char FlagOffset :5;
unsigned char MoreFragment :1;
unsigned char DontFragment :1;
unsigned char ReservedZero :1;
unsigned char FragOffset;
unsigned char Ttl;
unsigned char Protocol;
unsigned short Checksum;
unsigned int Source;
unsigned int Destination;
}IP_HDR;

typedef struct tcphdr // Entente TCP
{
unsigned short PortSource;
unsigned short PortDest;
unsigned int seqnum;
unsigned int acknum;
unsigned char unused:4, tcp_hl:4;
unsigned char flags;
unsigned short window;
unsigned short checksum;
unsigned short urgPointer;
} TCP_HDR;

Et voilà il ne nous reste plus qu'à remplir les structures et le tour est joué!

De la doc sur : http://www.frameip.com/
http://msdn2.microsoft.com/en-us/library/ms741394%28VS.85%29.aspx

Le code : main.cpp

Le projet + binaire : SnifferTCP.zip

Have Fun ;)
lilxam.

dimanche 13 janvier 2008

PE Analyser

Bonjour,
aujourd'hui je me penche sur le format PE. J'ai donc fais ce petit programme qui permet de récupérer quelques informations sur les entetes, sections et la table des imports. J'ai essayé de faire un code clair ainsi que d'accompagner toutes les structures que j'ai utilisé de leur définition, elles se situent toutes dans winnt.h.

Voici le code : PEAnalyser.cpp
De la doc : Format PE

Have Fun ;)
lilxam

samedi 12 janvier 2008

Injection de dll dans un processus

Aujourd'hui je vais vous présenter une méthode plutot connue pour injecter une dll dans un processus. Pour celà on va d'abord faire un loader qui s'ocuppera de charger notre dll dans un processus puis on construira ensuite celle-ci.
Pour le loaders on distingue 5 étapes :

1.Récupérer l'adresse de LoadLibraryA()
Pour récupérer l'adresse de LoadLibraryA() il suffit d'utiliser la fonction GetModuleHandleA(). Le prototype de la fonction :

HMODULE WINAPI GetModuleHandle(
__in_opt LPCTSTR lpModuleName
);


2.Ouvrir le processus voulu
Pour celà on créera une liste de tous les processus actifs et on récupèrera l'id de celui voulu. On ouvrira simplement le processus avec OpenProcess(). Le prototype de la fonction :
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);


3.Allouer un espace de mémoire dans le processus
Pour allouer un espace de mémoire on utilisera VirtualAllocEx(). Le prototype de la fonction :
LPVOID WINAPI VirtualAllocEx(
__in HANDLE hProcess,
__in_opt LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);


4.Ecrire les donnes necessaires au chargement de la dll
Pour ceci on va utiliser WriteProcessMemory(). On pourrait écrire quelque chose du genre LoadLibraryA("dll.dll") dans le processus, ce qui donne en assembleur :
PUSH offset_nom_dll
CALL LoadLibraryA
RET
Mais pour faire simple on se contentera d'écrire seulement le nom de la dll dans l'espace de mémoire et on éxecutera LoadLibraryA() grace à notre thread.
Le prototype de la fonction WriteProcessMemory est :
BOOL WINAPI WriteProcessMemory(
__in HANDLE hProcess,
__in LPVOID lpBaseAddress,
__in LPCVOID lpBuffer,
__in SIZE_T nSize,

__out SIZE_T* lpNumberOfBytesWritten
);

5.Créer un thread dans le processus afin d'excuter le code écris dans l'espace de mémoire alloué
C'est l'étape la plus importante, ici on utilisera CreateRemoteThread() pour créer un thread dans le processus qui executera LoadLibraryA() avec en parametre le nom de notre dll. Le prototype de la fonction :
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
);

Viens ensuite notre dll. Je vais faire simple pour bien montrer le concept.
Lorsqu'on va charger notre dll avec LoadLibaryA(), la fonction va ensuite appeler la fonction main de la Dll avec DLL_PROCESS_ATTACH comme second parametre. On vérifiera donc que le seconde parametre est bien à cette valeur et le tour est joué.
Vous trouverez plus d'info ici : http://msdn2.microsoft.com/en-us/library/ms684175(VS.85).aspx
et ici :
http://msdn2.microsoft.com/en-us/library/ms682583(VS.85).aspx

Le code de la dll : Injectme.cpp
Le code du loader : DllInjector.cpp

Voilà ce sera tout pour aujourd'hui.
Have Fun :)
lilxam.