Dex
Dex

Reputation: 194

Pass binary data to stdin of a program based on its stdout

I have a program A, which prints some text data, then does a gets() reading from stdin. I want to create a program/script which will read the stdout of A (text data) and based on the output pass data (binary) to its stdin.

The program is a simple exploitation demo (format string vulnerability to dump stack, then based on dumped values craft exploit payload which is then passed via gets to trigger a buffer overflow and execute the crafted shellcode).

int main(int argc, char** argv)
{
    char buffer[20];
    BOOL(__stdcall *getName)(LPSTR lpBuffer, LPDWORD nSize) = GetComputerNameA;

    printf("The argument is: ");
    printf(argv[1]);
    printf("\r\n");

    printf("Enter a message: ");
    gets(buffer);
    printf("Your message is: %s", buffer);

    TCHAR name[20];
    DWORD len = 19;
    getName(name, &len);
    printf("Your computer is called %s", name);
    printf("\r\n");
}

I have tried doing this in python via target.stdout.readline() and target.stdin.write(), but the readline hangs and never returns. I also tried in C# via the OutputDataReceived event, but I was only able to read the output if I wasn't passing any input. Once I redirected stdin, I wasn't able to read anything. Hangs also occured.

My question is how do I achieve this?

EDIT: Sample of the python code executing the program

from subprocess import Popen, PIPE, STDOUT
x = Popen(['test.exe', '"%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x"', 'start'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

out = x.stdout.readline()
print(out)
input("{press enter}")

data = bytearray(...payload...)
payload = buffer(data)
x.stdin.write(payload)
input("{press enter}")

Upvotes: 0

Views: 757

Answers (1)

Michael Veksler
Michael Veksler

Reputation: 8475

In C printf uses buffered output. When stdout is to a terminal then the buffer is flushed after each "\n", but in this case the output is to a pipe, so it is buffered to several k-bytes worth of data. The buffer is never flushed, and is not written to the pipeline.

To avoid python waiting for the buffered data forever, you can add fflush(stdout) after each printf or disable buffering altogether.

Upvotes: 1

Related Questions