编辑:看来我还有更多的阅读材料......
另外,对于那些告诉我这是一个坏主意的人来说,这是一个缓冲区溢出练习。
我有一个相当简单的C程序:
int main() {
system("cat file | nc -p 33 localhost 8080");
return 0;
}
我想把它变成十六进制汇编代码。想想:
\x55\x43\xff\x75\x13\x77...
我尝试过:
gcc -o shell shell.c
for i in $(objdump -d shell -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
这给了我一个很好的长串十六进制。但是当我在这个程序中测试它时,我得到了一个段错误。
code = "\x55\x43\xff\x75\x13\x77..."
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
任何人都知道如何让这个工作?谢谢!另外,我不知道它是否重要,但它是一个64位系统。
答案 0 :(得分:4)
在从磁盘加载二进制代码并执行二进制代码之间,操作系统会为您提供一大堆东西。函数调用"系统(char *命令)"例如:指向命令字符的指针无效,直到OS加载程序"修复"指针。
如果您非常非常小心,可以构建不依赖指针的代码,并且可以在没有OS加载程序帮助的情况下从任意地址运行。这就是创建堆栈溢出漏洞的方法。大多数现代CPU通过使用内存管理器将内存标记为" DATA"来阻止此代码运行。或者"代码"如果您的程序试图执行DATA或写入CODE,则会出错。
您正在尝试做什么,操作系统正试图阻止。
答案 1 :(得分:1)
这不起作用。主要原因是:您的编译器为您创建的不仅仅是简单的二进制代码,而是一个运行良好的程序定义良好的文件格式(在windows上PE文件,在linux上ELF file)此文件由操作系统的动态链接器读取并在执行之前进行预处理(例如链接到动态共享对象,读取库)跳转到入口点,它以某种方式在文件的标题中给出。只有跳转到文件中的第一个字节才能执行无法这样的文件。实际上,它是创建输出格式的链接器,但它由编译器自动调用。
如果您只是想要汇编程序代码,请使用gcc -S
...您将获得可以提供给独立汇编程序的助记符。
有一些方法可以欺骗链接器发出代码的 plain 二进制文件(请参阅此处interesting read,了解如何使用它来生成MS-DOS .COM
文件),但你仍然有一个问题,你的程序通常不仅包含文本(读取,执行二进制代码),但你也有数据,通常在 .data < / em> segment(用于readonly)和 .bss 段(用于readwrite)。
除此之外,将二进制文件放在c字符串中通常会将其放在 .data 段中。虽然这个可以可执行,但它不需要,并且从安全的角度来看,不应该 - 请参阅Data Execution Prevention。
总而言之,忘掉那个......
答案 2 :(得分:0)
我不确定你想要达到的目标,但是如果我把黑帽戴上一分钟......
如果您正在尝试编写堆栈溢出漏洞,则需要了解内存管理器和目标CPU的血腥细节。您将严格处理CPU并完全绕过操作系统。
如果您正在尝试编写特洛伊木马,则应将有效负载编译为动态库(.so),并将整个payload.so文件的十六进制编译为代码[]。然后,在运营商程序中,将代码[]映射到虚拟文件(或者只是将其写入磁盘)并在(虚拟)文件上调用loadlibrary()。您仍然不是root用户,但您的有效负载将隐藏在第一个可执行文件中。您可以对代码[]字节进行位旋转以混淆有效负载。您还需要弄清楚如何在新创建的文件上设置可执行标志。
对于其中任何一个,您将使用CPU和/或操作系统。