在C可执行文件中运行数据Shellcode [英] Running data shellcode in c executable
问题描述
我正在研究此C程序.我正在64位x64 linux上使用gcc对其进行编译:
I am working on this c program. I am compiling it with gcc on a 64 bits x64 linux:
#include <stdio.h>
char buffer[]={0x90,0x90,0xC3};
int main(int argc, char *argv[])
{
void (*fct)();
fct=buffer;
fct();
return 0;
}
0x90操作码为NOP
0x90 opcode is NOP
0xC3操作码为RET
0xC3 opcode is RET
我想知道我应该怎么做才能运行该程序.我在运行时遇到段错误...
I want to know what i should do in order to run this program. I get a segfault when running it...
谢谢
推荐答案
TL; DR 用-z execstack
编译以为可执行文件启用Linux的read-implies-exec功能.尽管名称,但它适用于所有页,而不仅仅是堆栈.
TL;DR Compile with -z execstack
to enable Linux's read-implies-exec feature for your executable. Despite the name, it applies to all pages, not just the stack.
程序出现故障,因为buffer
符号进入.data
部分,然后又与其他部分一起进入映射为读写但不可执行的ELF段.
The program is faulting because the buffer
symbol goes into the .data
section that in turns goes, along with other sections, into an ELF segment mapped Read-write but not executable.
要使buffer
可执行文件成为最佳操作,将是制作一个带有标志RWE的新ELF段并为其分配一个新部分,然后告诉GCC将buffer
放在此新部分中.
可以原则上通过以下链接描述文件来完成:
To make the buffer
executable the best course of action would be to make a new ELF segment with flags RWE and assign it a new section, then tell GCC to put buffer
in this new section.
This could be done, in principle with the following linker script:
PHDRS
{
MYSEG PT_LOAD FLAGS (7);
}
SECTIONS
{
MYSECT : { *(MYSECT) } : MYSEG
}
,更改源:
#include <stdio.h>
char buffer[] __attribute__ ((section ("MYSECT"))) ={0x90,0x90,0xC3};
int main(int argc, char *argv[])
{
void (*fct)();
fct=buffer;
fct();
return 0;
}
,编译通过-T
开关传递给GCC.
and the compiling passing the -T
switch to GCC.
但这不会有效.
GCC使用基于命令行的默认链接描述文件,并且-T
开关将其完全替换.
可以使用-Wl,-verbose
获取GCC使用的脚本并进行更新.
But this won't work.
GCC uses a default linker script based on the command line and the -T
switch replace it entirely.
It's possible to get the script used by GCC with -Wl,-verbose
and update it.
如果我们先通过-c
然后是LD调用GCC来拆分编译和链接,则只会得到一个段,因为这就是我们在链接描述文件中放置的内容-从而挫败了我们制作的所有努力仅 buffer
唯一的可执行数据.
If we split the compilation and the linking by first invoking GCC with -c
and then LD, we'd get only one segment because that's what we put in the linker script - thereby defeating all our efforts to make only buffer
the only executable data.
使用-z execstack
实际上,我们实际上仅告诉GCC使用设置GNU_STACK
ELF段RWE的链接描述文件.
这是加载器用来为堆栈页面设置正确权限的标记段(大小和lma为零).
但实际上,它被用作兼容性开关-将堆栈设置为可执行文件时,加载程序会将 all 所有可写页面设置为可执行文件.
With -z execstack
we actually only tell GCC to use a linker script that sets the GNU_STACK
ELF segment RWE.
This is a marker segment (size and lma are zero) used by the loader to setup the correct permissions for the stack pages.
But in truth it is used as a compatibility switch - when the stack is set as executable the loader will set all the writable pages as executable.
如果您正在使用shellcodes,则-z execstack
会很容易,但是它会使您的应用程序遭受大量攻击,但是我想这首先是您需要的.
If you are playing with shellcodes -z execstack
will make it easy, however it exposes your application to a boatload of attacks, but I guess this is what you needed in the first place.
这篇关于在C可执行文件中运行数据Shellcode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!