前言
关于动态靶场的问题也是搞得十分困扰啊,由于各种python的不兼容问题,导致2022年8月前的教程和一些模板都受到了影响,并且没有做处理,导致前期不是很顺利,不过好在最后还是柳暗花明了(虽然与BUG共存了)但能RUN起来就是好东西
参考:https://5ime.cn/h1ve.html
1、下载H1ve
git clone [https://github.com/D0g3-Lab/H1ve.git](https://github.com/D0g3-Lab/H1ve.git)
下载完后可以看到以下目录结构:
有3个yml文件,我们选择single.yml
即可,single-nginx是加了一层反向代理的容器
2、搭建(*坑1)
在官网上给的是直接docker-compose up即可,可实际上不行,会报一层namerror
的错误,貌似是啥bug,但是不影响运行,实际上假如你按着README走是出不来的,他会永远卡在这一步的报错:
你需要docker-compose -f single.yml up -d
- -d:后台搭建
假如不后台搭建,前台会一直卡在这,这是一个小坑点,然后搭建完后docker结构如下:
其中frpc和frps是用来穿透docker容器的:docker network inspect h1ve_frp_containers
:
frp的服务端和ctfd绑定在一起,方便穿透,之后我们题目容器也是创建在这个网络中的,这里是介绍一下整个架构
一些常用指令:
1 | docker-compose -f xxx up -d #后台搭建 |
3、出题(Web)——*大坑
到了这里你看到了官网炫酷的样子,你以为一切都尘埃落定,出题只是分分钟的事情,那就特错大错啦!
不出意外的话进入这个界面一开始全部都是NONE.点UPDATE也不好使,这也是我觉得最操蛋的一个地方
应该是python搭建的导致请求过快,然后后端没接受到,所以这里需要手动burp抓包,然后放包给他改了,我就是直接一个无语
Docker Flag Prefix:flag前缀
Docker APIs URL:/var/run/docker.sock是docker daemon监听的套接字socket(ip+port),
docker daemon 是docker架构中一个常驻在后台的系统进程,功能是:接收处理docker client发送的请求。 该守护进程在后台启动一个server,server负载接受docker client发送的请求;接受请求后,server通过路由与分发调度,找到相应的handler来执行请求。
MAX contaniner count:最大开启的容器数
Max Renewal Times :容器持续时间
这一部分把DirectIP改为你VPS的地址,上面的是假如你有域名就可以填
mini port和max port指的是开放的最小和最大端口,下面的config对着填就好,是frpc.ini的配置内容,在linux中也可以查看到:
将这些配置好后就是出题目了,出题需要编写Dockerfile和docker-compose.yml,题目目录结构如下(参考5ime师傅):
1 | test # 题目存放文件夹必须小写英文 |
Dockerfile
1 | FROM php:7.3-apache |
docker-compose.yml
1 | version: '2' |
这里的flag有点讲究,我们在搭建的时候在当前文件夹准备了一个flag,内容无所谓,只要前缀和大括号包裹起来就行,然后在启动动态容器的时候,他会把容器内的flag进行替换,达到动态flag的效果
然后就是ports的问题,前面的9999可以随便改,但是绝对不能去掉,去掉了的话开启的容器端口就和frp映射的对应不上了(BUG)
files/start.sh
1 | #!/bin/bash |
这是启动容器后需要做的事情
files/index.php
1 | <!DOCTYPE html> |
flag
1 | HnuSec{f4af4a4fg485a6w4f89a489zv} |
放入题目文件夹
我们题目需要放在source目录下(相对路径)
在上面的docker-compose.yml文件中可以看到volumes是挂载了我们当前所在目录,和容器内同步了,因此在外边改就能改到里面,这很方便,我们需要把题目放在source目录里,比如里面的test/JavaMaster_final
这样我们在部署题目的时候只需要填一个文件夹test/JavaMaster_final
即可完成部署
题目配置如上即可,FPR PORT是需要暴露的容器端口,tomcat就是8080,一般都是80
4、复杂环境出题经验
就拿这次招新赛的WonderfulのSQL
来看,一个由javaweb搭建的有JDBC的项目,实际上考的也就是双写绕过的注入,只不过我想练一下自己的部署能力
在这就有很多坑点啊
Dockerfile的编写
1 | FROM java8-tomcat-8-mysql:1 |
start.sh
1 | #!/bin/bash |
我们需要捋一捋思路,在tomcat容器和mysql容器中,谁应该先搭建好呢?那肯定是mysql啊,所以假如mysql和tomcat同时搭建好的话,那肯定会出现一些问题
这次就遇到了sql初始化的问题,start.sh中准备的是对mysql初始化的工作,但是在我不用wait-for-it.sh 脚本的时候,tomcat执行mysql指令是不会等mysql容器初始化好再执行的,所以就导致失败
docker-compose.yml
1 | version: '2' |
其次就是docker-compose的编写,其中service 依赖了mysql容器,意味着需要等mysql创建好了,再创建tomcat容器,但这还不够,所以要加wait-for-it.sh去等待
然后就是docker网络的问题,这里由于mysql和tomcat容器需要互相能ping通,因此把他们都放入了容器网络中(在这里mysql就默认是主机名字了)
Maven项目
对于部署java项目呢,maven打包一定也要把依赖打包进来哦,要不然是无效的
flag
flag内容和上面一样,大括号内的东西随便取就行了
5、动态flag
动态flag的问题就和一开始说了,在启动容器时会对容器挂载的flag进行替换,可以利用这一点进行操作,就可上述的Java项目一样,令v=
cat /flag``,把v赋值flag,在进行后续操作
flag格式
在默认的条件下flag中的-
是被去掉了的,想要加回去得修改一下模板文件:
在/opt/H1ve/CTFd/plugins/ctfd-owl/docker_utils.py
中产生了flag:
这里flag原本是flag=prefix+flag.replace("-","")
把中间的横杠去掉了,这里我去掉了replace,这就使得flag更加美观
总结
大致就这么多啦,有问题会补上的
bug集合
填坑按钮无效
这是谷歌浏览器的问题,用Firefox和国内的!!!妈的气死我了,又发现火狐其实也不能解决,这是他架构的问题
500错误
因为redis中max client在后端处理中没有清空,因此会导致达到最大值
解决方法指标不治本:把max client拉满CONFIG SET max client 100000
,满了之后就重启H1ve容器
About this Post
This post is written by Boogipop, licensed under CC BY-NC 4.0.