pwn IO相关偏移
About 8 min
pwn IO相关偏移
主要是因为有几次比赛,题基本打到IO了但是就剩下十分钟了根本调不通IO链,为了预防这种情况再次出现这里慢慢总结一下IO相关结构体和不同的攻击方式
这里主要是快捷提供了一些结构体以及偏移方便直接查询,这里的偏移以虚表为主,虚表实现主要是辅助我们查找函数的
gdb调试技巧
查看结构体的偏移量
ptype /o struct xxxx // 可以获取结构体的偏移量
查看变量的类型
ptype 变量 // 可以查看变量类型
largebin attack
主要是通过构造lagrebin attack 修改
_IO_list_all
然后因为修改后的目标地址存储的是我们unsortedbin 并入进入lagrebin的那个chunk,所以前0x30是没有办法劫持的
magic_gadget
搜索mov 赋值相关gadget 可以查找 比如这里查找magic_gadget
ROPgadget --binary ./libc.so.6 --only "mov|call" | grep "rdx" | grep "rax"
house of apple2
glibc2.38
其实就是edi+0x48位置赋值给rbp
0x7f20cbd5336e <svcudp_reply+20>: mov rbp,QWORD PTR [rdi+0x48]
0x7f20cbd53372 <svcudp_reply+24>: lea r13,[rbp+0x10]
0x7f20cbd53376 <svcudp_reply+28>: mov DWORD PTR [rbp+0x10],0x0
0x7f20cbd5337d <svcudp_reply+35>: mov rax,QWORD PTR [rbp+0x18]
0x7f20cbd53381 <svcudp_reply+39>: mov esi,0x0
0x7f20cbd53386 <svcudp_reply+44>: mov rdi,r13
0x7f20cbd53389 <svcudp_reply+47>: call QWORD PTR [rax+0x28]
2.38
2.38-1ubuntu4_amd64
_IO_FILE_plus结构体
struct _IO_FILE_plus
{
// _IO_FILE
FILE file;
const struct _IO_jump_t *vtable;
};
然后其属性和对应偏移
0-0xd8:file 0xd8:vtable
file结构体 偏移
/* offset | size */ type = struct _IO_FILE { /* 0 | 4 */ int _flags; /* XXX 4-byte hole */ /* 8 | 8 */ char *_IO_read_ptr; /* 16 | 8 */ char *_IO_read_end; /* 24 | 8 */ char *_IO_read_base; /* 32 | 8 */ char *_IO_write_base; /* 40 | 8 */ char *_IO_write_ptr; /* 48 | 8 */ char *_IO_write_end; /* 56 | 8 */ char *_IO_buf_base; /* 64 | 8 */ char *_IO_buf_end; /* 72 | 8 */ char *_IO_save_base; /* 80 | 8 */ char *_IO_backup_base; /* 88 | 8 */ char *_IO_save_end; /* 96 | 8 */ struct _IO_marker *_markers; /* 104 | 8 */ struct _IO_FILE *_chain; /* 112 | 4 */ int _fileno; /* 116 | 4 */ int _flags2; /* 120 | 8 */ __off_t _old_offset; /* 128 | 2 */ unsigned short _cur_column; /* 130 | 1 */ signed char _vtable_offset; /* 131 | 1 */ char _shortbuf[1]; /* XXX 4-byte hole */ /* 136 | 8 */ _IO_lock_t *_lock; /* 144 | 8 */ __off64_t _offset; /* 152 | 8 */ struct _IO_codecvt *_codecvt; /* 160 | 8 */ struct _IO_wide_data *_wide_data; /* 168 | 8 */ struct _IO_FILE *_freeres_list; /* 176 | 8 */ void *_freeres_buf; /* 184 | 8 */ size_t __pad5; /* 192 | 4 */ int _mode; /* 196 | 20 */ char _unused2[20]; /* total size (bytes): 216 */ }
_IO_wide_data结构体
/* offset | size */ type = struct _IO_wide_data {
/* 0 | 8 */ wchar_t *_IO_read_ptr;
/* 8 | 8 */ wchar_t *_IO_read_end;
/* 16 | 8 */ wchar_t *_IO_read_base;
/* 24 | 8 */ wchar_t *_IO_write_base;
/* 32 | 8 */ wchar_t *_IO_write_ptr;
/* 40 | 8 */ wchar_t *_IO_write_end;
/* 48 | 8 */ wchar_t *_IO_buf_base;
/* 56 | 8 */ wchar_t *_IO_buf_end;
/* 64 | 8 */ wchar_t *_IO_save_base;
/* 72 | 8 */ wchar_t *_IO_backup_base;
/* 80 | 8 */ wchar_t *_IO_save_end;
/* 88 | 8 */ __mbstate_t _IO_state;
/* 96 | 8 */ __mbstate_t _IO_last_state;
/* 104 | 112 */ struct _IO_codecvt {
/* 104 | 56 */ _IO_iconv_t __cd_in;
/* 160 | 56 */ _IO_iconv_t __cd_out;
/* total size (bytes): 112 */
} _codecvt;
/* 216 | 4 */ wchar_t _shortbuf[1];
/* XXX 4-byte hole */
/* 224 | 8 */ const struct _IO_jump_t *_wide_vtable;
/* total size (bytes): 232 */
}
虚表
- 虚表本质都是实现这个结构体,所以直接看这个结构体基本就行. 流程大概是先看代码调用了结构体vtable的哪个函数 然后通过这个函数找虚表实现看对应哪个结构体
/* offset | size */ type = struct _IO_jump_t {
/* 0 | 8 */ size_t __dummy;
/* 8 | 8 */ size_t __dummy2;
/* 16 | 8 */ _IO_finish_t __finish;
/* 24 | 8 */ _IO_overflow_t __overflow;
/* 32 | 8 */ _IO_underflow_t __underflow;
/* 40 | 8 */ _IO_underflow_t __uflow;
/* 48 | 8 */ _IO_pbackfail_t __pbackfail;
/* 56 | 8 */ _IO_xsputn_t __xsputn;
/* 64 | 8 */ _IO_xsgetn_t __xsgetn;
/* 72 | 8 */ _IO_seekoff_t __seekoff;
/* 80 | 8 */ _IO_seekpos_t __seekpos;
/* 88 | 8 */ _IO_setbuf_t __setbuf;
/* 96 | 8 */ _IO_sync_t __sync;
/* 104 | 8 */ _IO_doallocate_t __doallocate;
/* 112 | 8 */ _IO_read_t __read;
/* 120 | 8 */ _IO_write_t __write;
/* 128 | 8 */ _IO_seek_t __seek;
/* 136 | 8 */ _IO_close_t __close;
/* 144 | 8 */ _IO_stat_t __stat;
/* 152 | 8 */ _IO_showmanyc_t __showmanyc;
/* 160 | 8 */ _IO_imbue_t __imbue;
/* total size (bytes): 168 */
}
虚表实现
一般虚表的赋值都在libio/vtables.c文件里面
const struct _IO_jump_t __io_vtables[] attribute_relro =
{
/* _IO_str_jumps */
[IO_STR_JUMPS] =
{
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_str_finish),
JUMP_INIT (overflow, _IO_str_overflow),
JUMP_INIT (underflow, _IO_str_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_str_pbackfail),
JUMP_INIT (xsputn, _IO_default_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_str_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_default_setbuf),
JUMP_INIT (sync, _IO_default_sync),
JUMP_INIT (doallocate, _IO_default_doallocate),
JUMP_INIT (read, _IO_default_read),
JUMP_INIT (write, _IO_default_write),
JUMP_INIT (seek, _IO_default_seek),
JUMP_INIT (close, _IO_default_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_wstr_jumps */
[IO_WSTR_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_wstr_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
JUMP_INIT (xsputn, _IO_wdefault_xsputn),
JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
JUMP_INIT (seekoff, _IO_wstr_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_default_setbuf),
JUMP_INIT (sync, _IO_default_sync),
JUMP_INIT (doallocate, _IO_wdefault_doallocate),
JUMP_INIT (read, _IO_default_read),
JUMP_INIT (write, _IO_default_write),
JUMP_INIT (seek, _IO_default_seek),
JUMP_INIT (close, _IO_default_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_file_jumps */
[IO_FILE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_file_finish),
JUMP_INIT (overflow, _IO_file_overflow),
JUMP_INIT (underflow, _IO_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_file_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn),
JUMP_INIT (seekoff, _IO_new_file_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_new_file_setbuf),
JUMP_INIT (sync, _IO_new_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_file_jumps_mmap */
[IO_FILE_JUMPS_MMAP] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_file_finish),
JUMP_INIT (overflow, _IO_file_overflow),
JUMP_INIT (underflow, _IO_file_underflow_mmap),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_new_file_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn_mmap),
JUMP_INIT (seekoff, _IO_file_seekoff_mmap),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
JUMP_INIT (sync, _IO_file_sync_mmap),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close_mmap),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_file_jumps_maybe_mmap */
[IO_FILE_JUMPS_MAYBE_MMAP] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_file_finish),
JUMP_INIT (overflow, _IO_file_overflow),
JUMP_INIT (underflow, _IO_file_underflow_maybe_mmap),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_new_file_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn_maybe_mmap),
JUMP_INIT (seekoff, _IO_file_seekoff_maybe_mmap),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
JUMP_INIT (sync, _IO_new_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_wfile_jumps */
[IO_WFILE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_new_file_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow),
JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
JUMP_INIT (xsputn, _IO_wfile_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn),
JUMP_INIT (seekoff, _IO_wfile_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_new_file_setbuf),
JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync),
JUMP_INIT (doallocate, _IO_wfile_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_wfile_jumps_mmap */
[IO_WFILE_JUMPS_MMAP] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_new_file_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
JUMP_INIT (xsputn, _IO_wfile_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn),
JUMP_INIT (seekoff, _IO_wfile_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_file_setbuf_mmap),
JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync),
JUMP_INIT (doallocate, _IO_wfile_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close_mmap),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_wfile_jumps_maybe_mmap */
[IO_WFILE_JUMPS_MAYBE_MMAP] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_new_file_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap),
JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
JUMP_INIT (xsputn, _IO_wfile_xsputn),
JUMP_INIT (xsgetn, _IO_file_xsgetn),
JUMP_INIT (seekoff, _IO_wfile_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_file_setbuf_mmap),
JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync),
JUMP_INIT (doallocate, _IO_wfile_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_cookie_jumps */
[IO_COOKIE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_file_finish),
JUMP_INIT (overflow, _IO_file_overflow),
JUMP_INIT (underflow, _IO_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_file_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_cookie_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_file_setbuf),
JUMP_INIT (sync, _IO_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_cookie_read),
JUMP_INIT (write, _IO_cookie_write),
JUMP_INIT (seek, _IO_cookie_seek),
JUMP_INIT (close, _IO_cookie_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue),
},
/* _IO_proc_jumps */
[IO_PROC_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_new_file_finish),
JUMP_INIT (overflow, _IO_new_file_overflow),
JUMP_INIT (underflow, _IO_new_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_new_file_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_new_file_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_new_file_setbuf),
JUMP_INIT (sync, _IO_new_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_new_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_new_proc_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_mem_jumps */
[IO_MEM_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_mem_finish),
JUMP_INIT (overflow, _IO_str_overflow),
JUMP_INIT (underflow, _IO_str_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_str_pbackfail),
JUMP_INIT (xsputn, _IO_default_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_str_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_default_setbuf),
JUMP_INIT (sync, _IO_mem_sync),
JUMP_INIT (doallocate, _IO_default_doallocate),
JUMP_INIT (read, _IO_default_read),
JUMP_INIT (write, _IO_default_write),
JUMP_INIT (seek, _IO_default_seek),
JUMP_INIT (close, _IO_default_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
/* _IO_wmem_jumps */
[IO_WMEM_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_wmem_finish),
JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
JUMP_INIT (xsputn, _IO_wdefault_xsputn),
JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
JUMP_INIT (seekoff, _IO_wstr_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_default_setbuf),
JUMP_INIT (sync, _IO_wmem_sync),
JUMP_INIT (doallocate, _IO_wdefault_doallocate),
JUMP_INIT (read, _IO_default_read),
JUMP_INIT (write, _IO_default_write),
JUMP_INIT (seek, _IO_default_seek),
JUMP_INIT (close, _IO_default_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
[IO_PRINTF_BUFFER_AS_FILE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, NULL),
JUMP_INIT (overflow, __printf_buffer_as_file_overflow),
JUMP_INIT (underflow, NULL),
JUMP_INIT (uflow, NULL),
JUMP_INIT (pbackfail, NULL),
JUMP_INIT (xsputn, __printf_buffer_as_file_xsputn),
JUMP_INIT (xsgetn, NULL),
JUMP_INIT (seekoff, NULL),
JUMP_INIT (seekpos, NULL),
JUMP_INIT (setbuf, NULL),
JUMP_INIT (sync, NULL),
JUMP_INIT (doallocate, NULL),
JUMP_INIT (read, NULL),
JUMP_INIT (write, NULL),
JUMP_INIT (seek, NULL),
JUMP_INIT (close, NULL),
JUMP_INIT (stat, NULL),
JUMP_INIT (showmanyc, NULL),
JUMP_INIT (imbue, NULL)
},
[IO_WPRINTF_BUFFER_AS_FILE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, NULL),
JUMP_INIT (overflow, (_IO_overflow_t) __wprintf_buffer_as_file_overflow),
JUMP_INIT (underflow, NULL),
JUMP_INIT (uflow, NULL),
JUMP_INIT (pbackfail, NULL),
JUMP_INIT (xsputn, __wprintf_buffer_as_file_xsputn),
JUMP_INIT (xsgetn, NULL),
JUMP_INIT (seekoff, NULL),
JUMP_INIT (seekpos, NULL),
JUMP_INIT (setbuf, NULL),
JUMP_INIT (sync, NULL),
JUMP_INIT (doallocate, NULL),
JUMP_INIT (read, NULL),
JUMP_INIT (write, NULL),
JUMP_INIT (seek, NULL),
JUMP_INIT (close, NULL),
JUMP_INIT (stat, NULL),
JUMP_INIT (showmanyc, NULL),
JUMP_INIT (imbue, NULL)
},
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
/* _IO_old_file_jumps */
[IO_OLD_FILE_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_old_file_finish),
JUMP_INIT (overflow, _IO_old_file_overflow),
JUMP_INIT (underflow, _IO_old_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_old_file_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_old_file_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_old_file_setbuf),
JUMP_INIT (sync, _IO_old_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_old_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_file_close),
JUMP_INIT (stat, _IO_file_stat)
},
/* _IO_old_proc_jumps */
[IO_OLD_PROC_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_old_file_finish),
JUMP_INIT (overflow, _IO_old_file_overflow),
JUMP_INIT (underflow, _IO_old_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_old_file_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_old_file_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_old_file_setbuf),
JUMP_INIT (sync, _IO_old_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_file_read),
JUMP_INIT (write, _IO_old_file_write),
JUMP_INIT (seek, _IO_file_seek),
JUMP_INIT (close, _IO_old_proc_close),
JUMP_INIT (stat, _IO_file_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue)
},
#endif
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
/* _IO_old_cookie_jumps */
[IO_OLD_COOKIED_JUMPS] = {
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_file_finish),
JUMP_INIT (overflow, _IO_file_overflow),
JUMP_INIT (underflow, _IO_file_underflow),
JUMP_INIT (uflow, _IO_default_uflow),
JUMP_INIT (pbackfail, _IO_default_pbackfail),
JUMP_INIT (xsputn, _IO_file_xsputn),
JUMP_INIT (xsgetn, _IO_default_xsgetn),
JUMP_INIT (seekoff, _IO_cookie_seekoff),
JUMP_INIT (seekpos, _IO_default_seekpos),
JUMP_INIT (setbuf, _IO_file_setbuf),
JUMP_INIT (sync, _IO_file_sync),
JUMP_INIT (doallocate, _IO_file_doallocate),
JUMP_INIT (read, _IO_cookie_read),
JUMP_INIT (write, _IO_cookie_write),
JUMP_INIT (seek, _IO_old_cookie_seek),
JUMP_INIT (close, _IO_cookie_close),
JUMP_INIT (stat, _IO_default_stat),
JUMP_INIT (showmanyc, _IO_default_showmanyc),
JUMP_INIT (imbue, _IO_default_imbue),
},
#endif
};
_Static_assert (array_length (__io_vtables) == IO_VTABLES_NUM,
"initializer count");
劫持exit lagrebin attack
exit触发的函数调用链是_IO_cleanup-> _IO_flush_all->_IO_OVERFLOW (偏移0x18)然后就会获取_IO_list_all
然后开始循环
满足条件
- fp->_mode <= 0 也就是0xc0小于等于0
- fp->_IO_write_ptr > fp->_IO_write_base 也就是0x20 小于 0x28 (lagrebin attack自动满足这个条件)
- vatble 有值
- _lock要是一个可写地址(可写就行)
house of apple2
house of apple2的话我们要触发以下调用链 因为都是触发overflow函数所以不需要调整偏移
_IO_wfile_overflow
() (overflow函数对应偏移 0x18)_IO_wdoallocbuf
(非虚表)_IO_WDOALLOCATE
也就是对应doallocate
函数 (对应偏移0x68 f->_wide_vtable->__doallocate)
那么满足条件
- _flags & _IO_NO_WRITES == 0 (lagrebin attack自动满足)因为0&任意数任然为0
- (f->_flags & _IO_CURRENTLY_PUTTING) == 0 也是自动满足
- f->_wide_data->_IO_write_base == 0 也就是0xa0指向的地方的0x20偏移位置为0
板子
由于高版本执行到call的时候 rbp变成了0xffffffff,所以我们无法使用通用的板子.我们要是还是想要实现gadget
我们可以使用magic gadget svcudp_reply+20位置的代码 此时我们_stdout就是rdi寄存器
- 其实就是edi+0x48位置赋值给rbp