[C] datainjectie in IPC tussen 2 closed-source programma's

Pagina: 1
Acties:

  • raphidae
  • Registratie: Februari 2001
  • Laatst online: 06-01-2025

raphidae

...antichrist...

Topicstarter
Ik probeer een commando te 'injecteren' in de IPC van twee closed-source binaries, Programma A (een daemon) en Programma C.

Programma A voert Programma C uit als een child en stuurt newline-terminated commando's naar de stdin van C, Programma C reageert vervolgens met newline-terminated antwoorden op stdout.

Vrij standaard tot nu toe.

Nou wil ik dat Programma C twee commando's van mij uitvoert, voordat Programma C de commando's van Programma A ontvangt en gaat uitvoeren.

Dus ik heb een Programma B nodig die 'ertussen' zit en deze commando's naar C stuurt.

Ik heb wat aangerommeld en ik heb dit op het moment als Programma B:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <unistd.h>   
#include <stdio.h> 
#include <stdlib.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(){
  pid_t pid;
  char buffer[256];
  int rv;
  int inpipe[2];
  FILE * stream;
  fd_set rfds;  
  int retval;   

  if(pipe(inpipe)){
    fprintf(stderr,"pipe error!\n");
    exit(1);
  }
  if((pid=fork()) == -1){
    fprintf(stderr,"fork error!\n");
    exit(1);        
  }
  if(pid){
    /* parent */

    close(inpipe[0]);

    stream = fdopen( inpipe[1], "w" );
    setbuf (stream, NULL );
    fprintf(stream, "TEST COMMAND\n");

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);
    while(waitpid(-1, &rv, WNOHANG) <= 0){
      if (select(1, &rfds, NULL, NULL, NULL)) {
        fgets (buffer, 256, stdin);
        fputs(buffer, stream);
      }
    }  
    wait(&rv);
    fprintf(stderr,"child exited with a %d value\n",rv);
  }
  else{
    /* child */
    close(inpipe[1]);
    dup2(inpipe[0],0);
    if(execl("program","program",NULL) == -1){
      fprintf(stderr,"execl error!");
      exit(1);
    }
  }  
  return 0;
}


Over het algemeen werkt dit wel, maar het is niet de meest handige of nette oplossing.

In deze opzet zit de parent na het versturen van mijn twee commando's alleen maar de input van stdin door te geven aan de pipe, en bijvoorbeeld de select() blijft blocken als de child om de een of andere reden exit. Om nog maar niet te spreken van het misbruik van getc() en SIGPIPE's.

Er moet een simpelere manier zijn om voor elkaar te krijgen wat ik wil. Wat bijvoorbeeld in me opgekomen is is dat de parent na het sturen van de commando's zijn stdin connect aan de pipe, of dat de child setsid() en de parent na het versturen van de commando's de orginele stdin van de child weer herstelt en dan exit.

In ieder geval zou het zeer handig zijn als de parent na het versturen van de commando's gewoon kan verdwijnen, want dat scheelt een hele hoop ellende.

Ik zou wat input zeer op prijs stellen :)

Every morning is the dawn of a new error.