乐趣区

关于安全:软件安全实验栈溢出漏洞二

试验目标:

在把握栈帧构造的根底上,学习栈溢出破绽的基本原理。

实现性能:

在函数的栈帧中,局部变量是顺序排列的,栈帧中还保留前栈帧 EBP 及返回地址 RET 等信息。结构 password.txt。
使得 str 在读取该文件后恰可能笼罩 fun 函数的返回地址,从而运行 attack 函数。

试验代码:

#include <stdio.h>
void attack(){printf("Attacked!\n");
    exit(0);
}

void fun(){char password[6]="ABCDE";
    char str[6];
    FILE *fp;
    if(!(fp=fopen("password.txt","r"))){exit(0);
    }
    fscanf(fp,"%s",str);

    str[5]='\0';
    if(strcmp(str,password)==0)
        printf("OK!\n");
    else
        printf("NO!\n");
}

int main()
{fun();
    return 0;
}

试验后果和剖析:

  1. 设置程序断点
  2. 让程序运行到断点处进行,这时候查看 main()函数栈的 ebp 指针的值

    能够看到 ebp 指针的值是 0x6dff08
  3. 这时候让咱们跳进 fun()函数中去,同时查看 fun()函数栈中 ebp 指针的值
  4. 这时候关上内存,查看 fun()的 ebp 指针指向的值

    能够看到 fun()函数栈中 ebp 指针指向的值是 main()函数栈中 ebp 指针的值,因为栈的增长方向是从高地址向低地址增长的,ebp 指针紧挨着的高地址地位是函数栈的返回地址。咱们就能够晓得 fun()函数的返回地址是 0x401410,要使得 fun()函数返回时胜利地跳到 attack()函数处去,就得把 fun()函数的返回地址笼罩为 attack()的函数地址,这样能力实现跳转。
  5. 让咱们查看下 attack()的函数地址

    能够看到 attack()函数的地址是 0x401350
  6. 接着让咱们查看下 str 数组的地址

    从 fun()函数的 ebp 地址到 str 数组地址两头相差了 0x6dfef8 – 0x6dfee0 共 24 个字节,存储返回值的地址到 ebp 地址两头又相差了 4 个字节。返回地址的长度是 4 个字节,所以从 str 数组开始到齐全笼罩返回地址须要输出 32 个字节的数据。

    前 28 个字节轻易输出,后 4 个字节为 attack 的地址。
  7. 实现输出后,咱们始终点击 next line 让程序往下执行

    能够看到胜利地从 fun()返回后跳到了 attack()函数处,持续执行程序。

    胜利了!
退出移动版