前言
在2019年的bamboofox CTF
我做到了一道非传统的pwn题,之后队友在做一道沙箱逃逸
题目的时候也用到了相同的技巧,并找到了原型题目,由于后者已经有详细的题解,本文不再展开过多细节,后面会放参考链接供大家学习。
bamboofox CTF 2019 abw
程序分析 && 漏洞利用
题目给了一个压缩包,里面有Dockerfile
以及docker-compose.yml
让选手搭建本地环境,其中Dockerfile
内容如下:
FROM ubuntu:18.04
MAINTAINER Billy
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install xinetd -y
RUN apt-get install python3 -y
RUN useradd -m abw
COPY ./share /home/abw
COPY ./xinetd /etc/xinetd.d/abw
COPY ./flag /home/abw/flag
RUN chmod 774 /tmp
RUN chmod -R 774 /var/tmp
RUN chmod -R 774 /dev
RUN chmod -R 774 /run
RUN chmod 1733 /tmp /var/tmp /dev/shm
RUN chown -R root:root /home/abw
CMD ["/usr/sbin/xinetd","-dontfork"]
docker-compose.yml
内容如下,可以看到是开放12345
端口监听abw
服务
abw:
build: ./
environment:
- OLDPWD=/home
- XDG_RUNTIME_DIR=/run/user/1000
- LESSOPEN=| /usr/bin/lesspipe %s
- LANG=en_US
- SHLVL=1
- SHELL=/bin/bash
- FLAG=/
- ROOT=/
- TCP_PORT=12345
- PORT=12345
- X_PORT=12345
- SERVICE=abw
- XPC_FLAGS=0x0
- TMPDIR=/tmp
- RBENV_SHELL=bash
ports:
- "12345:12345"
expose:
- "12345"
xinetd
文件创建了一个服务
service abw
{
disable = no
type = UNLISTED
wait = no
server = /home/abw/run.sh
socket_type = stream
protocol = tcp
user = abw
port = 12345
flags = REUSE
per_source = 5
rlimit_cpu = 3
nice = 18
}
`run.sh
文件实际上是执行/home/abw/abw
exec 2> /dev/null
timeout 60 /home/abw/abw
而这个文件实际上是一些代码,代码的解释器为python3
,这里为了方便调试我直接在docker里把python3
拷贝了出来并重命名为py3_remote
#./py3_remote
print( "Write File")
filename = input("File Name :")
with open(filename,"wb") as file:
seek = int(input("Seek :"))
file.seek(seek)
file.write(bytes.fromhex(input("Data (hex):")[:20]))
至此我们已经找到了核心的程序逻辑,即给我们10字节
写任意文件任意offset
的机会,之后程序结束。这里我们写入的对象就是今天要介绍的/proc/self/mem
,/proc
顾名思义是存储进程相关的文件的目录,/proc/$pid/
存储的是进程号为pid
的进程的相关文件。/proc/self/
存储的是同本进程相关的文件。
这里引用百度百科比较权威的解释
proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
wz@wz-virtual-machine:~/Desktop/CTF/bamboofox/abw/release/share$ ll /proc/self/
点击收藏 | 2
关注 | 2