I'm using this code from here: Read and Execute Shellcode from a .txt File
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(void)
{
FILE *file = fopen("text.txt", "r");
unsigned char *buf;
int length = 0;
struct stat st;
int v;
// get file size and allocate. We're going to convert to bytes
// from text, so this allocation will be safely large enough
fstat(fileno(file), &st);
buf = valloc(st.st_size);
while (fscanf(file, "\\x%02x", &v) == 1)
{
buf[length++] = v;
}
fclose(file);
mprotect(buf, length, PROT_EXEC);
int (*ret)() = (int (*)())buf;
ret();
return 0;
}
And I'm compiling with: gcc -fno-stack-protector -z execstack testshell.c -o testshell
It runs just fine but the shellcode it executes writes to the terminal, but I would like to somehow redirect that to a file.
I tried:
./testshell > output.txt
but couldn't seem to get that to capture the results of the shellcode either.
How can I capture the output of any shellcode it runs, and if possible redirect that to a file?
Update: The shellcode I am using, and it outputs with a sys_write syscall output to a file descriptor (It does a calculation and prints to the screen) -
\xeb\x4d\x5e\x66\x83\xec\x0c\x48\x89\xe0\x48\x31\xc9\x68\x33\x09\x00\x7c\x48\x89\xcf\x80\xc1\x0c\x40\x8a\x3e\x40\xf6\xd7\x40\x88\x38\x48\xff\xc6\x68\x16\x96\xd0\xd9\x48\xff\xc0\xe2\xea\x2c\x0c\x48\x89\xc6\x68\xf2\xf5\x44\x48\x48\x31\xc0\x48\x89\xc7\x04\x01\x48\x89\xc2\x80\xc2\x0b\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05\xe8\xae\xff\xff\xff\x85\xa7\xaa\xc7\x9e\x87\xa5\xa5\x8e\xb7\x87\xba\x31\x80\xe0\x55\xef\xa1\x93\x0c\x4e\x1c\xdc\x34\x53\xb3\x8b\x43\x48\x68\x30\x1d\x4b\x65\x5b\x52\x41\x4e\x44\x53\x54\x52\x32\x5d
Transferring comments into an answer, giving credit where credit's due.
Deanie said:
This should work if the shellcode is writing to stdout and not stderr. Try:
./testshell > output.txt 1>&2
To which user2059300, the OP, responded:
No dice on the
1>&2
, the output still occurs in the terminal and not in output.txt
And David C. Rankin said:
I think he meant
./testshell > output.txt 2>&1
to redirect both stdout & stderr to output.txt.
But user2059300 stated:
Still a no-go on that, … I provided the shellcode I'm testing.
Then I asked:
And user2059300 stated:
It's a
sys_write
syscall output to a file descriptor.
prompting me to ask:
David C. Rankin noted:
That's still up in the air. Dumping to assembly shows a call to
fprintf
, but redirecting bothstderr
andstdout
does nothing. It's almost like a kernel printf is being used.
And I countered with:
stdin
, stdout
, stderr
), but then shell code in general is non-portable.And that seems to have been the key. David C. Rankin confirmed:
Hah! You nailed it.
./testshell > output.txt 0>&1
worked just fine. Learning has occurred… Thanks. That is the first, and hopefully the last time, I'll run across that. I'm too old to be learning those tricks.
and so did user2059300:
Thank you guys so much. Learning has indeed occurred.
./testshell > output.txt 0>&1
Obviously, I didn't know that was going to be the solution, but when the I/O redirection of standard output and standard error failed, it became a possibility. That behaviour has a very long history (7th Edition Unix, probably before that, too), though seldom if ever explicitly documented.