Vulnerability Development mailing list archives
Re: Buffer Overflow Help
From: "Steve Bonds" <kzzvt3302 () sneakemail com>
Date: Mon, 15 Nov 2004 11:11:31 -0800
Chris: First off, thanks for the superb information! In particular the specific references lead me to just where I needed to look where Google and grep had both failed. On Sun, 14 Nov 2004 22:24:17 -0800, Chris Eagle wrote:
You need to read the kernel sources to understand what happens when a process starts up. For specific information on the behavior you are witnessing, I suggest you take a look at the file fs/binfmt_elf.c, specifically the create_elf_tables function.
I looked at this and found the line where the stack pointer gets tweaked: ---- RH9 2.4.20-8 binfmt_elf.c line 159 ---- sp = (void *) (u_platform - (((current->pid+jiffies) % 64) << 7)); ---- This is introduced by the Red Hat patch "linux-2.4.20-stackcoloring.patch". (In hindsight, if I'd looked for every Red Hat kernel patch with "stack" in the name, I would have found this.)
2. The size of the padding is cyclic based on PID. If you have discovered a return address that will successfully exploit a process, then that same return address should work at least 1/64 of the time because every time the process is rerun with a pid that differs from your original pid by a multiple of 64, the padding will be the same size and all stack-based buffers should fall in the same place as they did for your successful exploit. With this in mind, if you find a return address that should work but doesn't, rerun your exploit and the change in padding will drive your payload towards your return address.
This is confirmed by the above code, with current->pid % 64 serving as one factor in determining the stack pointer.
3. The padding grows by 128 bytes each time the PID increments by one.
This follows from the "<< 7" in the above code, but this varies in practice because of the inclusion of jiffies (as you noted). The most common change in the stack pointer on my Red Hat 9 system was a decrement of 384 bytes, with a decrement of 512 bytes as a close second. (If any of you are wondering what a "jiffy" is, try this: http://www.kernelnewbies.org/glossary/#J -- it's a simple incrementing counter that wraps.) These statistics are from a test of about 300,000 runs of the "stackp" program run as fast as I could via: i=0; while true; do echo $i `./stackp`; i=`expr $i + 1`; done I never saw a jump of less than 384 bytes. The minimum stack pointer I saw was 0xbfffd9a4 and the maximum was 0xbffff924, separated into 64 slices of 128 bytes each.
RedHat throws a wrench into this as jiffies factors into their equation along with PID, so things do not seem to progress quite linearly all of the time. The maximum padding size remains restricted to 8k however.
I agree, this stack-based exploit would work nicely if I could get 8k of NOP sled in place. Unfortunately, I can't. I might be able to get 200 bytes, but this just reduces my odds from 1/64 to 1/32. Someone else has suggested a return-to-libc approach. I'm not familiar with this method of exploiting, so I'll have some reading to do. From what I've been able to discern, this method is probably better suited for a local exploit, where I can explore the libc in memory to determine where to jump. I don't yet see how this would work remotely unless libc uses the same address each time for system(). Thanks again for the excellent information on where to look for the answer to this problem. -- Steve
Current thread:
- Buffer Overflow Help eip (Nov 09)
- Re: Buffer Overflow Help Harry de Grote (Nov 10)
- Re: Buffer Overflow Help runixd (Nov 10)
- <Possible follow-ups>
- RE: Buffer Overflow Help Carlos Carvalho (Nov 10)
- Re: Buffer Overflow Help Steve Bonds (Nov 12)
- Re: Buffer Overflow Help Marco Ivaldi (Nov 12)
- Re: Buffer Overflow Help sin (Nov 12)
- Re: Buffer Overflow Help Steve Bonds (Nov 14)
- RE: Buffer Overflow Help Chris Eagle (Nov 15)
- Re: Buffer Overflow Help Steve Bonds (Nov 15)
- Re: Buffer Overflow Help sin (Nov 12)
- Re: Buffer Overflow Help Harry de Grote (Nov 10)