当前位置:首页|资讯

【pwn6 IO初印象】

作者:K3yB0ard发布时间:2024-09-22

后面打算多更一些IO链利用相关的,发现国内是真的喜欢考IO

libc 2.23及其之前的版本IO vtable没有保护,可以直接覆写IO_FILE结构体0xd8偏移的vtable指针,伪造vtable表,劫持程序流。

这里用一道经典老题——2018HCTF the end来展示基础IO getshell的利用方式。

程序libc版本为2.23.

首先看一下保护

checksec

打IO的基本上都是保护全开,算是比堆更复杂的利用方式了。

分析一下程序逻辑。

main

值得注意的是,程序关掉了标准输出stdout和标准错误stderr两个IO_FILE。然后给了五次任意地址写1字节的机会,最后调用exit函数结束掉程序。

这里打IO给出两种方式:

一、劫持stdout 的vtable表。

exit函数被调用结束掉程序时,有如下IO调用链子:

这里调用了stdout的vtable中的_set_buf函数。程序vtable表本身位于数据段,无法写,但是vtable指针可以被劫持。由于libc版本未对vtable指针做出检查,导致可以劫持vtable指针为fake vtable,再伪造_ste_buf函数表项为one_gadget直接getshell。

攻击思路如下:

1、首先劫持stdout的vtable为fake vtable,fake vtable的地址选取要求,该地址偏移0x58,即_set_buf在vtable中的偏移处可写,且为一个libc地址,这样我们才能用较少次数的任意地址写修改其为ogg地址,即选取的fake vtable应该在stdout结构体附近寻找。也可以去stdout结构体的vtable附近寻找。

2、在fake vtable的0x58处写入ogg地址,然后等着程序调用exit直接getshell。

exp如下:

执行结果:

exp res

成功执行one gadget。

二、写exit_hook

不熟悉exithook可参考如下链接:

https://www.cnblogs.com/bhxdn/p/14222558.html

exithook类似堆中的malloc hook和free hook为调用exit函数时必然会调用的函数,因此称之为hook,实质上是调用了 __rtld_lock_lock_recursive 和 __rtld_lock_unlock_recursive两个函数,这两个函数位于_rtld_global结构体中,而该结构体位于ld中,与libc与固定偏移,且可写。

可以gdb手动找一下:

_rtld_global的偏移

可以直接看到该结构体和libc的偏移,而两个exithook的函数都跟结构体有固定偏移,具体由libc版本而定:

在libc-2.23中
hook1 offset:3848

hook2 offset :3856

在libc-2.27中

hook1 offset :3840

hook2 offset :3848

则直接利用任意地址写,将one_gadget地址写入任意一个exit hook即可。

exp如下:

执行结果:

_rtld_global

在exit hook中写入one_gadget。

exp res

成功执行one_gadget。

值得注意的是,由于程序关闭了标准输出,笔者自行本地测试的时候无法得到标准输出。

res1

不过通过执行touch 命令发现确实可以创建文件,说明还是成功执行了shell的吧。,而且看gdb的调试窗口确实也是执行到shell了,如果在远程环境打的话应该可以正常通过

exec 1>&0通过重定向标准输出得到服务器输出内容。

res2

劫持vtable算是最简单的IO利用方式,后面会继续更一些house of家族的复杂IO利用,尤其是house of apple 123,国内考的好多都可以用apple2直接秒的说。

By Del0n1x

Keyboard


Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1