Looks like it is possible to read from file descriptor 1 under Linux. I've attached example code below. I can interact with it using keyboard and provide valid password.
Problem is, that I'm unable to execute it without user involvement. For example:
echo "123" | ./stdout_as_stdin
./stdout_as_stdin < <(echo "123")
When I change line:
read(1, buff, buff_size-2); // reading from STDOUT
to
read(0, buff, buff_size-2); // reading from STDIN
input redirection is working fine.
How to perform Program Interaction from other bash/python script without user involvement in described scenario?
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
const int buff_size = 1024;
char buff[buff_size];
char p_1[] = "123";
char p_2[] = "abc";
printf("Enter secret password (%s):\n", p_1);
memset(buff, 0, buff_size);
read(1, buff, buff_size-2); // reading from STDOUT
if ((strlen(buff) == strlen(p_1) + 1) && (memcmp(p_1, buff, strlen(p_1)) == 0)) {
printf("Secret token: %s\n", p_2);
return 0;
} else {
printf("Failed\n");
return 1;
}
}
I'm looking for hack/solution which allows me to automate execution of program which reads data from STDOUT instead of STDIN.
To make something like this work, you need to connect the program's standard output to a file (in the broad sense) that will both provide the wanted input and accept the output delivered to it.
Thank you @john-bollinger for this precious information. I was able to solve my issue.
Bash
mkfifo ./my_fifo
exec ./stdout_as_stdin 1<> ./my_fifo &
I can interact with program using fifo file.
Python
os.mkfifo('./my_fifo', 0o600)
fd = os.open('./my_fifo', os.O_RDWR)
p = pwn.process(argv = ['./stdout_as_stdin'], stdout = fd)
Followed by the os.read(fd, ...)
and os.write(fd, ...)
calls.
Why?
Looks like I wasn't clear enough. I'm not writing program which act in a such way. Provided example showed that particular behavior is possible. I don't know why most of the feedback moved discussion away from "how to tackle such scenario". Anyway, thanks for the valuable comments.
Looks like it is possible to read from file descriptor 1 under Linux.
You seem to be making an unwarranted generalization. Clearly, what you observed is possible under some circumstances. It definitely is not possible under other circumstances, however, such as when the standard output is connected to a file open only for writing, or to one that doesn't even support reading, such as the write end of a pipe.
Moreover, although there may be special cases -- even common ones -- in which you can read the same data from stdout
that you could have read from stdin
, in the general case, you cannot expect stdout
to yield the same data that stdin
does. Nor is it safe to assume, in general, that reading stdout
will yield data that your program or any other wrote to the same file. Nor that it will yield any data at all.
I'm unable to execute it without user involvement. For example:
echo "123" | ./stdout_as_stdin ./stdout_as_stdin < <(echo "123")
That's not at all surprising. In general, stdout
is not equivalent to stdin
. Cases where one or the other have been redirected are especially likely to demonstrate that.
When I change line:
read(1, buff, buff_size-2); // reading from STDOUT
to
read(0, buff, buff_size-2); // reading from STDIN
input redirection is working fine.
Redirection was working fine in both cases. What you need to grasp is that redirection demonstrates that your assumption that stdout
can safely be treated as an alias of stdin
is not well founded.
How to perform Program Interaction from other bash/python script without user involvement in described scenario?
Programs that expect to read data provided on their standard input should read it from their standard input, and not from anywhere else. Details depend on programming language, among other things, but the general rule is universal. This is especially true for programs that want to support input coming from a pipe or redirected from a file, which work fine on Linux as long as the program actually reads from its input.
I'm looking for hack/solution which allows me to automate execution of program which reads data from STDOUT instead of STDIN.
This is an ill-conceived idea, because a program such as you want to automate is ill conceived in the first place. Especially so for a program that also wants to write output to its stdout
(otherwise you could probably just dupe the standard input onto the standard output).
To make something like this work, you need to connect the program's standard output to a file (in the broad sense) that will both provide the wanted input and accept the output delivered to it. A socket or the client end of a pseudoterminal could serve. Then you would need to drive it from a wrapper program that feeds in the wanted input and does something with the output. But I'm not sure what you prove by rigging up something like this.