Reputation: 194
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
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