CTFshow-PWN-栈溢出(pwn35)

正式开始栈溢出了,先来一个最最最最简单的吧

检查 

checksec pwn

32 位程序,RELRO 与 NX保护开启 

 拖进 ida32 反编译看main 函数

关键代码分析:

stream = fopen("/ctfshow_flag", "r");

打开文件 /ctfshow_flag 读取内容

if ( argc <= 1 )
  {
    puts("Try again!");
  }
  else
  {
    ctfshow((char *)argv[1]);

只要命令行参数个数大于 1 就会调用 ctfshow 函数

双击跟进 ctfshow 函数

ctfshow 的函数接受一个指向字符数组的指针 char *src 作为参数;

声明了一个名为 dest 的字符数组,长度为 104;

使用 strcpy 函数将 src 指向的字符串拷贝到 dest 中,返回指向 dest 的指针,即拷贝后的字符串的起始地址。strcpy 是一个典型的可能造成栈溢出的函数。

这里注意到如下代码:

  fgets(flag, 64, stream);
  signal(11, (__sighandler_t)sigsegv_handler);

从指定的输入流 stream 中读取最多 63 个字符(因为最后一个位置留给了空字符 '\0')到名为 flag 的字符数组中;当程序执行中发生段错误时,会触发 SIGSEGV 信号,此时程序会自动调用 sigsegv_handler 函数进行处理。 

跟进 sigsegv_handler 函数:

在收到 SIGSEGV 信号时,打印 flag 变量的内容到标准错误流

那么我们可以让第二个命令行参数(argv[1])超过 dest 数组长度(104)

制造栈溢出,让程序崩溃进而输出 flag

验证:

我们先让第二个命令行参数刚好为 104 个字符进行测试

./pwnme 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

没有输出 flag,因为不存在溢出,程序没有出错 

使用 105 个字符进行测试,这种情况会存在溢出

./pwnme 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

拿到 flag:ctfshow{102b6088-faed-47ce-b06c-0e7b863cac7e}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

My6n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值