1
   0x08048785 <+344>:   movl   $0x0,0xc(%esp)
   0x0804878d <+352>:   movl   $0x804896c,0x8(%esp)
   0x08048795 <+360>:   movl   $0x8048973,0x4(%esp)
   0x0804879d <+368>:   movl   $0x8048973,(%esp)
=> 0x080487a4 <+375>:   call   0x8048470 <execlp@plt>

I am wondering is it possible to alter the argument that is going to the function execlp() in order to execute a shell? and if it is possible how can I change those values like 0x8(%esp)?

Thanks a lot.

  • It's not quite clear if you're interested in manually changing that assembly code by patching or are you're asking about exploitation. – NirIzr Mar 18 '17 at 14:50
1

I am wondering is it possible to alter the argument that is going to the function execlp() in order to execute a shell?

Yes, this is possible. The strings located at the memory addresses written to the stack prior to calling execlp can be patched such that /bin/sh is executed instead. If there is not enough space for the pathname of the program to execute and/or its arguments between the current memory references, the memory addresses being written to the stack will have to be patched as well to reflect the lengths of the new strings they reference.

The memory addresses being written to the stack prior to calling execlp are pointers to strings in the .rodata section of the binary, where the string pointed to by the first argument (0x8048973 in the snippet of disassembled code above) is the pathname of the program to execute (we can think of execlp as "exec load path"). If this string is changed, execlp will load the program located at the new pathname.

For reference, here is the prototype for execlp and its description from the man page:

int execlp(const char *file, const char *arg, ... /* (char *) NULL */);

The const char *arg and subsequent ellipses in the execl(), execlp(), and execle() functions can be thought of as arg0, arg1, ..., argn. Together they describe a list of one or more pointers to null-terminated strings that represent the argument list available to the executed program. The first argument, by convention, should point to the filename associated with the file being executed. The list of arguments must be terminated by a null pointer, and, since these are variadic functions, this pointer must be cast (char *) NULL.

Here is a good explanation of how execlp works: I do not understand how execlp() works in Linux

Note also that since the ISA is x86 and the compiler is GCC, the arguments to a function are written to the stack in the reverse order of their corresponding parameters in the function prototype. This means that the last argument written to the stack corresponds to the first parameter in the function prototype. In the case of execlp, the last argument written to the stack prior to calling execlp will be the pointer to the pathname of the program to load.

and if it is possible how can I change those values like 0x8(%esp)?

Patching strings in the .rodata section and patching instructions and memory addresses in the .text section can be accomplished using a hex editor like xxd or hexedit, or by using radare2.

Resources

For using GDB to patch the binary, see these:

Using GDB to modify an executable

Use gdb to Modify Binary

Debugging with GDB: Patching

ELF binary modification:

Fixing/Making Holes in ELF Binaries/Programs - Black Hat

How do I add functionality to an existing binary executable?

The ELF shell

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.