cloversec-ctf-build-dockerizer
npx skills add https://github.com/d1a0y1bb/cloversec-ctf-build-dockerizer-skill --skill CloverSec-CTF-Build-Dockerizer
Agent 安装分布
Skill 文档
CloverSec-CTF-Build-Dockerizer
硬约æï¼å¹³å°åºå®ä½¿ç¨ /start.sh å¯å¨
éåæ ¹ç®å½é»è®¤å¿
é¡»å
å« /flag ä¸å¯è¯»ï¼RDG ä¸ include_flag_artifact=false 坿¾è¡ï¼
éåä¸å¿
é¡»åå¨ /bin/bash
è½åè¾¹çï¼å½åæ¯æ Jeopardy 模å¼ï¼Web/Pwn/AIï¼ä¸ RDGï¼Dockerï¼æ¨¡å¼ï¼ä¸æ¯æ AWD/AWDP ç«èµæ¨¡å¼ç¼æã
å¿«éå¼å§
- è¿å ¥ç¤ºä¾ç®å½ã
- ç¨
render.pyçæDockerfile/start.sh/flag(å¯é)+check èææ¶ã - ç¨
validate.shåéææ ¡éªã - æ¬å°
docker buildã - æ¬å°
docker run ... /start.shã - è§å¯æ¥å¿å¹¶ä¿®å¤é®é¢ã
æå°å½ä»¤é¾ï¼
cd src/CloverSec-CTF-Build-Dockerizer/examples/node-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-node-basic:latest .
docker run -d -p 3001:3000 ctf-node-basic:latest /start.sh
docker logs -f $(docker ps -q --filter ancestor=ctf-node-basic:latest | head -n 1)
ææ¡£å¯¼èª
- è¾å
¥ schemaï¼
src/CloverSec-CTF-Build-Dockerizer/data/schema.md - æ é»è®¤å¼ï¼
src/CloverSec-CTF-Build-Dockerizer/data/stacks.yaml - è¿è¡æ¶æ¡£ä½ï¼
src/CloverSec-CTF-Build-Dockerizer/data/runtime_profiles.yaml - æ¨æè§åï¼
src/CloverSec-CTF-Build-Dockerizer/data/patterns.yaml - å¯é
ç½®æ ¡éªï¼
src/CloverSec-CTF-Build-Dockerizer/data/validate_rules.yaml - digest æ¾è¡ç½ååï¼
src/CloverSec-CTF-Build-Dockerizer/data/base_image_allowlist.yaml - å¹³å°å¥çº¦ï¼
src/CloverSec-CTF-Build-Dockerizer/docs/platform_contract.md - æ¶ææ»è§ï¼
src/CloverSec-CTF-Build-Dockerizer/docs/architecture_overview.md - ç®å½æå¼ï¼
src/CloverSec-CTF-Build-Dockerizer/docs/directory_guide.md - æ æåï¼
src/CloverSec-CTF-Build-Dockerizer/docs/stack_cookbook.md - æ
éææ¥ï¼
src/CloverSec-CTF-Build-Dockerizer/docs/troubleshooting.md - æ°ææåï¼å®è£
/触å/åºæ¯ï¼ï¼
src/CloverSec-CTF-Build-Dockerizer/docs/beginner_guide.md
ç½ç®ä¹¦ç« èæ å°
- ç½ç®ä¹¦ä¸»ææ¡£ï¼
README.md - æ¬æä»¶ä¸ç½ç®ä¹¦å
³é®å¯¹åºï¼
- æ¬æ
è¾å ¥å¥çº¦<-> ç½ç®ä¹¦5. è¾å ¥å¥çº¦ - æ¬æ
AI Orchestrated Mode<-> ç½ç®ä¹¦6. AI Orchestrated Wizard - æ¬æ
æå¨æ¨¡å¼<-> ç½ç®ä¹¦7. æå¨æ¨¡å¼ - æ¬æ
9 æ æ¨¡æ¿ç´¢å¼<-> ç½ç®ä¹¦8. 乿 è½åå¯¹ç § - æ¬æ
validate è§å鿥<-> ç½ç®ä¹¦10. æ ¡éªç³»ç» - æ¬æ
å½ä»¤éæ¥/éå½<-> ç½ç®ä¹¦12-15
- æ¬æ
ä¸å¥è¯å®ä½
å½ä½ è¦æ WebãPwnãAI ä¸ RDGï¼Dockerï¼æ¨¡å¼é¢ç®æºç åæå¹³å°å¯è¿è¡éåæ¶ï¼ä½¿ç¨æ¬æè½å¯ä»¥ç¨³å®çæå¹¶æ ¡éªäº¤ä»ä»¶ã
è¾å ¥å¥çº¦ï¼challenge.yaml åæ®µæ å°ï¼
| åæ®µ | å¿ å¡« | é»è®¤å¼æ¥æº | ç¤ºä¾ | æ å°æ¨¡æ¿åé/è¡ä¸º |
|---|---|---|---|---|
challenge.name |
æ¯ | æ | node-basic |
ç¨äºæ è¯é¢ç®ï¼ä¸ç´æ¥è¿æ¨¡æ¿ |
challenge.stack |
å¦ | 侦æµç»æ | node |
éæ© templates/<stack>/ |
challenge.base_image |
å¦ | stacks.yaml |
node:20-alpine |
{{BASE_IMAGE}} |
challenge.workdir |
å¦ | stacks.yaml |
/app |
{{WORKDIR}}ï¼å¹¶è¦æ± start.sh cd |
challenge.app_src |
å¦ | . |
. |
{{APP_SRC}} |
challenge.app_dst |
å¦ | workdir |
/app |
{{APP_DST}} |
challenge.expose_ports |
å¦ | patterns -> stacks | ["3000"] |
{{EXPOSE_PORTS}} |
challenge.start.mode |
å¦ | cmd |
cmd |
å½±å exec æ ¡éªçç¥ |
challenge.start.cmd |
å¦ | patterns -> stacks | node server.js |
{{START_CMD}} |
challenge.start.service_name |
å¦ | 空 | apache2 |
å¤æå¡æè¿°è¾ å© |
challenge.runtime_deps |
å¦ | [] |
["curl"] |
{{RUNTIME_DEPS_INSTALL}} |
challenge.build_deps |
å¦ | [] |
[] |
å½åä¸ç´æ¥æ¸²æï¼ä¿çæ©å± |
challenge.flag.path |
å¦ | /flag |
/flag |
å¹³å°å¥çº¦å段 |
challenge.flag.permission |
å¦ | 444 |
444 |
å¹³å°å¥çº¦å段 |
challenge.platform.entrypoint |
å¦ | /start.sh |
/start.sh |
å¹³å°å¥çº¦å段 |
challenge.platform.require_bash |
å¦ | true |
true |
å¹³å°å¥çº¦å段 |
challenge.platform.allow_loopback_bind |
å¦ | false |
true |
localhost çå¬é¨ç¦è±å ï¼SSRF/å ç½é¾è·¯ï¼ |
challenge.healthcheck.enabled |
å¦ | true |
false |
æ§å¶æ¯å¦æ¸²æ HEALTHCHECK |
challenge.healthcheck.cmd |
å¦ | stacks.yaml |
bash -lc 'echo > /dev/tcp/127.0.0.1/80' |
HEALTHCHECK CMD |
challenge.healthcheck.interval |
å¦ | 30s |
30s |
HEALTHCHECK --interval |
challenge.healthcheck.timeout |
å¦ | 5s |
5s |
HEALTHCHECK --timeout |
challenge.healthcheck.retries |
å¦ | 3 |
5 |
HEALTHCHECK --retries |
challenge.healthcheck.start_period |
å¦ | 10s |
20s |
HEALTHCHECK --start-period |
challenge.extra.env |
å¦ | {} |
{NODE_ENV: production} |
{{ENV_BLOCK}} |
challenge.extra.copy |
å¦ | [] |
[{from:a,to:b}] |
{{COPY_APP}} |
challenge.extra.user |
å¦ | 空 | www-data |
å½åä¸ç´æ¥æ¸²æ |
challenge.extra.npm_install_block |
å¦ | èªå¨çæ | RUN npm ci ... |
{{NPM_INSTALL_BLOCK}} |
challenge.extra.pip_requirements_block |
å¦ | èªå¨çæ | RUN pip install ... |
{{PIP_REQUIREMENTS_BLOCK}} |
challenge.rdg.enable_sshd |
å¦ | true |
true |
RDG sshd ç»å½å¼å ³ |
challenge.rdg.sshd_port |
å¦ | 22 |
22 |
RDG sshd ç«¯å£ |
challenge.rdg.sshd_password_auth |
å¦ | true |
true |
RDG sshd å¯ç è®¤è¯ |
challenge.rdg.ttyd_binary_relpath |
å¦ | ttyd |
ttyd |
RDG ttyd äºè¿å¶ç¸å¯¹è·¯å¾ |
challenge.rdg.ttyd_install_fallback |
å¦ | true |
true |
RDG ttyd å®è£ åéå¼å ³ |
challenge.rdg.ctf_user |
å¦ | ctf |
ctf |
RDG é»è®¤éæè´¦æ· |
challenge.rdg.ctf_password |
å¦ | 123456 |
123456 |
RDG é»è®¤éæå£ä»¤ |
challenge.rdg.ctf_in_root_group |
å¦ | false |
false |
RDG æ¯å¦å å ¥ root ç» |
challenge.rdg.scoring_mode |
å¦ | check_service |
check_service |
RDG å¤å®æ¨¡å¼ |
challenge.rdg.include_flag_artifact |
å¦ | true |
false |
RDG æ¯å¦ä¿ç /flag äº§ç© |
challenge.rdg.check_enabled |
å¦ | true |
true |
RDG check é¨ç¦å¼å ³ |
challenge.rdg.check_script_path |
å¦ | check/check.sh |
check/check.sh |
RDG check èæ¬è·¯å¾ |
RDG check èæ¬å¥çº¦ï¼v1.4.0-r2ï¼
- æ¨èå
¥å£ï¼
bash check/check.sh [target_ip] [target_port] - åæ°åéï¼
TARGET_IP/TARGET_HOST/TARGET_PORT - è¿åç è¯ä¹ï¼
0ï¼æ£æ¥éè¿1ï¼æ£æ¥å¤±è´¥2ï¼èæ¬ä½¿ç¨æè¿è¡é误
- é¨ç¦è§åï¼
render.pyèªå¨èææ¶ä¸º fail-closedï¼CHECK_IMPLEMENT_ME+exit 1ï¼ï¼validate.shä¼é»æå ä½èæ¬ï¼å¦CHECK_IMPLEMENT_ME/TODOãçèæ¬ç´æ¥exit 0ï¼ã
ç»ä¸æ¨¡æ¿å鿏 å
BASE_IMAGEWORKDIRAPP_SRCAPP_DSTEXPOSE_PORTSSTART_CMDRUNTIME_DEPS_INSTALLCOPY_APPENV_BLOCKNPM_INSTALL_BLOCKPIP_REQUIREMENTS_BLOCKHEALTHCHECK_BLOCKSTACK_FLAG_BLOCK
validate èªå¨ä¿®å¤ä¸åå¸é¨ç¦ï¼v1.4.0-r2ï¼
bash .../validate.sh --fix Dockerfile start.sh challenge.yaml- ä» é¢è§å®å ¨èªå¨ä¿®å¤ï¼ä¸è½çã
bash .../validate.sh --fix-write Dockerfile start.sh challenge.yaml- åºç¨å®å ¨èªå¨ä¿®å¤åç»§ç»æ ¡éªã
bash .../validate.sh --fix --fix-loopback ...- å
è®¸ææ¾å¼ loopback ç»å®åæ°ï¼å¦
--host 127.0.0.1ï¼æ¹å为0.0.0.0ã
- å
è®¸ææ¾å¼ loopback ç»å®åæ°ï¼å¦
- åå¸é¾è·¯å¯è®¾ç½®
VALIDATE_ENFORCE_DIGEST=1ï¼è§¦ååºç¡éå digest 强é¨ç¦ï¼å®æ¹ç½åå tag-only æ¾è¡ï¼ã
å¹³å°å¥çº¦è§£éï¼æ§è¡æ¶å¿ é¡»ç¢è®°ï¼
- å¹³å° run å½ä»¤ä¼æ¾å¼ä¼
/start.shã - å æ¤
/start.shå¿ é¡»å¯æ§è¡ã /start.shå¿ é¡»è½å¯å¨ç宿å¡ã/start.shå¿ é¡»ä¿æå®¹å¨æç»è¿è¡ã/start.shå¿ é¡»æå¯è§æµæ¥å¿è¾åºã/flagé»è®¤å¿ é¡»åå¨ä¸å¯è¯»ï¼RDG ä¸include_flag_artifact=false坿¾è¡ï¼ã/bin/bashå¿ é¡»åå¨ã- åæå¡å¿
é¡»
exec主è¿ç¨ã - 夿å¡å¯åå°ä¸ä¸ªåå°ä¸ä¸ªï¼ä½ä¸è½ç©ºè½¬ã
AI Orchestrated Modeï¼å¼ºå¶åè®®ï¼
æ¬æè½é»è®¤è¿è¡å¨ AI ç¼ææ¨¡å¼ï¼ç®æ æ¯âç¨æ·åªå 5 项确认ï¼AI èªå¨å®æå ¶ä½æ¥éª¤âã
æ»åå
- AI å¿
é¡»ä¼å
æ§è¡èæ¬ï¼
derive_config.pyãrender.pyãvalidate.shã - AI ä¸å¾è¦æ±ç¨æ·èªå·±æ§è¡ä»»ä½å½ä»¤ã
- AI ä¸å¾åç»éªç´æ¥æå Dockerfile åä»£èæ¬è¾åºã
- AI å¿ é¡»æå ³é®é»è®¤å¼çè¯æ®ï¼evidenceï¼è§£éç»ç¨æ·ã
Step 0ï¼AI èªå¨æ§è¡ï¼ä¸è¯¢é®ç¨æ·ï¼
ç½ç®ä¹¦å¯¹åºï¼README.md -> 6. AI Orchestrated Wizardï¼5 é®ç¡®è®¤ + OK 鍿§ï¼
AI å¿ é¡»å æ§è¡ï¼
python3 src/CloverSec-CTF-Build-Dockerizer/scripts/derive_config.py --project-dir <é¢ç®ç®å½> --format json --pretty
ä»è¾åºä¸æå ProposedConfigï¼å¹¶çæâé ç½®ææ¡æè¦âï¼ä» 5 项ï¼ï¼
- ææ¯æ çæµ
- 端å£çæµ
- WORKDIR çæµ
- å¯å¨å½ä»¤åéï¼æå¤ 3 个ï¼
- app_src/app_dst æ·è´è·¯å¾å»ºè®®
æ¯é¡¹å¿
é¡»é带 evidenceï¼å½ä¸æä»¶/è§åï¼ã
è¥è¾åºå
å« config_proposal åæ®µï¼ä¼å
ç´æ¥ç¨äº Step 1 ç YAML ç¡®è®¤åæ¸²æã
è¥è¾åºå
å« gates åæ®µï¼å¿
é¡»ä¼å
æ§è¡é¨ç¦æç¤ºï¼
requires_explicit_stack_confirm=trueï¼ç¦æ¢ç´æ¥è¿å ¥ Step 2ï¼Q1 å¿ é¡»è®©ç¨æ·æ¾å¼ç¡®è®¤ stackãrequires_start_cmd_confirm=trueï¼Q4 å¿ é¡»è¦æ±ç¨æ·ç»åºæç» start å½ä»¤ï¼ç¦æ¢é»è®¤å车ç´è¿ãrequires_port_confirm=trueï¼Q2 å¿ é¡»è¦æ±ç¨æ·ç¡®è®¤ç«¯å£ï¼ä¸å¾âé»è®¤è§ä¸ºæ£ç¡®âã
Step 1ï¼ä» é® 5 个确认é®é¢ï¼
ç½ç®ä¹¦å¯¹åºï¼README.md -> 5. è¾å
¥å¥çº¦ï¼challenge.yaml + CONFIG PROPOSALï¼
AI å¿ é¡»æåºå®é¡ºåºæé®ï¼ä¸æ¯é¢é½å¸¦é»è®¤å¼ï¼
Q1 ææ¯æ + è¿è¡æ¶æ¡£ä½ï¼ä»
php/node/java æ¾ç¤ºæ¡£ä½åéï¼
é»è®¤ï¼<stack_guess.id> + <recommended_profile>
å¯éï¼node/php/python/java/tomcat/lamp/pwn/ai/rdg + runtime profile åéï¼è¥æï¼
Q2 容å¨ç«¯å£
é»è®¤ï¼<port_guess.ports>
æ ¼å¼ï¼åç«¯å£æéå·åéå¤ç«¯å£
Q3 å·¥ä½ç®å½ WORKDIR
é»è®¤ï¼<workdir_guess.workdir>
Q4 å¯å¨å½ä»¤ é»è®¤ï¼åé 1 åæ¶å±ç¤ºåé 2/3 å è®¸ç¨æ·ç´æ¥è¾å ¥èªå®ä¹å½ä»¤
Q5 ä»£ç æ·è´è·¯å¾
é»è®¤ï¼app_src="." -> app_dst=WORKDIR
åºå®æé®æ¨¡æ¿ï¼å¿ é¡»ææ¤ç»æï¼ï¼
ãé
ç½®ææ¡æè¦ã
1) æ : <stack_guess.id>ï¼confidence=<x.xx>ï¼evidence: <...>ï¼
2) 端å£: <ports>ï¼evidence: <...>ï¼
3) WORKDIR: <workdir>ï¼evidence: <...>ï¼
4) å¯å¨åé:
- #1 <cmd1>ï¼evidence: <...>ï¼
- #2 <cmd2>ï¼evidence: <...>ï¼
- #3 <cmd3>ï¼evidence: <...>ï¼
5) æ·è´è·¯å¾: <app_src> -> <app_dst>ï¼evidence: <...>ï¼
è¯·ç¡®è®¤ä»¥ä¸ 5 项ï¼ç´æ¥å车使ç¨é»è®¤å¼ä¹å¯ä»¥ï¼ï¼
Q1 ææ¯æ + è¿è¡æ¶æ¡£ä½ [é»è®¤: <stack_guess.id> + <recommended_profile>]ï¼
Q2 容å¨ç«¯å£ [é»è®¤: <ports>]ï¼
Q3 WORKDIR [é»è®¤: <workdir>]ï¼
Q4 å¯å¨å½ä»¤ [é»è®¤: <cmd1>; å¤é: <cmd2>/<cmd3>]ï¼
Q5 ä»£ç æ·è´ [é»è®¤: <app_src> -> <app_dst>]ï¼
Step 1 æ«å°¾ç¡¬è§åï¼å¿ é¡»æ§è¡ï¼ï¼
- 卿é®ç»æåï¼AI å¿
é¡»è¾åºâè¯æ®æè¦âï¼æå¤ 5 è¡ï¼æ¯è¡åªè¯´æ 1 æ¡å½ä¸ä¾æ®ï¼ä¾å¦å½ä¸
package.jsonãapp.pyãROOT.warãrequirements.txtæstacks.yamlé»è®¤è§åï¼ã - è¯æ®æè¦åï¼AI å¿
é¡»è¾åºä¸ä¸ªåç¬ç YAML é
ç½®åï¼æ é¢åºå®ä¸º
CONFIG PROPOSALï¼é®ååºå®å¦ä¸ï¼
CONFIG PROPOSAL:
stack: <node|php|python|java|tomcat|lamp|pwn|ai|rdg>
base_image: <string|optional> # ç±è¿è¡æ¶æ¡£ä½æ å°ææå¨æå®
workdir: <string>
app_src: <string>
app_dst: <string>
expose_ports: [<port>, ...]
start:
mode: cmd
cmd: "<string>"
platform:
entrypoint: "/start.sh"
require_bash: true
allow_loopback_bind: false
flag:
path: "/flag"
permission: "444"
healthcheck:
enabled: true
cmd: "bash -lc 'echo > /dev/tcp/127.0.0.1/80'"
interval: "30s"
timeout: "5s"
retries: 3
start_period: "10s"
rdg:
enable_ttyd: true
ttyd_port: "8022"
ttyd_login_cmd: "/bin/bash"
enable_sshd: true
sshd_port: "22"
sshd_password_auth: true
ttyd_binary_relpath: "ttyd"
ttyd_install_fallback: true
ctf_user: "ctf"
ctf_password: "123456"
ctf_in_root_group: false
scoring_mode: "check_service"
include_flag_artifact: true
check_enabled: true
check_script_path: "check/check.sh"
- YAML ååå¿ é¡»åæ ·è¾åºä»¥ä¸ä¸¤å¥è¯ï¼ä¸å¾æ¹åï¼ï¼
â妿以ä¸é ç½®æ£ç¡®ï¼è¯·åå¤ï¼OKâ
â妿éè¦ä¿®æ¹ï¼è¯·ç´æ¥å¨ä¸é¢ç YAML å鿹坹åºè¡å¹¶ååï¼ä¸è¦é¢å¤è§£éï¼ï¼æä¼æä½ ä¿®æ¹åçé 置继ç»çæä¸æ ¡éªãâ
交äºçº¦æï¼
- ä¸å 许追å 第 6 个é®é¢ï¼é¤éè¾å ¥ææ¾å²çªä¸æ æ³ç»§ç»ã
- æ¯é¢é½è¦ç»â为ä½é»è®¤å¦æ¤âçè¯æ®è¯´æï¼ç®çï¼ã
- å¦æç¨æ·è¾å
¥çå¯å¨å½ä»¤å¯è½åªçå¬
127.0.0.1ï¼AI å¿ é¡»æç¤ºæ¹ä¸º0.0.0.0å¹¶ç»åºç¤ºä¾ã - ç¨æ·è¥ä» å夿£ä¹±ææ¬ï¼AI ä¸å¾è¿å ¥çæé¶æ®µï¼å¿ é¡»è¦æ±å ¶âåå¤ OKâæâç²è´´ä¿®æ¹åç CONFIG PROPOSAL YAMLâã
Step 2ï¼ç¨æ·ç¡®è®¤å AI èªå¨çæï¼
ç½ç®ä¹¦å¯¹åºï¼README.md -> 6. AI Orchestrated Wizardï¼5 é®ç¡®è®¤ + OK 鍿§ï¼
AI èªå¨å®æï¼
è¿å ¥ Step 2 ç鍿§ï¼ç¡¬è§åï¼ï¼
- åªæå½ç¨æ·åå¤
OKï¼æè¿å䏿®µå¯è¢«è§£æçCONFIG PROPOSALYAML æ¶ï¼æè½ç»§ç»ã - è¥ç¨æ·è¾å
¥æ æ³è§£æä¸ºé
ç½®åï¼AI åªè½æç¤ºéå
OKæ YAMLï¼ä¸å¾å¼å§ render/validateã
AI èªå¨å®æï¼æé¡ºåºï¼ï¼
- ç¨æ·åå¤
OKï¼- éç¨ Step 1 䏿åä¸ç
CONFIG PROPOSALã
- éç¨ Step 1 䏿åä¸ç
- ç¨æ·åå¤ YAMLï¼
- å
æ§è¡
parse_config_block.pyä» stdin è§£æä¸ºchallenge.yamlã
- å
æ§è¡
- æ§è¡
render.pyçæDockerfile/start.sh/flag(å¯é)+check èææ¶ã - æ§è¡
validate.shåéææ ¡éªã
æ¨èå½ä»¤é¾ï¼
cat <project_dir>/config-proposal.yaml | python3 src/CloverSec-CTF-Build-Dockerizer/scripts/parse_config_block.py --output <project_dir>/challenge.yaml
python3 src/CloverSec-CTF-Build-Dockerizer/scripts/render.py --config <project_dir>/challenge.yaml --output <project_dir>
bash src/CloverSec-CTF-Build-Dockerizer/scripts/validate.sh <project_dir>/Dockerfile <project_dir>/start.sh <project_dir>/challenge.yaml
ä¿®å¤çç¥ï¼
- è¥ validate åºç° ERRORï¼AI å¿
é¡»èªå¨ä¿®å¤å¹¶éè· validateï¼ç´å°
ERROR=0æç¡®è®¤æ æ³èªå¨ä¿®å¤ã - è¥ä» WARNï¼å 许继ç»ï¼ä½å¿ 须解éå½±åä¸å»ºè®®ã
Step 3ï¼äº¤ä»è¾åºï¼
ç½ç®ä¹¦å¯¹åºï¼README.md -> 7. æå¨æ¨¡å¼ä¸çä»·å½ä»¤é¾ ä¸ 15. åå¸åéªæ¶æ¸
å
AI å¿ é¡»è¾åºï¼
- æç»æä»¶æ¸
åï¼
challenge.yamlãDockerfileãstart.shãflag(å¯é)ãcheck/check.sh(æ rdg.check_enabled çæï¼éæ¿æ¢ä¸ºç宿£æ¥é»è¾) - æ¬å°æµè¯å½ä»¤ï¼
docker build+docker run ... /start.sh - å¹³å°å¯¼å
¥æéï¼ç«¯å£æ å°ãåºå®
/start.shå¯å¨ã卿 flag ä¾èµ bash
ä½äº¤äºå¤±è´¥ä¿æ¤è§å
-
æ 侦æµç½®ä¿¡åº¦
<0.6ï¼- ä»ç»é»è®¤å¼
- ä½ Q1 å¿ é¡»å¼ºæç¤ºâè¯·ç¡®è®¤ææ¯æ â
- è¥
gates.requires_explicit_stack_confirm=trueï¼ç¦æ¢ç´æ¥è¿å ¥ Step 2
-
æ¾ä¸å°å¯ç¨å ¥å£æä»¶ï¼
start_cmd_candidateså¿ é¡»å å«ä¸ä¸ªç©ºå¼åéï¼cmd: ""ï¼å¹¶ç»åºé误æç¤º- Q4 强æç¤ºâå¿ é¡»ç¡®è®¤/å¡«åå¯å¨å½ä»¤â
- è¥
gates.requires_start_cmd_confirm=trueï¼ç¨æ·æªæç¡®ç¡®è®¤åä¸å¾ render
-
端å£ä¸ºç©ºï¼
- åéæ é»è®¤ç«¯å£
- Q2 强æç¤ºâ请确认端å£â
- è¥
gates.requires_port_confirm=trueï¼ç¨æ·å¿ é¡»æ¾å¼ç¡®è®¤ç«¯å£åæè½è¿å ¥ Step 2
æå¨æ¨¡å¼ï¼å¤ç¨ï¼
å½ AI ç¼æä¸å¯ç¨æ¶ï¼å 许æä¼ ç»å½ä»¤é¾æå¨æ§è¡ï¼
python3 src/CloverSec-CTF-Build-Dockerizer/scripts/render.py --config challenge.yaml --output .
bash src/CloverSec-CTF-Build-Dockerizer/scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t <image>:latest .
docker run -d -p <host_port>:<container_port> <image>:latest /start.sh
9 æ æå°æ¨¡æ¿åºç´¢å¼
Node
éç¨ï¼
- Node åç http
- Express
- Koa
- Fastify
é»è®¤ï¼
- 端å£
3000 - å¯å¨å½ä»¤
node server.js
æå°å¯å¨å½ä»¤èå¼ï¼
node server.js
å¯éåä½ï¼
npm run startpm2-runtime app.jsï¼å¯éï¼ä¸é»è®¤ï¼
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/node/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/node/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/node/README.md
PHP (Apache)
éç¨ï¼
- ä¼ ç» PHP ç«ç¹
- è½»é PHP æ¡æ¶
é»è®¤ï¼
- 端å£
80 - å¯å¨å½ä»¤
apache2-foreground
æå°å¯å¨å½ä»¤èå¼ï¼
apache2-foreground
å¯éåä½ï¼
- php-fpm 忝ï¼å¯æ©å±ï¼ä¸é»è®¤ï¼
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/php/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/php/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/php/README.md
Python
éç¨ï¼
- Flask
- FastAPI
- Django
- èªå HTTP
é»è®¤ï¼
- 端å£
5000 - å¯å¨å½ä»¤
python app.py
æå°å¯å¨å½ä»¤èå¼ï¼
python app.py
å¯éåä½ï¼
gunicorn -b 0.0.0.0:5000 app:appuvicorn app:app --host 0.0.0.0 --port 5000
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/python/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/python/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/python/README.md
Java (JAR)
éç¨ï¼
- å·²æå¯è¿è¡
app.jar
é»è®¤ï¼
- 端å£
8080 - å¯å¨å½ä»¤
java -jar app.jar
æå°å¯å¨å½ä»¤èå¼ï¼
java -jar app.jar
å¯éåä½ï¼
java -Xms128m -Xmx256m -jar app.jar
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/java/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/java/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/java/README.md
Tomcat (WAR)
éç¨ï¼
- å·²æ WAR å é¨ç½²
é»è®¤ï¼
- 端å£
8080 - å¯å¨å½ä»¤
catalina.sh run
æå°å¯å¨å½ä»¤èå¼ï¼
catalina.sh run
å¯éåä½ï¼
- å¤ WAR åºæ¯å¯å¤å¶æ´ä¸ª webapps ç®å½
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/tomcat/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/tomcat/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/tomcat/README.md
LAMP
éç¨ï¼
- å容å¨å éè¦ Apache + PHP + MariaDB
é»è®¤ï¼
- 端å£
80 - å¯å¨å½ä»¤
apache2ctl -D FOREGROUND
æå°å¯å¨å½ä»¤èå¼ï¼
- åå°å¯å¨ MariaDB
- åå°
exec apache2ctl -D FOREGROUND
å¯éåä½ï¼
- 使ç¨
MYSQL_INIT_SQL_B64æ³¨å ¥åå§å SQL - 坿©å± supervisorï¼ä¸é»è®¤ï¼
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/lamp/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/lamp/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/lamp/README.md
Pwn (xinetd/tcpserver/socat)
éç¨ï¼
- Jeopardy 模å¼äºè¿å¶è¿ç¨äº¤äºé¢ç®
- 以 xinetdãtcpserver æ socat æç®¡ææè¿ç¨
é»è®¤ï¼
- 端å£
10000 - å¯å¨å½ä»¤
/usr/sbin/xinetd -dontforkï¼Alpine å¯åé tcpserverï¼ç¼ºå¤±æ¶åé socatï¼
æå°å¯å¨å½ä»¤èå¼ï¼
exec /usr/sbin/xinetd -dontfork/exec tcpserver .../exec socat ...
å¯éåä½ï¼
- å¨
start.shå¯å¨åå°/flag忥å°/home/ctf/flag - æ ¹æ®
ctf.xinetdå¨æè°æ´ç«¯å£ä¸ server_argsï¼æ xinetd æ¶åé tcpserverï¼ä»ä¸å¯ç¨æ¶åé socat
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/pwn/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/pwn/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/pwn/README.md
AI (CPU)
éç¨ï¼
- CTF AI Web é¢ç®ï¼Flask/FastAPI çï¼
- 髿 ¸å¿å®¿ä¸»æºä¸ééå¶çº¿ç¨ç CPU æ¨çåºæ¯
é»è®¤ï¼
- 端å£
5000 - å¯å¨å½ä»¤
gunicorn -w 1 --threads 1 -b 0.0.0.0:5000 app:app
æå°å¯å¨å½ä»¤èå¼ï¼
exec gunicorn -w 1 --threads 1 -b 0.0.0.0:5000 app:app
å¯éåä½ï¼
- è½»éæ¨¡å¼ï¼
ai-basicï¼Flask + gunicornï¼ - å¢å¼ºæ¨¡å¼ï¼
ai-transformers-basicï¼å« transformers ä¾èµï¼
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/ai/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/ai/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/ai/README.md
RDG (Docker)
éç¨ï¼
- é²å¾¡ä¿®å¤å Docker é¢ç®ï¼check-service å¤å®ï¼
- éè¦ ttyd/sshd ç»å½ééä¸å¯é flag å ¼å®¹è·¯å¾
é»è®¤ï¼
- 端å£
80/22/8022ï¼ä¸å¡ç«¯å£ + sshd + ttydï¼ - å¯å¨å½ä»¤æä¸å¡æ éæ©ï¼å¦
apache2-foregroundæpython app.pyï¼
æå°å¯å¨å½ä»¤èå¼ï¼
- åééå¯ç¨æ¶ï¼åå°æèµ·
sshdåttydï¼åå°execä¸å¡ä¸»æå¡ - å
³éç»å½ééæ¶ï¼
enable_ttyd=falseä¸enable_sshd=falseï¼ä» ä¿çä¸å¡ä¸»æå¡åå°è¿è¡
å¯éåä½ï¼
include_flag_artifact=falseï¼ä» check-service å¤å®ï¼æ¾è¡/flag产ç©çº¦æcheck_enabled=true+check_script_pathï¼å¯ç¨å¼ºé¨ç¦ check èæ¬å¥çº¦
模æ¿è·¯å¾ï¼
src/CloverSec-CTF-Build-Dockerizer/templates/rdg/Dockerfile.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/rdg/start.sh.tplsrc/CloverSec-CTF-Build-Dockerizer/templates/rdg/README.md
validate è§å鿥
å¸¸è§ ERROR
Dockerfile æªå¤å¶ /start.shï¼
- å» Dockerfile å¢å
COPY start.sh /start.sh
Dockerfile æªå¤å¶ /flagï¼
- å¢å
COPY flag /flagæRUN touch /flag
/start.sh æéä¸å¯¹ï¼
- å¢å
RUN chmod 555 /start.sh
/flag æéä¸å¯¹ï¼
- å¢å
RUN chmod 444 /flag
bash 缺失ï¼
- Debian/Ubuntu å®è£ bash
- Alpine å®è£ bash
EXPOSE 缺失ï¼
- å¢å
EXPOSE <port>
åæå¡æ²¡æ execï¼
- æå¯å¨å½ä»¤æ¹æ
exec <主å½ä»¤>
æ£æµå°ç©ºè½¬å¾ªç¯ï¼
- å é¤ç©ºè½¬å½ä»¤ï¼æ¹ä¸ºç宿å¡åå°å¯å¨
tail -f /dev/null 䏿²¡ææå¡ï¼
- å¯å¨ç宿å¡ï¼ä¸å
许åªé
/dev/nullä¿æ´»
å¸¸è§ WARN
pip install æªå¸¦ --no-cache-dirï¼
- å¨ pip å½ä»¤å
--no-cache-dir
npm install æªä¼å
npm ciï¼
- æ lock æ¶æ¹ä¸º
npm ci
npm æªæ¸
ç cacheï¼
- å®è£
å
npm cache clean --force
夿塿ªä½¿ç¨ execï¼
- ç¡®ä¿è³å°æä¸ä¸ªåå°ä¸»è¿ç¨å¹¶å¯è§æµæ¥å¿
è¾åºå¥çº¦æ¸ åï¼çæåå¿ é¡»æ»¡è¶³ï¼
- 产ç©å¿
é¡»å
å«
Dockerfileãstart.shï¼å¹¶å¨é»è®¤æ¨¡å¼ä¸å å«flagã start.shé¦è¡å¿ é¡»æ¯#!/bin/bashãstart.shå¿ é¡»å å«set -euo pipefailãDockerfileå¿ é¡»æEXPOSEãDockerfileå¿ é¡»æstart.shæ¾å°/start.shãDockerfileå¿ é¡»æflagæ¾å°/flagï¼RDG ä¸include_flag_artifact=falseé¤å¤ï¼ãDockerfileå¿ é¡»è®¾ç½®/start.sh坿§è¡ãDockerfileå¿ é¡»è®¾ç½®/flagå¯è¯»ï¼RDG ä¸include_flag_artifact=falseé¤å¤ï¼ã- éåå¿
é¡»æ
/bin/bashã - åæå¡å¿
é¡»
exec主è¿ç¨ã - ä¸è½ä½¿ç¨ç©ºè½¬ä¿æ´»ã
- 注éå¿ é¡»æ¯ä¸æå¹¶è§£é设计åå ã
æ éææ¥å§æ¬
å§æ¬ A: render 失败
- æ£æ¥
challenge.yamlæ¯å¦å¯è§£æã - æ£æ¥
stackæ¯å¦å¨stacks.yamlæ¯æèå´å ã - æ£æ¥æ¨¡æ¿ include è·¯å¾æ¯å¦åå¨ã
- æ£æ¥æ¨¡æ¿å鿝å¦é½å¯æ¿æ¢ã
å§æ¬ B: validate 失败
- å ç ERRORã
- æéè¯¯ææ¡æ¹ Dockerfile/start.shã
- éæ° renderã
- éæ° validateã
- ç´å° ERROR 为 0ã
å§æ¬ C: build 失败
- ç Docker build æ¥å¿ä¸å¤±è´¥å±ã
- æ£æ¥åºç¡éåä¸å 管çå¨å¹é ã
- æ£æ¥ä¾èµå½ä»¤æ¯å¦ä¸éååè¡çä¸è´ã
å§æ¬ D: run 失败
docker logsçå¯å¨è¾åºã- æ£æ¥
START_CMDæ¯å¦æ£ç¡®ã - æ£æ¥çå¬å°åæ¯å¦
0.0.0.0ã - æ£æ¥ç«¯å£æ å°ã
å§æ¬ E: è¿è¡ä½è®¿é®å¤±è´¥
- æå¡æ¯å¦åªçå¬ localhostã
EXPOSEæ¯å¦å¹é challenge 端å£ãdocker run -pæ¯å¦æ å°æ£ç¡®ã
å§æ¬ F: è¿è¡ä½æ æ¥å¿
- æå¡æ¯å¦å stdout/stderrã
- 夿塿¯å¦ tail ç宿¥å¿æä»¶ã
- é¿å
ä»
é
/dev/nullã
å§æ¬ G: 忥åæè½ç®å½ä¸å®æ´
- æ§è¡
bash scripts/sync.shã - æ£æ¥ç®æ ç®å½æ¯å¦å
å«
SKILL.md/README.md/data/scripts/templates/examples/docsã - è¥ç®æ ä¸å¯åï¼æ¹ç¨
--target-dirã
å½ä»¤éæ¥
渲æ
python3 src/CloverSec-CTF-Build-Dockerizer/scripts/render.py --config challenge.yaml
æ ¡éª
bash src/CloverSec-CTF-Build-Dockerizer/scripts/validate.sh Dockerfile start.sh challenge.yaml
示ä¾åå½
bash src/CloverSec-CTF-Build-Dockerizer/scripts/validate_examples.sh
åç
bash src/CloverSec-CTF-Build-Dockerizer/scripts/smoke_test.sh
æ¸ ç
bash src/CloverSec-CTF-Build-Dockerizer/scripts/cleanup_test_containers.sh
忥
bash scripts/sync.sh
bash scripts/sync.sh --codex-dir
对LLM&Agentå·¥å ·çæ§è¡è¦æ±
- ä¼å éµå¾ªå¹³å°å¥çº¦ã
- ä¼å çæå¯è¿è¡ç»æï¼å追æ±ä¼åã
- åºç° ERROR å¿ é¡»èªå¨ä¿®å¤å¹¶éè¯ã
- åºç° WARN å¿ é¡»è§£éå½±åã
- ä¸è·³è¿æ ¡éªã
- ä¸ç¨ç©ºè½¬ææ®µä¼ªé åæ´»ã
对维æ¤è çæ§è¡è¦æ±
- æ°å¢æ æ¶åæ¥æ´æ° data/templates/examples/docsã
- æ°å¢è§åæ¶æ¶æ¯å¿ é¡»ç»ä¿®å¤æå¼ã
- åæ´åå¿ é¡»è·åå½ã
- åå¸åå¿ é¡»åæ¥å°æè½ç®å½å¹¶æ£æ¥å®æ´æ§ã
èªæ£æ¸ åï¼äº¤ä»åï¼
render.pyè½æ¸²æç®æ ç®å½ãvalidate.shæ ERRORã- 示ä¾åå½éè¿ã
- å ³é®ç¤ºä¾å¯ build/runã
- docs 龿¥ææã
- sync åç®å½èªå å«ã
åæ´è¾¹ç
æ¬æè½é»è®¤ä¸åï¼
- ä¸å¡ä»£ç æ¼æ´ä¿®å¤ã
- æ°æ®åºä¸å¡é»è¾è®¾è®¡ã
- AWD/AWDP èµå¶ç¼æã
æ¬æè½åªå¤çï¼
- Jeopardy æ¨¡å¼ Web/Pwn/AI ä¸ RDGï¼Dockerï¼é¢ç®ç¯å¢å®¹å¨å ¥å£æ ååã
- å¹³å°å¥çº¦åè§ã
- 模æ¿åå¤ç¨ä¸å¯éªè¯äº¤ä»ã
ç¸å ³æä»¶ç´¢å¼
README.mdsrc/CloverSec-CTF-Build-Dockerizer/data/schema.mdsrc/CloverSec-CTF-Build-Dockerizer/data/stacks.yamlsrc/CloverSec-CTF-Build-Dockerizer/data/validate_rules.yamlsrc/CloverSec-CTF-Build-Dockerizer/templates/node/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/php/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/python/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/java/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/tomcat/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/lamp/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/pwn/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/ai/README.mdsrc/CloverSec-CTF-Build-Dockerizer/templates/rdg/README.mdsrc/CloverSec-CTF-Build-Dockerizer/docs/platform_contract.mdsrc/CloverSec-CTF-Build-Dockerizer/docs/stack_cookbook.mdsrc/CloverSec-CTF-Build-Dockerizer/docs/troubleshooting.mdsrc/CloverSec-CTF-Build-Dockerizer/docs/beginner_guide.md
éå½ A: åæ æå°å½ä»¤
Node:
cd src/CloverSec-CTF-Build-Dockerizer/examples/node-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-node-basic:latest .
docker run -d -p 3001:3000 ctf-node-basic:latest /start.sh
PHP:
cd src/CloverSec-CTF-Build-Dockerizer/examples/php-apache-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-php-apache-basic:latest .
docker run -d -p 8081:80 ctf-php-apache-basic:latest /start.sh
Python:
cd src/CloverSec-CTF-Build-Dockerizer/examples/python-flask-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-python-flask-basic:latest .
docker run -d -p 5001:5000 ctf-python-flask-basic:latest /start.sh
Java:
cd src/CloverSec-CTF-Build-Dockerizer/examples/java-jar-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-java-jar-basic:latest .
docker run -d -p 8082:8080 ctf-java-jar-basic:latest /start.sh
Tomcat:
cd src/CloverSec-CTF-Build-Dockerizer/examples/tomcat-war-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-tomcat-war-basic:latest .
docker run -d -p 8083:8080 ctf-tomcat-war-basic:latest /start.sh
LAMP:
cd src/CloverSec-CTF-Build-Dockerizer/examples/lamp-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-lamp-basic:latest .
docker run -d -p 8084:80 ctf-lamp-basic:latest /start.sh
Pwn:
cd src/CloverSec-CTF-Build-Dockerizer/examples/pwn-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-pwn-basic:latest .
docker run -d -p 10001:10000 ctf-pwn-basic:latest /start.sh
AI:
cd src/CloverSec-CTF-Build-Dockerizer/examples/ai-basic
python3 ../../scripts/render.py --config challenge.yaml --output .
bash ../../scripts/validate.sh Dockerfile start.sh challenge.yaml
docker build -t ctf-ai-basic:latest .
docker run -d -p 5002:5000 ctf-ai-basic:latest /start.sh
éå½ B: åå½å½ä»¤
bash src/CloverSec-CTF-Build-Dockerizer/scripts/validate_examples.sh
bash src/CloverSec-CTF-Build-Dockerizer/scripts/smoke_test.sh
bash src/CloverSec-CTF-Build-Dockerizer/scripts/cleanup_test_containers.sh