0

I know how to pass an argument to system, for example:

char words[]="abcde";
sprintf(str, "echo %s",words);
system(str);

I write a simple code to brute-foce crack a rar file.

But I don't know how to pass password to system when the prompt appears.

I try this code below

char pw[512];
for(int i=0;i<26;i++){
    char ch=i+'a';

    memset(pw, '\0', sizeof(512));
    system("unrar x filename");// prorgam will wait at this point for a password
    sprintf(pw, "%c",ch);   
    system(pw); //this line doesn't make sense....
}

How can I pass that data to system when the program is waiting for input?

GSerg
  • 76,472
  • 17
  • 159
  • 346
Makoto
  • 241
  • 3
  • 10
  • No you cannot send data from your program directly to the subprocess started with system(), see my answer. system() does not return until the program finishes. popen() lets you communicate with the subprocess by returning a FILE * connected to the stdin/stdout of the subprocess – Bogatyr Jul 13 '13 at 12:12
  • Ok, thanks for your reply and teaching.Sorry that I don't choose your reply for best answer.Both of your answers are very good!! – Makoto Jul 13 '13 at 12:18

2 Answers2

4

You cannot use system() if you want to directly interact with the command you specify, since it states in the system() description that system() does not return until the specified command finishes: http://www.tutorialspoint.com/c_standard_library/c_function_system.htm.

As Marcelo noted, if the program you want to send data to accepts command line parametes, just specify the data on the command line you pass to system(). Another approach if the program you want to call takes data on the stdin is to save the data to a temporary file, then specify a stdin redirect on the command line, then after system() returns delete your file:

char *inputFileName = mkstemp("/tmp/myinputXXXXXX");
// store data in inputFileName
char buf[128];
sprintf(buf, "/path/to/myprogram < %s", inputFileName);
system(buf);
unlink(inputFileName);

If you need to interact with the program you run, you need to use another set of library functions to start the process and set up an IPC mechanism between them. The std library has a function similar to system() which lets you do this: popen(). popen() lets you specify a command line similar to system(), but it creates a pipe to the created program and returns a FILE * which lets your calling program read, write, or both, data from/to the subprocess:

FILE *myprogFP = popen("/path/to/myprog", "rw");
fprintf(myprogFP, "%d\n", i);
pclose(myprogFP);

For more information and examples of handling error returns from these functions, see for example: http://www.gnu.org/software/libc/manual/html_node/Pipe-to-a-Subprocess.html

Bogatyr
  • 19,255
  • 7
  • 59
  • 72
3

Unrar lets you supply the password as part of the command-line:

for (char ch = 'a'; ch <= 'z'; ++ch) {
    char cmdline[512];
    sprintf(cmdline, "unrar -p%c x filename", ch);
    system(cmdline);
}
Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • Tnanks for your reply.But can I pass data to system when system is waiting for?I just want to know how to do it. – Makoto Jul 13 '13 at 12:04
  • Not with `system()`. `popen()` lets you either write to a child process's stdin or read from its stdout, but not both. If you want both, that's much more difficult and hazardous. You need to give the child process a pseudo-tty to trick it into thinking that its talking to a keyboard and screen. Otherwise, it may misbehave quite badly because of I/O buffering. This is especially important for passwords, which are usually entered via something other than stdin (which echoes to the screen). – Marcelo Cantos Jul 13 '13 at 12:07
  • Hmm...that sounds difficult. I think me have some ideas about how to do it. Thank you very much. – Makoto Jul 13 '13 at 12:13
  • @user2579069: That worries me. This problem is known to be difficult and tricky to get right even when you know what you're doing. See [here](http://stackoverflow.com/questions/1203652/how-to-create-a-pseudo-tty-for-reading-output-and-writing-to-input) for guidance on the best way forward (i.e., someone else has done the hard work for you). – Marcelo Cantos Jul 13 '13 at 12:25
  • Keep in mind that providing a password via command line is generally a bad idea, since a process's command line is usually available to all other users in a system without much difficulty. I know that this is only for a single archive... but still. – Daniel Kamil Kozar Jul 13 '13 at 12:57