ec_fingerprint.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:13k
源码类别:

网络截获/分析

开发平台:

C/C++

  1. /*
  2.     ettercap -- fingerprinter
  3.     Copyright (C) 2001  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "include/ec_main.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #include <fcntl.h>
  22. #include <sys/time.h>
  23. #include <unistd.h>
  24. #include "include/ec_inet_structures.h"
  25. #include "include/ec_inet.h"
  26. #include "include/ec_inet_forge.h"
  27. #include "include/ec_decodedata.h"
  28. #include "include/ec_error.h"
  29. #ifdef DEBUG
  30.    #include "include/ec_debug.h"
  31. #endif
  32. #ifdef HAVE_SYS_UTSNAME_H
  33.    #include <sys/utsname.h>
  34. #endif
  35. #define NUM_TESTS 7
  36. #define NUM_CONDS 6
  37. #define MSS 265
  38. // global data...
  39. int IPS, IPD, sock, MTU;
  40. u_short open_port=0, closed_port=0, PORTS;
  41. long SYN_SEQ;
  42. unsigned short IP_ID;
  43. unsigned char MACS[6];
  44. unsigned char MACD[6];
  45. // Static arrays? bleah...
  46. char packet_stamp[NUM_TESTS][NUM_CONDS][10];
  47. char test_name[NUM_CONDS][10];
  48. // protos....
  49. char * Fingerprint_OS(char *IP);
  50. char * Fingerprint_MAC(char *MAC);
  51. //--------------------------
  52. int Fingerprint_Match(char *mycond, char *fpcond)
  53. {
  54.    int matched=0; char *single_cond, *deadend=NULL;
  55.    deadend=fpcond+strlen(fpcond);
  56.    if (deadend==fpcond) matched=1;
  57.    while( !matched && (unsigned long)fpcond<(unsigned long)deadend )
  58.    {
  59.       single_cond=(char *)strtok(fpcond,"|");
  60. if (!strcmp(mycond,single_cond)) matched=1;
  61. fpcond+=strlen(single_cond)+1;
  62.    }
  63.    return matched;
  64. }
  65. void Fingerprint_send_probes()
  66. {
  67.    char *probe_pck;
  68. #define TH_BOGUS 64
  69. #define OPTIONS "0303120102040111101277777777000000000000"
  70. #define OPT_LEN 20
  71.    PORTS++;
  72.    probe_pck=(char *)Inet_Forge_packet(ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN);
  73.    Inet_Forge_ethernet( probe_pck, MACS, MACD, ETH_P_IP );
  74.    Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  75.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS, open_port,  SYN_SEQ, 0, TH_BOGUS|TH_SYN, 0, 0);
  76.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS , OPT_LEN);
  77.    Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN);
  78.    Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  79.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+1, open_port,  SYN_SEQ, 0, 0, 0, 0);
  80.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  81.    Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN);
  82.   Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  83.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+2, open_port,  SYN_SEQ, 0, TH_SYN|TH_FIN|TH_URG|TH_PSH, 0, 0);
  84.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  85. Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN);
  86. Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  87.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+3, open_port,  SYN_SEQ, 0, TH_ACK, 0, 0);
  88.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  89. Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN );
  90. Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  91.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+4, closed_port,  SYN_SEQ, 0, TH_SYN, 0, 0);
  92.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  93. Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN );
  94. Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  95.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+5, closed_port,  SYN_SEQ, 0, TH_ACK, 0, 0);
  96.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  97. Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN );
  98.    Inet_Forge_ip( probe_pck + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  99.    Inet_Forge_tcp( probe_pck + ETH_HEADER + IP_HEADER, PORTS+6, closed_port,  SYN_SEQ, 0, TH_FIN|TH_PSH|TH_URG, 0, 0);
  100.    Inet_Forge_Insert_TCPOpt( probe_pck + ETH_HEADER + IP_HEADER, OPTIONS ,OPT_LEN );
  101. Inet_SendRawPacket(sock, probe_pck, ETH_HEADER + IP_HEADER + TCP_HEADER + OPT_LEN );
  102.    Inet_Forge_packet_destroy( probe_pck );
  103. }
  104. void Fingerprint_parse_probes()
  105. {
  106.    ETH_header *eth;
  107.    IP_header *ip;
  108.    TCP_header *tcp;
  109.    short type;
  110.    int len;
  111.    char *probe_pck;
  112.    TIME_DECLARE;
  113.    TIME_START;
  114.    probe_pck=(char *)Inet_Forge_packet(MTU);
  115.    do
  116.    {
  117. len=Inet_GetRawPacket(sock,probe_pck,MTU,&type);
  118. TIME_FINISH;
  119. if (len>0 && type==PACKET_HOST)
  120. {
  121.    eth=(ETH_header *)probe_pck;
  122.    if (ntohs(eth->type)==ETH_P_IP)
  123.    {
  124. ip=(IP_header *)(probe_pck+ETH_HEADER);
  125. if (ip->proto==IPPROTO_TCP && ip->source_ip==IPD)
  126. {
  127.    tcp=(TCP_header *)(probe_pck+ETH_HEADER+IP_HEADER);
  128.    if ( (u_short)ntohs(tcp->dest)>=PORTS && (u_short)ntohs(tcp->dest)<PORTS+NUM_TESTS)
  129.    {
  130. char *p, *q, *arrive;
  131. unsigned int num_test;
  132. num_test=ntohs(tcp->dest)-PORTS;
  133. // Replied
  134. strcpy(&packet_stamp[num_test][0][0],"Y");
  135.     // DF flag
  136. if(ntohs(ip->frag_and_flags) & 0x4000)
  137. {
  138.    strcpy(&packet_stamp[num_test][1][0],"Y");
  139. }
  140. else strcpy(&packet_stamp[num_test][1][0], "N");
  141. // Window Size
  142. sprintf(&packet_stamp[num_test][2][0],"%hX",ntohs(tcp->window));
  143. // ACK Sequence
  144. if (ntohl(tcp->ack_seq) == SYN_SEQ+1)
  145.    strcpy(&packet_stamp[num_test][3][0],"S++");
  146. else if (ntohl(tcp->ack_seq) == SYN_SEQ)
  147.    strcpy(&packet_stamp[num_test][3][0],"S");
  148. else
  149.    strcpy(&packet_stamp[num_test][3][0],"O");
  150. // Flags
  151. p=&packet_stamp[num_test][4][0];
  152. *p='';
  153. if (tcp->flags & 0x40)   *p++='B'; // BOGUS
  154. if (tcp->flags & TH_URG) *p++='U';
  155. if (tcp->flags & TH_ACK) *p++='A';
  156. if (tcp->flags & TH_PSH) *p++='P';
  157. if (tcp->flags & TH_RST) *p++='R';
  158. if (tcp->flags & TH_SYN) *p++='S';
  159. if (tcp->flags & TH_FIN) *p++='F';
  160. *p++='';
  161. // TCP Options
  162. p=&packet_stamp[num_test][5][0];
  163. q=((char *)tcp) + TCP_HEADER;
  164. arrive = ((char *)tcp) + (tcp->doff*4);
  165. while(q<arrive)
  166. {
  167.    int opcode;
  168.    opcode=*q++;
  169.    if (!opcode) {
  170. *p++ = 'L';
  171. break;
  172.    } else if (opcode == 1) {
  173.      *p++ = 'N';
  174.    } else if (opcode == 2) {
  175.      *p++ = 'M';
  176.      q++;
  177.      if (ntohs(ptohs(q)) == MSS)
  178.       *p++ = 'E';
  179.      q+=2;
  180.    } else if (opcode == 3) {
  181.      *p++ = 'W';
  182.      q+=2;
  183.    } else if (opcode == 8) {
  184.      *p++ = 'T';
  185.      q+=9;
  186.    }
  187. }
  188. *p++='';
  189.    }
  190. }
  191.    }
  192. }
  193.    }while(TIME_ELAPSED<1);
  194.    Inet_Forge_packet_destroy( probe_pck );
  195. }
  196. void Fingerprint_Init_Test()
  197. {
  198.    sprintf(test_name[0],"Resp");
  199.    sprintf(test_name[1],"DF");
  200.    sprintf(test_name[2],"W");
  201.    sprintf(test_name[3],"ACK");
  202.    sprintf(test_name[4],"Flags");
  203.    sprintf(test_name[5],"Ops");
  204.    strcpy(&packet_stamp[0][0][0],"N");
  205.    strcpy(&packet_stamp[1][0][0],"N");
  206.    strcpy(&packet_stamp[2][0][0],"N");
  207.    strcpy(&packet_stamp[3][0][0],"N");
  208.    strcpy(&packet_stamp[4][0][0],"N");
  209.    strcpy(&packet_stamp[5][0][0],"N");
  210.    strcpy(&packet_stamp[6][0][0],"N");
  211. }
  212. char *Fingerprint_Make_Finger_print()
  213. {
  214.    FILE *file;
  215.    int i, no_match=1;
  216.    char dummy[500];
  217.    char num_test[5];
  218.    char *condition;
  219.    char *test;
  220.    static char osname[500];
  221.    #include "include/ec_install_path.h"
  222.    char database[sizeof(path)+22];
  223.    static char res_list[2000];
  224.    strcpy(database, path);
  225.    strcat(database, "nmap-os-fingerprints");
  226.    file = fopen(database, "r");
  227.    if (!file)
  228.       file = fopen("./share/nmap-os-fingerprints","r");
  229.       if (!file)
  230.          Error_msg("Can't open "nmap-os-fingerprints" file !!");
  231.    Fingerprint_Init_Test();
  232.    Fingerprint_send_probes();
  233.    Fingerprint_parse_probes();
  234. res_list[0]=0;
  235.    loop
  236.    {
  237. char *To_EOF;
  238. while( (To_EOF=fgets(osname,500,file)) && !strstr(osname,"Fingerprint") );
  239. if (!To_EOF) break;
  240. no_match=0;
  241. for (i=1; i<=7 && !no_match; i++)
  242. {
  243.    char *deadend;
  244.    sprintf(num_test,"T%1d",i);
  245.    while(fgets(dummy,500,file) && !strstr(dummy,num_test));
  246.    test=dummy+3;
  247.    dummy[strlen(dummy)-2]=0;
  248.    deadend=test+strlen(test);
  249.    while( !no_match &&  (unsigned long)test<(unsigned long)deadend )
  250.    {
  251. int j; char *pos=NULL;
  252. condition=(char *)strtok(test,"%");
  253. test+=strlen(condition)+1;
  254. for (j=0; j<NUM_CONDS && pos!=condition; j++)
  255.     pos=(char *)strstr(condition,test_name[j]);
  256. condition +=  strlen(test_name[j-1])+1;
  257. if ( !Fingerprint_Match(&packet_stamp[i-1][j-1][0],condition) ) no_match=1;
  258.    }
  259. }
  260. if (!no_match)
  261. {
  262.     strcat(res_list,osname+sizeof("Fingerprint"));
  263.   }
  264.    }
  265.    fclose(file);
  266. if (!strcmp(res_list, ""))
  267. strcpy(res_list, "Not found in the databasen");
  268.    //if ( res_list[strlen(res_list)-1] == 'n') res_list[strlen(res_list)-1] = 0; // trim the trailing n
  269.    return res_list;
  270. }
  271. void Fingerprint_Parse_packet(char *buffer)
  272. {
  273.    IP_header  *ip;
  274.    TCP_header *tcp;
  275.    ip = (IP_header *) (buffer+ETH_HEADER);
  276.    if (ip->source_ip==IPD && ip->dest_ip==IPS && ip->proto==IPPROTO_TCP)
  277.    {
  278.      tcp = (TCP_header *) ((int)ip + ip->h_len * 4);
  279.      if ( (tcp->flags & TH_SYN) && (tcp->flags & TH_ACK) )
  280.         open_port=ntohs(tcp->source);
  281.      if ( (tcp->flags & TH_RST) && ntohs(tcp->dest)==PORTS )
  282.         closed_port=ntohs(tcp->source);
  283.    }
  284. }
  285. void Fingerprint_Simple_Scan()
  286. {
  287.    int i, startP, finP;
  288.    char *pck_to_send;
  289.    TIME_DECLARE;
  290.    startP = 10;  finP = 150;
  291.    pck_to_send = (char *)Inet_Forge_packet(MTU);
  292.    Inet_Forge_ethernet( pck_to_send, MACS, MACD, ETH_P_IP );
  293.    Inet_Forge_ip( pck_to_send + ETH_HEADER, IPS, IPD, TCP_HEADER, IP_ID++, 0, IPPROTO_TCP);
  294.    for (i=startP; i<=finP; i++)
  295.    {
  296.       Inet_Forge_tcp( pck_to_send + ETH_HEADER + IP_HEADER, PORTS, i,  SYN_SEQ, 0, TH_SYN, 0, 0);
  297.       Inet_SendRawPacket(sock, pck_to_send, ETH_HEADER + IP_HEADER + TCP_HEADER );
  298.       if (!(i%5)) usleep(500);
  299.    }
  300.    TIME_START;
  301.    do
  302.    {
  303.       Inet_GetRawPacket(sock, pck_to_send, MTU, NULL);
  304.       Fingerprint_Parse_packet(pck_to_send);
  305.       TIME_FINISH;
  306.    } while (TIME_ELAPSED <2 && (!open_port || !closed_port) );
  307.    Inet_Forge_packet_destroy( pck_to_send );
  308. }
  309. char * Fingerprint_OS(char *IP)
  310. {
  311. char *res_name;
  312. #ifdef DEBUG
  313.    Debug_msg("Fingerprint_OS -- [%s]", IP);
  314. #endif
  315. if (!strcmp(IP, Inet_MyIPAddress()))
  316. {
  317. #ifdef HAVE_SYS_UTSNAME_H
  318. struct utsname buf;
  319. res_name = (char *)malloc(50);
  320. uname(&buf);
  321. strcpy(res_name, buf.sysname);
  322. strcat(res_name, " ");
  323. strcat(res_name, buf.release);
  324. return res_name;
  325. #else
  326. return "Yourself ;) try `uname -sr`";
  327. #endif
  328. }
  329.    IPD = inet_addr(IP);
  330.    sock = Inet_OpenRawSock(Options.netiface);
  331.    fcntl(sock, F_SETFL, O_NONBLOCK);
  332.    Inet_GetIfaceInfo(Options.netiface, &MTU, MACS, (unsigned long *)&IPS, 0);
  333.    memcpy(MACD, Inet_MacFromIP(inet_addr(IP)), 6);
  334.    srand(time(0)); IP_ID = PORTS = SYN_SEQ = rand()%(0xFFFE)+1;
  335. open_port = 0;
  336. closed_port = 0;
  337.    Fingerprint_Simple_Scan();
  338.    if (!open_port || !closed_port)
  339.       return "Can't find ports to probe";
  340.    else
  341.    {
  342. res_name = Fingerprint_Make_Finger_print();
  343. if (!res_name)
  344.        return "No match in database";
  345. else
  346.     return res_name;
  347.    }
  348. }
  349. char * Fingerprint_MAC(char *MAC)
  350. {
  351.    FILE *fto;
  352.    static char adname[200];
  353.    char ScanMAC[20];
  354.    #include "include/ec_install_path.h"
  355.    char file[sizeof(path)+20];
  356. #ifdef DEBUG
  357.    Debug_msg("Fingerprint_MAC -- [%s]", MAC);
  358. #endif
  359.    strcpy(file, path);
  360.    strcat(file, "mac-fingerprints");
  361.    fto = fopen(file, "r");
  362.    if (!fto)
  363.       fto = fopen("./share/mac-fingerprints","r");
  364.       if (!fto)
  365.          Error_msg("Can't open "mac-fingerprints" file !!");
  366.    while (fgets(adname, 200, fto))
  367.    {
  368.       int i;
  369.       for (i=0; i<200;i++)
  370.          if (adname[i]=='n')
  371.             adname[i]=0;
  372.       sscanf(adname,"%s",ScanMAC);
  373.       if (MAC==strstr(MAC,ScanMAC))
  374.       {
  375.          fclose(fto);
  376.          return adname+strlen(ScanMAC)+2;
  377.       }
  378.    }
  379.    fclose(fto);
  380.    return "unknown";
  381. }
  382. /* EOF */