作为一个出题人需要有一些觉悟,这周花了三天时间去研究Dockerfile的写法,主要还是为了实现动态flag,思路理顺了就会发现,原来Dockerfile和动态flag这么简单,这里直接现写两个简单的题目来演示一下。
web题,首先是需要按照常规逻辑写一个网页,这里就写一个带flag的简单网页,把flag放在源代码里,并注释掉。代码如下,保存为index.php。
<!DOCTYPE html>
<html>
<head>
<title>签到</title>
</head>
<!--flag{testflag}-->
<body>
<?php
echo "Do u want 2 sign??<br>";
?>
</body>
</html>
接下来编写Dockerfile,各语句解释就写在后面的注释里吧,正式编写请删掉注释。
FROM ctftraining/base_image_nginx_mysql_php_56 #web题docker基础镜像,这里使用ctftraing打包好
的,包含了基础的nginx,mysql,php环境,并且会自动运行flag.sh脚本(后面会提到),本题使用php环境。
COPY src /var/www/html # 将你编写的网页源码复制到docker容器中,这里为php网页,因此只需要
复制源码到/var/www/html就可以了,其他类型网页按照实际部署情况COPY到docker中相应目录下就可以了
RUN mv /var/www/html/flag.sh / \ #把你源码中的flag.sh复制到根目录以便自动执行
&& chmod +x /flag.sh #添加运行权限
我所使用的平台无需暴露端口,如有需要可以使用EXPOSE 80暴露80端口。
接下来实现动态flag,还记得上面提到的flag.sh吗,先来看一下它的代码,同样相关解释写在注释里,正式使用记得删掉注释。
PS:flag.sh推荐在linux环境下创建,否则docker build时会报错,泪的教训。
#!/bin/sh #必需的东西没什么好讲的
sed -i "s/flag{testflag}/$GZCTF_FLAG/" /var/www/html/index.php #使用平台的动态flag替换
index.php中的flag,这里我使用的平台为GZCTF,因此动态flag环境变量为$GZCTF_FLAG,其他平台一般
为$FLAG
export GZCTF_FLAG="" #这一句暂时不知道什么作用,但是要写着
整体目录结构
接下来的操作我默认你已经安装了docker和docker-compose,并且已经docker login了
使用build命令,构建题目镜像,name为dockerhub名(自行注册登录),webtest为镜像名(自定义),"."为版本号,代表latest,也可以自定义,不过拉取时记得加上版本号
docker build -t name/webtest .
push到你的dockerhub镜像仓库,name为dockerhub名,webtest为镜像名
docker push name/webtest
接下来部署题目,类型记得选择动态容器,不同平台可能有所不同,这里以GZCTF为例。
测试题目
如上图,成功实现了web题的动态flag,接下来实现pwn题的动态flag,pwn题基本逻辑一般为利用栈溢出漏洞,打通后得到shell权限,因此把flag文件放在容器的根目录或其他目录下即可,为了安全,这里在ctf_xinetd基础上做出一些修改来进行pwn题的部署,github链接:https://github.com/Eadom/ctf_xinetd
修改后的Dockerfile
FROM ubuntu:16.04
RUN sed -i "s/http:\/\/archive.ubuntu.com/http:\/\/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && \
apt-get update && apt-get -y dist-upgrade && \
apt-get install -y lib32z1 xinetd
RUN useradd -m ctf
WORKDIR /home/ctf
RUN cp -R /lib* /home/ctf && \
cp -R /usr/lib* /home/ctf
RUN mkdir /home/ctf/dev && \
mknod /home/ctf/dev/null c 1 3 && \
mknod /home/ctf/dev/zero c 1 5 && \
mknod /home/ctf/dev/random c 1 8 && \
mknod /home/ctf/dev/urandom c 1 9 && \
chmod 666 /home/ctf/dev/*
RUN mkdir /home/ctf/bin && \
cp /bin/sh /home/ctf/bin && \
cp /bin/ls /home/ctf/bin && \
cp /bin/cat /home/ctf/bin
COPY ./ctf.xinetd /etc/xinetd.d/ctf
COPY ./flag.sh /flag.sh
RUN echo "Blocked by ctf_xinetd" > /etc/banner_fail
RUN chmod +x /flag.sh
COPY ./bin/ /home/ctf/
RUN chown -R root:ctf /home/ctf && \
chmod -R 750 /home/ctf && \
chmod 740 /home/ctf/flag
CMD ["/flag.sh"]
EXPOSE 70
修改后的ctf.xinetd
service ctf
{
disable = no
socket_type = stream
protocol = tcp
wait = no
user = root
type = UNLISTED
port = 70
bind = 0.0.0.0
server = /usr/sbin/chroot
# replace helloworld to your program
server_args = --userspec=1000:1000 /home/ctf ./pwn #pwn为二进制可执行文件的文件名
banner_fail = /etc/banner_fail
# safety options
per_source = 10 # the maximum instances of this service per source IP address
rlimit_cpu = 20 # the maximum number of CPU seconds that the service may use
#rlimit_as = 1024M # the Address Space resource limit for the service
#access_times = 2:00-9:00 12:00-24:00
}
把"start.sh"改为"flag.sh",以下为flag.sh的具体内容
#!/bin/sh
# Add your startup script
#!/bin/sh
sed -i "s/flag{pwntestflag}/$GZCTF_FLAG/" /home/ctf/flag
export GZCTF_FLAG=""
# DO NOT DELETE
/etc/init.d/xinetd start;
sleep infinity;
整体目录结构
flag文件内容
Dockerfile及flag.sh的相关解释见上面的web题编写部分
剩下的步骤和web题一样,就不再赘述了,直接上图
build
push
题目部署
题目测试
文章来源:https://www.toymoban.com/news/detail-420280.html
成功实现了pwn题的动态flag
如有错误或补充,欢迎评论或直接联系我
更多内容见我的个人博客:www.nh0pe.top
附开源CTF平台GZCTFgithub地址:https://github.com/GZTimeWalker/GZCTF,真的很好的一个平台。文章来源地址https://www.toymoban.com/news/detail-420280.html
到了这里,关于web和pwn题的简单动态flag实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!