如何优雅的使用Docker出一道动态flag的CTF题-GZCTF
如何优雅的使用Docker出一道动态flag的CTF题-GZCTF
最近想给新生出一些CTF入入入门题,一点一点摸索搭建了GZCTF(感谢GZTime师傅制作的如此优秀的平台),但是苦于出题,网上也没有很多相关文章,只能自己一点一点摸索。
关于安装Docker不在赘述,本文侧重记录构建Docker镜像实现动态flag的一种解决办法
首先一道CTF赛题的镜像构建前的大致目录结构如下-以SQL注入题目为例
CTF_Challenge/ |
这是一个最简单sql注入题目的目录,不包含README,Wreitup等。
关于index.php和sql_connect.php两个文件不在赘述。
Dockerfile
这里采用公开镜像base_image_nginx_mysql_php_56,师傅还有很多很好的镜像,例如php7的,可以移步这里CTFTraining
这个镜像预先集成了nginx,mysql等必要环境,无需我们手动构建,给我们构建Dockerfile带来的极大的方便
使用此镜像的Dockerfile的示例
FROM ctftraining/base_image_nginx_mysql_php_56 |
下面是我的Dockerfile
FROM ctftraining/base_image_nginx_mysql_php_56 |
实现动态flag需要在flag.sh中完成,不能在Dockerfile中实现,这是一个很简单的问题,因为Dockerfile是构建镜像的,注入动态flag需要在分发构建好的镜像后,不同用户启动镜像时完成。
db.sql
使用base_image_nginx_mysql_php_56构建镜像时,将db.sql放在src目录下,镜像启动过程中db.sql会自动执行并初始化数据库。
所以这个文件就是初始化数据库用的,不过对题目而言,sql注入题目需要在数据库中预先创建一个放置flag的表,用于存放flag。
比如
DROP DATABASE IF EXISTS challenge; |
这样就在数据库challenge中初始化了一个flag的表,其中有一个flag_is_here的字段
flag.sh
同样使用base_image_nginx_mysql_php_56构建镜像时,将flag.sh放在src目录下,镜像启动过程中会自动执行,需要在Dockerfile中给予可执行权限。下面是在数据库中插入动态flag值得一种方案
|
值得注意的是,镜像构建的时候先执行Dockerfile
,然后执行flag.sh
,最后执行db.sql
所以不能在flag.sh中这样写
|
因为此时db.sql
还未执行,会出现报错”ERROR 1049 (42000) at line 1: Unknown database ‘challenge’”
完成这些后,就可以构建镜像查看效果了
docker build -t 镜像名 . # 构建镜像 |
记住构建的镜像名,可以选择把他push到dockrhub上方便下载和分发
然后在GZCTF的题目镜像中填入构建好的镜像名,选择开启测试容器
然后就可以访问实例入口,尝试解题,看看flag是否已经被替换为动态flag
其他的flag.sh写法
关于其他类型的ctf题目,比如flag存放在根目录下的flag.txt,或者在源码目录的flag.php中等等以纯文本形式存放的,flag.sh可以参考如下
|
预先在需要存放flag的位置写一个flag{test},然后用sed,将环境变量替代他即可,最后记得把环境变量置空防止非预期。