1

How should I format my input for the return to libc attack in the following code:

void example_function(int x, const char *name)
{
    void (*foo)(int, const char *) = http_serve_none;
    char buf[1024];

    sprintf(buf, name);

    foo(x, buf);
}

Given that the stack is non executable. I want to do return to libc attack by changing foo function pointer to system in libc and not by changing the return address of example_function. What I've done so far is used the conventional method for the input:

padding + address of system ( at foo function's address ) + address of exit + ptr to string ( string = "/bin/sh" )

but however this is not working. I don't know how to format my argument in input string for system call. I searched a lot on internet but everywhere I saw calling system() using return address only.

Extra Assumption:

there are no '0' in system call address. Machine is 32 bit and sprintf is working properly i.e, storing name into the buffer buf[1024].

david watson
  • 99
  • 1
  • 10

2 Answers2

1

I solved it finally... I just passed pointer to string "/bin/sh" at address of x and it worked for me

david watson
  • 99
  • 1
  • 10
0

First, make sure your sprintf is actually sprintf and not __sprintf_chk which is going to try to thwart your overflow. You can tell it's the fortify version because you'll get a SIGABRT rather than something else (like SIGSEGV). You can turn off fortify globally, but you can also just get avoid the macro like:

(sprintf)(buf, name);

Your next problem is zeros. If the address of system has any zero bytes in it, then the sprintf is going to stop copying at that point. This is both "well, there are an awful lot of 64-bit addresses with zeros in them," and intentional. It's called ASCII armoring, and on some platforms important libc functions are made sure to have zeros in them to stop exactly this attack. (See Writing a return-to-libc attack, but libc is loaded at 0x00 in memory for a little more on that.)

You may want to explore this attack using a function in your program (i.e. not libc) that you've ensured has no zeros in it. That's a bit easier to do if you build for 32-bit. And of course, you probably want to turn off fortify and stack protection and all the other things that the compiler is doing to stop this :D (at least until you have have a basic version working; then you can turn those on one at a time).

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • I've clarified these things in the question now. please tell me how to call system() in libc to execute shellcode using foo() – david watson Feb 05 '17 at 17:11
  • The code should be very short so you should be able to post it. It's also critical to say what you mean by "doesn't work." Does it crash? Where and how? Run the debugger on it. What is the value of name and foo right before it's executed? – Rob Napier Feb 05 '17 at 17:46
  • Is there a zero anywhere in your payload? Remember, it's going to stop copying at that point. – Rob Napier Feb 05 '17 at 17:47
  • (and you have turned off ASLR, right? Otherwise `system()` isn't where you think it is.) – Rob Napier Feb 05 '17 at 18:31
  • ASLR is turned off and there is no 0 in my payload – david watson Feb 05 '17 at 18:52
  • @davidwatson well you could post it on Github and paste the link. I do that regularly here. – Bart van Kuik Feb 05 '17 at 18:56
  • A basic attack should be pretty small. Have you reduced this down to the smallest test version? Start with a `buf` size of zero, so you don't have to worry about padding. And get rid of any parsing from the commandline; just hard-code everything until you get it working. – Rob Napier Feb 05 '17 at 19:24