-2

My aim is to write an infinite loop. I have to print infinitely this string "Hello World %s" and I can just use ROP (Return-oriented programming).

gcc -fno-stack-protector loop.c -o loop  

I can compile as shown. How can I do ROP?

#include<stdio.h>
#include<string.h>

main(char argc, char ** argv){
    char buffer[80];
    strcpy(buffer,argv[1]);
    printf("Hello World %s",buffer);
    return 1;
}
vlp
  • 7,811
  • 2
  • 23
  • 51
epoxxy
  • 97
  • 1
  • 8
  • 1
    Isn't the point of your homework to learn how to do it? – Mike Andrews Sep 04 '15 at 20:11
  • 1
    When you say your purpose is "infinite loop", what does that mean? What portion of code do you need in an infinite loop? In any case, `while(1)` is probably the easiest way to do that. – PC Luddite Sep 04 '15 at 20:12
  • 1
    Also, why do you `return 1`? A non-zero exit code indicates that the program terminated with an error. – PC Luddite Sep 04 '15 at 20:13
  • This is likely machine dependent and must use *undefined behavior*, and it is unclear what *return-oriented-programming* is. Can you define this term? – Jens Sep 04 '15 at 20:14
  • no i just want a idea about this – epoxxy Sep 04 '15 at 20:14
  • Are you trying to do [this](https://en.wikipedia.org/wiki/Return-oriented_programming)? – dbush Sep 04 '15 at 20:14
  • after we compiled . we just enter parameter for example with python and with this parameter program will be Infinite Loop – epoxxy Sep 04 '15 at 20:16
  • 4
    Just to clarify, your goal is to use a buffer overflow to overwrite the return address on the stack, so instead of jumping back to the previous function in the call-stack, you instead end up jumping to the `printf` statement again? – Some programmer dude Sep 04 '15 at 20:17
  • yess https://en.wikipedia.org/wiki/Return-oriented_programming – epoxxy Sep 04 '15 at 20:19
  • @JoachimPileborg it prints only the first – epoxxy Sep 04 '15 at 20:22
  • There's nothing really wrong with the C program you show (at least not from the perspective of this exercise), the problem is that you need to know the exact stack format used by the compiler, and the input you give the program. – Some programmer dude Sep 04 '15 at 20:25
  • Which architecture will be used for this task? x86? – splotz90 Sep 04 '15 at 20:51

2 Answers2

1

So, the rough approach:

buffer is located on the stack, where the return address of the main function-callee is located. Due to the fact, that the stacks grows backwards you can overwrite the return address, since it got appended before. The stack should look like this:

[buffer data][ebp save][callee return address]...anything

It's not quite sure, but pretty likely, that the callee's return address is located after the ebp saved value, which is located after the buffer data, so you would need to give a 84 byte long array of data (not containing 0x00, because that would terminate the string) followed by the return address. The address needs to point somewhere, where your "hack" is located in memory. One possible location for this would be the stack itself, so you might want to append the machine code of the infinite loop after the return address.

It's important to note, that you have to generate machine code, that does not contain a null-byte. An example layout of the argument string, that you might give to the program should look like this:

[84 byte data][return address][machine code]

This should work on older linux kernels. Additionally this assumes you are working on a 32 bit system, so pointers are 4 bytes long. On a 64 bit system it would be 8 bytes.

qwertz
  • 14,614
  • 10
  • 34
  • 46
  • 1
    Hmm. The OP wants to use ROP and therefore I assume that DEP is active. That would mean that it is not possible to execute *own* code. – splotz90 Sep 04 '15 at 21:28
  • @splotz90 In this case you could override with main's address, which would work until the stack is completly drained. Sadly this would not be really infinite and only works if the compiler makes the caller pass arguments via registers and `argv` is not allocated on the stack somewhere near. – qwertz Sep 04 '15 at 21:31
  • Yes, I had the same idea. But I didn't write it here since it is (as you said) not really infinite. Unfortunately I have no other ideas by now. – splotz90 Sep 04 '15 at 21:39
0

I am not proficient with this, but (theoretically) your ultimate goal is to return to the startup code (either _start or e.g. glibc's __libc_start_main) which will in turn call your main() again with the same arguments. As the arguments will be the same, the code enters an endless loop.

In order to accomplish this you might need to find some gadget(s) which setup the stack and call them before returning to the above-mentioned startup code (probably only cleaning the main arguments would be needed assuming callee clean-up convention).

Please update us with yours results.

vlp
  • 7,811
  • 2
  • 23
  • 51