Bugtraq mailing list archives
Smashing the stack
From: zblaxell () tenchi myrus com (Zygo Blaxell)
Date: Mon, 20 Jan 1997 22:05:34 -0500
Please correct me everywhere where this is wrong: On iX86-based Unix systems the general method for buffer overrun attacks is to create a string consisting of three parts: 1. garbage or code here; specific length required 2. fake stack frame pointing to #1 or #3 as a return address for the currently executing function 3. garbage or code here; may have a length limit For this to work, we have to know the exact address of #2 (so we can rewrite it) and the exact address of #1 (so we can point to it in #2). If we know where #2 is, we can add or subtract to find where #1 and #3 are. "Exact" is perhaps too strong; as I wrote the previous paragraph I realized that if we can guess the mis-alignment of the buffer (usually 0) and we can guess to within a few hundred or few thousand bytes the location of #1, then we just have to have relocation code at the beginning of #1 followed by several versions of #2 for different addresses of #1. Whichever version of #2 is correct will be pulled off the stack, and it will point to the correct location of #1. As a further limitation on #1 and #3, we usually cannot have a 0 (null) character in the text of #1 or #3 (or for that matter #2). That's no problem, because we can write a decoder in X86 machine code that uudecodes a interesting program, using a fairly restrictive set of characters. Another problem is finding interesting system calls to execute. Under X86 Unix there's usually a specific instruction sequence for the kernel interface, but under Windoze you actually have to be able to do dynamic linkage to access DLLs (why?). Apparently this isn't much of a problem, and someone has already solved it by a combination of guessing and pattern matching. On the X86 memory can be read-only, read-write, or unmapped. This means that it's not possible to mark memory as readable but not executable. On every other major architecture I've heard of (except maybe the 68000), it is at least theoretically possible to mark which addresses can be used to fetch machine instructions and which ones can't, even if the operating system doesn't usually actually do that (as in the recently discussed case of the Alpha and OSF's Unix flavor, where the stack is no-execute but the heap isn't). Depending on the architecture it may be possible to fake enough machine state to do this kind of attack even without execute permission, if you can somehow manage to get a pointer to a string like "cp /bin/sh /tmp && chmod 4555 /tmp/sh" in a register, then specify the address of the system() library routine as the "return address" as in #2 above. Some architectures have bits in the stack frame that indicate what registers are on the stack, which helps a lot for this kind of attack. There are other variations that only pose trivial obstacles to buffer overrun attacks: using the Alpha again, the return address of a stack frame could be placed at a lower address than automatic variables; in this case the fake stack frame (#2 above) clobbers the stack frame of the return address of the caller of the current function. Some architectures grow the stack "upwards" in memory instead of "downwards"; this means that buffer overrun doesn't overwrite existing stack frames at all. Is there a solution for this kind of architecture? For that matter, can anyone offhand name such a machine? I've heard rumours about Crays... Small architectures pose problems of their own. A 16-bit architecture has a really small address space compared to the potential size of a buffer overrun; it could not only overrun an automatic variable and clobber a stack frame, but it could proceed on from there and overwrite the code that is copying the buffer, or the heap, or anything else in that tiny address space. The 286 has an interesting twist; it uses 16-bit registers with segment registers to boost its address range, and no memory protection worth speaking of. A 65536-byte buffer overrun could rewrite the *entire* stack. A good way to stamp out most of these attacks would be to allocate automatic variables somewhere on the heap or at least somewhere that isn't the stack. This may cause a performance penalty on CPUs that have special optimizations for data at short offsets from a particular "stack" register. This solution may be unreasonable on most real-world systems, but if you're designing a system from the ground up this is something to think of early on if it genuinely makes no difference in terms of performance. Of course, all of this just deals with automatic variable overruns that clobber the stack; in general a buffer overrun could occur anywhere, even in the heap and in dynamically allocated memory. This requires some effort to exploit, but it could be helped if the program is pushing around a lot of pointers to functions in struct's with buffers in them for some reason. It's difficult even to contrive a case where this might happen, but I'm sure we'll all recognize it when we actually see it... -- Zygo Blaxell. Unix/soft/hardware/firewall/security guru. 10th place, ACM Intl Prog Contest, 1995. Admin Linux+Solaris for food, Tshirts, anime. Pager: 1613 7608572. "I gave up $1000 to avoid working on windoze... *sigh*"-Amy Fong. "smb is a microsoft toy, like a "child" protocol that never matured"-S Boisjoli.
Current thread:
- Re: BoS: serious security bug in wu-ftpd v2.4 -- PATCH, (continued)
- Re: BoS: serious security bug in wu-ftpd v2.4 -- PATCH Henrik P Johnson (Jan 12)
- Stronghold v1.3.3: Security Release Sean B. Hamor (Jan 13)
- [linux-security] SECURITY: Important bug fix for /sbin/login Erik Troan (Jan 16)
- Smashing the stack on a DEC Alpha Lamont Granquist (Jan 16)
- Re: Smashing the stack on a DEC Alpha Digital Dreamer (Jan 16)
- Re: Smashing the stack on a DEC Alpha Julian Assange (Jan 16)
- FreeBSD Security Advisory: SA-96:21 - talkd FreeBSD Security Officer (Jan 18)
- Re: FreeBSD Security Advisory: SA-96:21 - talkd Theo de Raadt (Jan 20)
- talkd problem Theo de Raadt (Jan 20)
- Re: talkd problem David Holland (Jan 20)
- Smashing the stack Zygo Blaxell (Jan 20)
- Re: Smashing the stack David Holland (Jan 20)
- Re: Smashing the stack Bill Sommerfeld (Jan 21)
- [linux-security] write(1) leak David Holland (Jan 19)
- [linux-security] write(1) leak David Holland (Jan 20)