Directing Shellcode Output to a File - C - c

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:
How does the shell code do the writing? What is it doing? I'm not going to dissect it for you; shell code tends to be very platform specific, and you've not identified which system you're using. Granted, it is reasonably easy to guess that you're using Linux on an Intel machine, but it might be 32-bit or 64-bit Linux, and what the shell code does still needs to be understood to know how to redirect its output. If it opens the terminal and writes to it, you'll be hard put to avoid the output appearing on the terminal, for example.
And user2059300 stated:
It's a sys_write syscall output to a file descriptor.
prompting me to ask:
Which file descriptor? 0, 1, 2, or another?
David C. Rankin noted:
That's still up in the air. Dumping to assembly shows a call to fprintf, but redirecting both stderr and stdout does nothing. It's almost like a kernel printf is being used.
And I countered with:
That's why I listed 0 as a candidate file descriptor. File descriptor 0 is usually a dup of file descriptors 1 and 2, so you can both write to 0 (standard input) and read from 1 and 2 (standard output and standard error). Of course, doing so is totally unsupported and non-portable (and you can't do it via the file streams 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.

Related

system() function doesn't produce expected output file

F
I'm using Graphviz to render .dot file as graphs, and typically I would write in my terminal :
dot -Tpng yourFile.dot -o yourOutput.png to produce a .png image representing my graph. (I'm using a Unix environment btw)
Now let's say I have the following C function:
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 255
typedef struct placeholder mystruct;
struct placeholder {
...
}
void outputGraph(mystruct str, char* outputName) {
char command[MAXSIZE];
char* tmpFile = "temp.dot";
char imageFile[MAXSIZE];
snprintf(imageFile, MAXSIZE, "%s.png", outputName);
FILE* file = fopen(tmpFile, "w");
writeStructToFile(str, file);
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
system(command);
snprintf(command, MAXSIZE, "rm %s", tmpFile);
system(command);
}
(my function WriteStructToFile is another one that I made and is working properly so the problem is somewhere else)
From what I understood about the system() function, it should produce the image output just the same as when I execute the same command myself.
Well, it does execute without any errors, but there is no image in the directory where I'm working.
At first, I thought, it's easy, system() doesn't start a new shell in the same working directory, so I tried to see the output of system(pwd); and it was my current working directory. So back to the starting point.
I also tried to check the value system(command) by doing int status = system(command); and then printf("status : %d\n", status); and, well, it printed 0.
Now I'm kinda clueless, I really don't see why it doesn't produce the image output.
I'd be very interested in any ideas or even solutions you have.
This is not the most elegant code, but it works & may help you debug your problem. It calls dot in three different ways. All three work as expected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char command[50];
int rc;
strcpy(command, "dot -Tdot this.gv" );
rc=system(command);
printf("\n\n+++ call #1 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -oout1.dot" );
rc=system(command);
printf("\n\n+++ call #2 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -o out2.dot" );
rc=system(command);
printf("\n\n+++ call #3 returned %d\n", rc);
return(0);
}
snprintf(command, MAXSIZE, "touch %s", tmpFile);
system(command);
Why do you code that?
You certainly don't need to use system(3) then touch(1). You could use appropriate syscalls(2) (open(2) and close(2) here) or at least fopen(3) followed by fclose(3).
You might in some cases consider using popen(3) with pclose(3)
Of course, after
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
int bad = system(command);
You need to first check that bad is 0 and you probably want to use stat(2) or access(2) to check that imageFile exists.
There could be many reasons why system with a dot command fails. For example, a bad $PATH variable. I suggest using popen(3) with pclose(3) and probably /usr/bin/dot in the command.
Compile your C code using GCC as gcc -Wall -Wextra -g and use GDB to debug your executable. Both strace(1) and ltrace(1) could help you understand the behavior of your program.
Consider reading Advanced Linux Programming and studying for inspiration the source code of some simple open source Linux shells, such as sash or (more complex) GNU bash.
Be aware that Graphviz could be used as a library.
I wasn't closing the temp.dot file in which I was writing. My mistake.
I shall now remember to always close files that I open!
A big thank you to everyone who helped on here.
(Whether it was for the problem or on how to use properly SO)

How to not write more bytes than are in the buffer in C?

I'm trying to write a simple copy program. It reads test_data.txt in chunks of 100 bytes and copies those bytes to test_dest.txt. I find that the destination file is at least one unit of chunk larger than the source file. How could I adjust it so that just the right number of bytes are copied? Would I need a copy buffer of size 1?
Please not the point is to solve it using low level I/O system calls.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main() {
int fh = open("test_data.txt", O_RDONLY);
int trg = open("test_dest.txt", O_CREAT | O_WRONLY);
int BUF_SIZE = 100;
char inp[BUF_SIZE];
int read_bytes = read(fh, inp, BUF_SIZE);
while (read_bytes > 0) {
write(trg, inp, BUF_SIZE);
read_bytes = read(fh, inp, BUF_SIZE);
}
close(trg);
close(fh);
return 0;
}
The read function just told you how many bytes it read. You should write that amount of bytes:
write(trg, inp, read_bytes);
On another note, you really should check for failures from the write call as well. And definitely the open calls.
On yet another note, you only really need one call to read:
ssize_t read_bytes; // The read function is specified by POSIX to return a ssize_t
while ((read_bytes = read(fh, inp, sizeof inp)) > 0)
{
write(trg, inp, read_bytes);
}
Your code is not standard C11. Check by reading the standard n1570, and read before the Modern C book.
Your code is more or less POSIX, and certainly compiles on most Linux distributions, e.g. Debian or Ubuntu (you want to install their build-essentials metapackage).
Please read the documentation of open(2), read(2), write(2), every syscalls(2) you are using, and of errno(3).
Notice that each of the functions you are calling can fail, and your code should test for the failure case. Also be aware that a write (or a read) could be partial in some cases, and this is documented.
Recommendation:
with a recent GCC -the usual C compiler on most Linux distributions, compile with all warnings and debug info, so gcc -Wall -Wextra -g.
Read Advanced Linux Programming and How to debug small programs
Learn to use the GDB debugger.
Read about build automation tools, such as GNU make (a very common tool on most Linux systems) or ninja.
Be aware of strace(1). You might use it on cp(1), or study the source code of GNU coreutils (providing cp).
Remember that most Linux distributions are mostly made of open source software.
You are allowed to study their source code.
I even believe that you should study their source code, at least for inspiration !
I'm trying to write a simple copy program. It reads test_data.txt in chunks of 100 bytes and copies those bytes to test_dest.txt
If performance matters, the chunk size of 100 bytes is really too small in practice. I would recommend a power of two bigger than 4Kbytes (the usual page size on x86-64).

Why do we put exit(1) in the C code even knowing that it will terminate the program abnormally.

Why are we putting exit(1) to terminate the program abnormally? Why do we want to terminate abnormally?
//Program exits itself
//Note that the example would terminate anyway
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
cout<<"Program will exit";
exit(1); // Returns 1 to the operating system
cout<<"Never executed";
}
I think I see the problem. Saying that exit(1) terminates the program abnormally is not a very accurate statement, and can lead to confusion. A better way to say it is that exit(1) indicates unsuccessful termination, i.e., it lets the user of the program know that something went wrong. It's simply a way to communicate the problem.
I don't actually think this is such a bad question, it just indicates the confusion of someone new to coding.
The number that is returned from a C executable is returned to the environment.
If the SHELL is bash, you can capture the exit status of an executable with 'echo $?' from the command prompt.
Here is an example of a C code:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
FILE *fp;
if( ( fp = fopen( "nonexistfile", "r" ) )== NULL ){
exit(5);
}
if(fp) fclose(fp);
return 0;
}
This code is trying to open a file that does not exists. So it will exit with status of 5. Lets say the executable of this program is called "open_file".
When you run this executable and type "$?",
>./open_file
>echo $?
>5
Here a bash script that runs this executable:
#!/bin/bash
./open_file
exit_status="$?"
if [ $exit_status -eq 5 ]
then
echo "FILE not there"
fi
Now lets say you have 10 C executable programs that are similar to above C program but trying to open different files.
And lets say you want to keep a log file of which of these programs failed opening a file.
As a programmer, you can exit with different exit status number for different programs.
e.g. exit(1); for executable #1
exit(2); for executable #2
...
exit(10); for executable #10
From bash script, it can keep track of exactly which executable failed from return value of an executable.
This example was to illustrate how you can coordinate the exit(n); from a C program with bash script that runs this executable. (n represents a decimal value)
The reason is usually to tell the operating system something unusual happened. Typically, a program exits with a value of zero. In Linux, you can use $? to see the value returned (i.e. 'echo $?'). You can use this value in scripts, etc. to check how your program terminated.

unix command result to a variable - char*

How can I assign "pwd" (or any other command in that case) result (present working dir) to a variable which is char*?
command can be anything. Not bounded to just "pwd".
Thanks.
Start with popen. That will let you run a command with its standard output directed to a FILE * that your parent can read. From there it's just a matter of reading its output like you would any normal file (e.g., with fgets, getchar, etc.)
Generally, however, you'd prefer to avoid running an external program for that -- you should have getcwd available, which will give the same result much more directly.
Why not just call getcwd()? It's not part of C's standard library, but it is POSIX, and it's very widely supported.
Anyway, if pwd was just an example, have a look at popen(). That will run an external command and give you a FILE* with which to read its output.
There is a POSIX function, getcwd() for this - I'd use that.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
char *dir;
dir = getcwd(NULL, 0);
printf("Current directory is: %s\n", dir);
free(dir);
return 0;
}
I'm lazy, and like the NULL, 0 parameters, which is a GNU extension to allocate as large a buffer as necessary to hold the full pathname. (It can probably still fail, if you're buried a few hundred thousand characters deep.)
Because it is allocated for you, you need to free(3) it when you're done. I'm done with it quickly, so I free(3) it quickly, but that might not be how you need to use it.
You can fork and use one of the execv* functions to call pwd from your C program, but getting the result of that would be messy at best.
The proper way to get the current working directory in a C program is to call char* getcwd(char* name, size_t size);

Executing machine code in memory

I'm trying to figure out how to execute machine code stored in memory.
I have the following code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE* f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
char* bin = (char*)malloc(len);
fread(bin, 1, len, f);
fclose(f);
return ((int (*)(int, char *)) bin)(argc-1, argv[1]);
}
The code above compiles fine in GCC, but when I try and execute the program from the command line like this:
./my_prog /bin/echo hello
The program segfaults. I've figured out the problem is on the last line, as commenting it out stops the segfault.
I don't think I'm doing it quite right, as I'm still getting my head around function pointers.
Is the problem a faulty cast, or something else?
You need a page with write execute permissions. See mmap(2) and mprotect(2) if you are under unix. You shouldn't do it using malloc.
Also, read what the others said, you can only run raw machine code using your loader. If you try to run an ELF header it will probably segfault all the same.
Regarding the content of replies and downmods:
1- OP said he was trying to run machine code, so I replied on that rather than executing an executable file.
2- See why you don't mix malloc and mman functions:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
char *a=malloc(10);
char *b=malloc(10);
char *c=malloc(10);
memset (a,'a',4095);
memset (b,'b',4095);
memset (c,'c',4095);
puts (a);
memset (c,0xc3,10); /* return */
/* c is not alligned to page boundary so this is NOOP.
Many implementations include a header to malloc'ed data so it's always NOOP. */
mprotect(c,10,PROT_READ|PROT_EXEC);
b[0]='H'; /* oops it is still writeable. If you provided an alligned
address it would segfault */
char *d=mmap(0,4096,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE|MAP_ANON,-1,0);
memset (d,0xc3,4096);
((void(*)(void))d)();
((void(*)(void))c)(); /* oops it isn't executable */
return 0;
}
It displays exactly this behavior on Linux x86_64 other ugly behavior sure to arise on other implementations.
Using malloc works fine.
OK this is my final answer, please note I used the orignal poster's code.
I'm loading from disk, the compiled version of this code to a heap allocated area "bin", just as the orignal code did (the name is fixed not using argv, and the value 0x674 is from;
objdump -F -D foo|grep -i hoho
08048674 <hohoho> (File Offset: 0x674):
This can be looked up at run time with the BFD (Binary File Descriptor library) or something else, you can call other binaries (not just yourself) so long as they are statically linked to the same set of lib's.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
unsigned char *charp;
unsigned char *bin;
void hohoho()
{
printf("merry mas\n");
fflush(stdout);
}
int main(int argc, char **argv)
{
int what;
charp = malloc(10101);
memset(charp, 0xc3, 10101);
mprotect(charp, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
__asm__("leal charp, %eax");
__asm__("call (%eax)" );
printf("am I alive?\n");
char *more = strdup("more heap operations");
printf("%s\n", more);
FILE* f = fopen("foo", "rb");
fseek(f, 0, SEEK_END);
unsigned int len = ftell(f);
fseek(f, 0, SEEK_SET);
bin = (char*)malloc(len);
printf("read in %d\n", fread(bin, 1, len, f));
printf("%p\n", bin);
fclose(f);
mprotect(&bin, 10101, PROT_EXEC | PROT_READ | PROT_WRITE);
asm volatile ("movl %0, %%eax"::"g"(bin));
__asm__("addl $0x674, %eax");
__asm__("call %eax" );
fflush(stdout);
return 0;
}
running...
co tmp # ./foo
am I alive?
more heap operations
read in 30180
0x804d910
merry mas
You can use UPX to manage the load/modify/exec of a file.
P.S. sorry for the previous broken link :|
It seems to me you're loading an ELF image and then trying to jump straight into the ELF header? http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
If you're trying to execute another binary, why don't you use the process creation functions for whichever platform you're using?
An typical executable file has:
a header
entry code that is called before main(int, char **)
The first means that you can't generally expect byte 0 of the file to be executable; intead, the information in the header describes how to load the rest of the file in memory and where to start executing it.
The second means that when you have found the entry point, you can't expect to treat it like a C function taking arguments (int, char **). It may, perhaps, be usable as a function taking no paramters (and hence requiring nothing to be pushed prior to calling it). But you do need to populate the environment that will in turn be used by the entry code to construct the command line strings passed to main.
Doing this by hand under a given OS would go into some depth which is beyond me; but I'm sure there is a much nicer way of doing what you're trying to do. Are you trying to execute an external file as a on-off operation, or load an external binary and treat its functions as part of your program? Both are catered for by the C libraries in Unix.
It is more likely that that it is the code that is jumped to by the call through function-pointer that is causing the segfault rather than the call itself. There is no way from the code you have posted to determine that that code loaded into bin is valid. Your best bet is to use a debugger, switch to assembler view, break on the return statement and step into the function call to determine that the code you expect to run is indeed running, and that it is valid.
Note also that in order to run at all the code will need to be position independent and fully resolved.
Moreover if your processor/OS enables data execution prevention, then the attempt is probably doomed. It is at best ill-advised in any case, loading code is what the OS is for.
What you are trying to do is something akin to what interpreters do. Except that an interpreter reads a program written in an interpreted language like Python, compiles that code on the fly, puts executable code in memory and then executes it.
You may want to read more about just-in-time compilation too:
Just in time compilation
Java HotSpot JIT runtime
There are libraries available for JIT code generation such as the GNU lightning and libJIT, if you are interested. You'd have to do a lot more than just reading from file and trying to execute code, though. An example usage scenario will be:
Read a program written in a scripting-language (maybe
your own).
Parse and compile the source into an
intermediate language understood by
the JIT library.
Use the JIT library to generate code
for this intermediate
representation, for your target platform's CPU.
Execute the JIT generated code.
And for executing the code you'd have to use techniques such as using mmap() to map the executable code into the process's address space, marking that page executable and jumping to that piece of memory. It's more complicated than this, but its a good start in order to understand what's going on beneath all those interpreters of scripting languages such as Python, Ruby etc.
The online version of the book "Linkers and Loaders" will give you more information about object file formats, what goes on behind the scenes when you execute a program, the roles of the linkers and loaders and so on. It's a very good read.
You can dlopen() a file, look up the symbol "main" and call it with 0, 1, 2 or 3 arguments (all of type char*) via a cast to pointer-to-function-returning-int-taking-0,1,2,or3-char*
Use the operating system for loading and executing programs.
On unix, the exec calls can do this.
Your snippet in the question could be rewritten:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
return execv(argv[1],argv+2);
}
Executable files contain much more than just code. Header, code, data, more data, this stuff is separated and loaded into different areas of memory by the OS and its libraries. You can't load a program file into a single chunk of memory and expect to jump to it's first byte.
If you are trying to execute your own arbitrary code, you need to look into dynamic libraries because that is exactly what they're for.

Resources