这道题的方法对于我来说有点陌生,堆操作之后利用IO_FILE的相关知识,记录一下,以后还会有更多对于 IO 的利用
保护机制全开,所以常规方法肯定没办法
分析程序:
这是主程序
menu函数
create函数
逻辑是输入申请大小,在输入index,然后就写入chunk
没有任何检查,比如申请过的index不能用之类的
最简洁的申请函数
delete函数
同样是简洁的释放函数,而且有 uaf 漏洞
rename函数
改写chunk内容,写入的时候貌似没有溢出,但是 uaf 能用在这上面
程序看似简单,但是保护机制全开,而且没有任何输出函数可以让我泄露出什么
然后就遇到了我不太熟悉的方法,就是利用 __IO_2_1_stdout 来泄露信息
记录一下 IO_FILE 基本的信息,虽然到目前为止还是不太清楚,也就只能做一道题看一道了
pwndbg> ptype stdout
type = struct _IO_FILE {
int _flags;
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
char *_IO_write_base;
char *_IO_write_ptr; //本题用到的 IO_write_ptr 和 IO_write_base
char *_IO_write_end;
char *_IO_buf_base;
char *_IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
__off64_t _offset;
struct _IO_codecvt *_codecvt;
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
size_t __pad5;
int _mode;
char _unused2[20];
} *
这是IO_FILE 结构体
#define _IO_MAGIC 0xFBAD0000 /* Magic number */
#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
#define _IO_MAGIC_MASK 0xFFFF0000
#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */
#define _IO_UNBUFFERED 2
#define _IO_NO_READS 4 /* Reading not allowed */
#define _IO_NO_WRITES 8 /* Writing not allowd */
#define _IO_EOF_SEEN 0x10
#define _IO_ERR_SEEN 0x20
#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */