vendredi 26 septembre 2008

ARP Reverse Like

Un petit outil écrit en C pour faire une "sorte" de Reverse ARP...

EDIT: ha hé heu oui, faut linker avec : iphlpapi.lib ws2_32.lib :p


// - Reverse ARP Like Tool -
// - by 5m0k3 -

#include "stdafx.h"
#include "string.h"
#include <stdlib.h>
#include <stdio.h>
#include <atlbase.h>
#include <shellapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>

typedef struct {
DWORD Address; // Replying address
unsigned long Status; // Reply status
unsigned long RoundTripTime; // RTT in milliseconds
unsigned short DataSize; // Echo data size
unsigned short Reserved; // Reserved for system use
void *Data; // Pointer to the echo data
IP_OPTION_INFORMATION Options; // Reply options
} IP_ECHO_REPLY, * PIP_ECHO_REPLY;


void getIP(char * ip, int bufsize)
{
struct sockaddr_in sAddIn;
struct hostent *sHostent;
char FAR buffer[ 64 ] = "";
WORD wVersionRequested;
WSADATA wsaData;
int iErr = 0;
int i = 0 ;

// Version de Winsock
wVersionRequested = MAKEWORD( 1, 1 );

// On démarre Winsock
iErr = WSAStartup( wVersionRequested, &wsaData );

// On récupère le nom de la machine
gethostname( buffer, sizeof( buffer ) );
sHostent = gethostbyname( buffer );

while( ( sHostent->h_addr_list[ i + 1 ] ) != NULL )
i++;

memcpy( &sAddIn.sin_addr.s_addr, sHostent->h_addr_list[ i ], sHostent->h_length );

strncpy(ip,inet_ntoa( sAddIn.sin_addr ),bufsize);

// On arrête Winsock
WSACleanup( );
}

int ping(char * Ip1)
{
SOCKADDR_IN sin;
DWORD Result1;
int ret=0;

// Fonction de convertion d'une chaine de caractère en structure IPv4
sin.sin_addr.s_addr = inet_addr(Ip1);

// On vérifie que les pointeurs vers les fonction ICMP ne sont pas nulls
if ((IcmpCreateFile == 0) || (IcmpSendEcho == 0))
{
ret=-1;
goto error;
}

// Initialise le service de PING
HANDLE hIP = IcmpCreateFile();
if (hIP == INVALID_HANDLE_VALUE)
{
ret=-2;
goto error;
}

// Construction du paquet ICMP
char acPingBuffer[1];
memset(acPingBuffer, '\xAA', sizeof(acPingBuffer));

PIP_ECHO_REPLY pIpe = (PIP_ECHO_REPLY)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer));

if (pIpe == 0)
{
ret=-3;
goto error;
}

pIpe->Data = acPingBuffer;
pIpe->DataSize = sizeof(acPingBuffer);

// Envoi du paquet
Result1 = IcmpSendEcho(hIP,sin.sin_addr.S_un.S_addr,acPingBuffer, sizeof(acPingBuffer), NULL, pIpe,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer), 1);

GlobalFree(pIpe);

error:

return ret;
}

void getIPfromMAC(char * searchedMAC)
{
DWORD i;
PMIB_IPNETTABLE pIpNetTable = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
DWORD dwResult;
char bufferMAC[100];

// On récupère la taille du cache ARP
dwResult = GetIpNetTable(NULL, &dwSize, 0);

if (dwResult == ERROR_INSUFFICIENT_BUFFER)
{
pIpNetTable = (MIB_IPNETTABLE *) malloc (dwSize);
}

// On récupère le cache ARP
if ((dwRetVal = GetIpNetTable(pIpNetTable, &dwSize, 0))== NO_ERROR)
{
if (pIpNetTable->dwNumEntries > 0)
{
// On boucle sur la liste récupérée
for (i=0; i<pIpNetTable->dwNumEntries; i++)
{
// On construit une chaine de caractères contenant l'adresse MAC de l'entrée en cours, pour la comparaison
_snprintf(bufferMAC,100,"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",pIpNetTable->table[i].bPhysAddr[0],pIpNetTable->table[i].bPhysAddr[1],pIpNetTable->table[i].bPhysAddr[2],pIpNetTable->table[i].bPhysAddr[3],pIpNetTable->table[i].bPhysAddr[4],pIpNetTable->table[i].bPhysAddr[5]);

if(strcmp(bufferMAC,searchedMAC)==0)
{
printf("\n >>> %s is at %s :} <<<\n",searchedMAC,inet_ntoa(*(struct in_addr *)&pIpNetTable->table[i].dwAddr));
exit(0);
}

}
}
}

}

void parse(char * ip,int * tab)
// Parse une IP (chaine) en tableau d'int
{
char buffer[4];
unsigned long i=0,j=0,k=0;

while(i<4)
{
memset(buffer,0,4);

while((ip[j]!='.')&&(j<strlen(ip)&&(k<4)))
{
buffer[k]=ip[j];
j++;
k++;
}
tab[i]=atoi(buffer);
k=0;
j++;
i++;
}
}

int main(int argc, char * argv[])
{
if(argc<4)
{
printf("\nUsage: %s <Mac To Find>xx:xx:xx:xx:xx:xx <Ip Range Start> <Ip Range End>\n",argv[0]);
exit(0);
}

int RangeCurrent[4];
int RangeStart[4];
int RangeEnd[4];
char currentIP[100];
char buff[20],buff2[20],buff3[20],buff4[20];

parse(argv[2],RangeStart);
parse(argv[3],RangeEnd);

memcpy(RangeCurrent,RangeStart,sizeof(int)*4);

while(RangeCurrent[0]<=RangeEnd[0])
{
while(RangeCurrent[1]<=RangeEnd[1])
{
while(RangeCurrent[2]<=RangeEnd[2])
{
while (RangeCurrent[3]<255)
{

itoa(RangeCurrent[0],buff,10);
itoa(RangeCurrent[1],buff2,10);
itoa(RangeCurrent[2],buff3,10);
itoa(RangeCurrent[3],buff4,10);

// snprintf au lieu _snprintf si on est pas sous Visual Studio...
_snprintf(currentIP,100,"%s.%s.%s.%s",buff,buff2,buff3,buff4);

ping(currentIP);

getIPfromMAC(argv[1]);

if((RangeCurrent[2]==RangeEnd[2])&&(RangeCurrent[3]==RangeEnd[3])&&(RangeCurrent[1]==RangeEnd[1])&&(RangeCurrent[0]==RangeEnd[0]))
{
break;
}

RangeCurrent[3]++;
}
RangeCurrent[3]=1;
RangeCurrent[2]++;
}
RangeCurrent[2]=1;
RangeCurrent[1]++;
}
RangeCurrent[1]=1;
RangeCurrent[0]++;
}
return 0;
}

Aucun commentaire: