攻防世界进阶题Recho——知识点缝合怪

攻防世界进阶题Recho——知识点缝合怪

引入

好久没有做pwn题了,手生的厉害,做道简单题练练手好了

这道题其实难度不高,属于那种开门见山把漏洞点抛出任君采撷的题,但是由于涉及的知识点较多,在ROP链构造时需要有清晰的思路,对于我这样的小白来说自然是再好不过的练习题。

初分析

1、checksec

题目拿到手上,第一件事还是checksec

发现只有NX(栈不可执行)打开了

2、主函数结构

ida反汇编伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char nptr[16]; // [rsp+0h] [rbp-40h] BYREF
  char buf[40]; // [rsp+10h] [rbp-30h] BYREF
  int v6; // [rsp+38h] [rbp-8h] var_8
  int v7; // [rsp+3Ch] [rbp-4h] var_4

  Init();
  write(1, "Welcome to Recho server!\n", 0x19uLL);
  while ( read(0, nptr, 0x10uLL) > 0 )
  {
    v7 = atoi(nptr);                            // 输入希望读入的字符长度
    if ( v7 <= 15 )
      v7 = 16;                                  // 至少读入16个字符
    v6 = read(0, buf, v7);                      // 读入缓冲区,v6记录读入长度
    buf[v6] = 0;                                // 加入截断
    printf("%s", buf);
  }
  return 0;
}

显而易见的栈溢出

3、栈结构

Recho2

buf距离return地址0x38字节

4、特殊字符串

data段的小提示

image-20210920153355615

解题过程

其实解题思路已经很明显了,整个栈空间都在控制内,又给出了提示“flag”文件名,故整体思路如下

  • 挟持GOT,调用open函数打开flag
  • 用read函数把flag文件中的内容读入bss段缓存区(可读可写)
  • 用printf函数把缓存区中的内容输出
1、gadget搜集

由于涉及到ROP对函数调用,又是x86-64架构的系统,函数参数主要通过寄存器传递,所以需要找到控制相应寄存器的gadget

并且为了更改GOT表项的值,还需要一个可以改变特定地址值的地址

已知函数参数主要通过寄存器传递,前三个参数分别放在rdi,rsi,rdx寄存器中,幸运的是,这三条指令都存在(0x4008a3、0x4008a1, 0x4006fe),这样我们就不需要用到One_gadget去硬凑了(有关万能One_gadget的相关知识)。同时,我们也顺利的找到了所需的改值gadget(0x40070d)

2、GOT表详情

需要更改GOT表项以获得open函数,所以看看plt表中有哪些函数(关于GOT,PLT和延迟绑定机制)

因为alarm函数不需要用到,所以计划将alarm函数的got表项改为system_call这个系统调用接口函数,这个函数在使用时只需改变保存在eax中的系统调用号即可调用系统函数。

3、函数参数说明
  • <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值