commit 9b4282aae929e14ee59f0f9715fd9785705e6904 Author: lhy6305 <2734565242@qq.com> Date: Wed Sep 18 23:32:52 2024 +0800 ~~ssh~~ https auto update diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7674cbf --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ + +/*.bat +/*.sh +/ssh-* + +/phplib/teaminfo_cache_* + +libvar_gsec.php +libvar_tid2proj.php diff --git a/api.php b/api.php new file mode 100644 index 0000000..32699a7 --- /dev/null +++ b/api.php @@ -0,0 +1,109 @@ +: download attachment for challenge , or interact with it\n"; + exit; +} + +gen_error_400("unknown action '".$action[0]."'. use 'help' to view help"); +exit; diff --git a/assets/Ubuntu Mono derivative Powerline.ttf b/assets/Ubuntu Mono derivative Powerline.ttf new file mode 100644 index 0000000..c9ce6a0 Binary files /dev/null and b/assets/Ubuntu Mono derivative Powerline.ttf differ diff --git a/assets/favicon.ico b/assets/favicon.ico new file mode 100644 index 0000000..85ea5d3 Binary files /dev/null and b/assets/favicon.ico differ diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 0000000..aded277 Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/team_token_tip.png b/assets/team_token_tip.png new file mode 100644 index 0000000..5b21bf2 Binary files /dev/null and b/assets/team_token_tip.png differ diff --git a/assets/ubuntu-font-licence-1.0.txt b/assets/ubuntu-font-licence-1.0.txt new file mode 100644 index 0000000..ae78a8f --- /dev/null +++ b/assets/ubuntu-font-licence-1.0.txt @@ -0,0 +1,96 @@ +------------------------------- +UBUNTU FONT LICENCE Version 1.0 +------------------------------- + +PREAMBLE +This licence allows the licensed fonts to be used, studied, modified and +redistributed freely. The fonts, including any derivative works, can be +bundled, embedded, and redistributed provided the terms of this licence +are met. The fonts and derivatives, however, cannot be released under +any other licence. The requirement for fonts to remain under this +licence does not require any document created using the fonts or their +derivatives to be published under this licence, as long as the primary +purpose of the document is not to be a vehicle for the distribution of +the fonts. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this licence and clearly marked as such. This may +include source files, build scripts and documentation. + +"Original Version" refers to the collection of Font Software components +as received under this licence. + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to +a new environment. + +"Copyright Holder(s)" refers to all individuals and companies who have a +copyright ownership of the Font Software. + +"Substantially Changed" refers to Modified Versions which can be easily +identified as dissimilar to the Font Software by users of the Font +Software comparing the Original Version with the Modified Version. + +To "Propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification and with or without charging +a redistribution fee), making available to the public, and in some +countries other activities as well. + +PERMISSION & CONDITIONS +This licence does not grant any rights under trademark law and all such +rights are reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of the Font Software, to propagate the Font Software, subject to +the below conditions: + +1) Each copy of the Font Software must contain the above copyright +notice and this licence. These can be included either as stand-alone +text files, human-readable headers or in the appropriate machine- +readable metadata fields within text or binary files as long as those +fields can be easily viewed by the user. + +2) The font name complies with the following: +(a) The Original Version must retain its name, unmodified. +(b) Modified Versions which are Substantially Changed must be renamed to +avoid use of the name of the Original Version or similar names entirely. +(c) Modified Versions which are not Substantially Changed must be +renamed to both (i) retain the name of the Original Version and (ii) add +additional naming elements to distinguish the Modified Version from the +Original Version. The name of such Modified Versions must be the name of +the Original Version, with "derivative X" where X represents the name of +the new work, appended to that name. + +3) The name(s) of the Copyright Holder(s) and any contributor to the +Font Software shall not be used to promote, endorse or advertise any +Modified Version, except (i) as required by this licence, (ii) to +acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with +their explicit written permission. + +4) The Font Software, modified or unmodified, in part or in whole, must +be distributed entirely under this licence, and must not be distributed +under any other licence. The requirement for fonts to remain under this +licence does not affect any document created using the Font Software, +except any version of the Font Software extracted from a document +created using the Font Software may only be distributed under this +licence. + +TERMINATION +This licence becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER +DEALINGS IN THE FONT SOFTWARE. diff --git a/assets/user_index_template.html b/assets/user_index_template.html new file mode 100644 index 0000000..b4e9b86 --- /dev/null +++ b/assets/user_index_template.html @@ -0,0 +1,32 @@ + + + + + + + +用户页面 - 附件分发 - woodpecker2024 + + + + + +

欢迎来到woodpecker2024::ctf

+

您当前作为队伍 [#REPLACE-ANCHOR-0#](id=#REPLACE-ANCHOR-1#) 登录

+
+
+由本服务提供的题目列表(点击下载附件或进行交互,在新窗口打开)
+#REPLACE-ANCHOR-2# +
+ + + + diff --git a/docker_container/Dockerfile b/docker_container/Dockerfile new file mode 100644 index 0000000..d614fb9 --- /dev/null +++ b/docker_container/Dockerfile @@ -0,0 +1,3 @@ +FROM debian:11-slim + +RUN sh "./docker_container/script-onboot.sh" diff --git a/docker_container/nginx-0.conf b/docker_container/nginx-0.conf new file mode 100644 index 0000000..0f7063e --- /dev/null +++ b/docker_container/nginx-0.conf @@ -0,0 +1,72 @@ +#it's already in the http directive + +server { + listen 2250; + listen [::]:2250; + listen 2260 ssl; + listen [::]:2260 ssl; + + root /root/www; + + add_header Access-Control-Allow-Origin * always; + + index null; + + autoindex on; + autoindex_localtime on; + charset utf-8,gbk; + + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + location ^~ /ldb/ { + proxy_pass http://127.0.0.1:2251/; + proxy_connect_timeout 50ms; + proxy_set_header Host "$http_host"; + proxy_buffering off; + error_page 502 =200 @error_default; + } + + location ~ /internal/ { + allow 127.0.0.1; + allow 192.168.1.14; + deny 192.168.1.0/24; + deny all; + location ~* (\.php|\.bat)$ { + include snippets/fastcgi-php.conf; + fastcgi_pass 127.0.0.1:9000; + } + } + + location ~* \.src$ { + try_files $uri $uri/ @try_use_src; + } + + location @try_use_src { + rewrite (.+)\.src$ $1 break; + error_page 404 @error_default; + add_header X-Source-File $uri always; + add_header Content-Type "text/plain; charset=utf-8" always; + } + + location @error_default {} + + location ~* (\.php\.*|\.bat\.*)$ { + include snippets/fastcgi-php.conf; + fastcgi_pass 127.0.0.1:9000; + } + + error_page 405 =200 $uri; + + + ssl_certificate /root/ly65.top_ecc/pub_chain1.pem; + ssl_certificate_key /root/ly65.top_ecc/pri.pem; + + ssl_session_timeout 5m; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; +} diff --git a/docker_container/script-onboot.sh b/docker_container/script-onboot.sh new file mode 100644 index 0000000..849819d --- /dev/null +++ b/docker_container/script-onboot.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +tail -f /dev/null diff --git a/docker_container/start.sh b/docker_container/start.sh new file mode 100644 index 0000000..821ff15 --- /dev/null +++ b/docker_container/start.sh @@ -0,0 +1 @@ +docker run --memory 1GB --user root --volume /media/sf_woodpecker2024/attachment_server/:/root/www/ --volume /media/sf_woodpecker2024/attachment_server/log/:/root/log/ --workdir /root/ --expose 80 --publish 12345:80 --attach stdin --attach stdout --attach stderr --interactive --tty debian:11-slim bash \ No newline at end of file diff --git a/incl_attachment_dl.php b/incl_attachment_dl.php new file mode 100644 index 0000000..fd697d6 --- /dev/null +++ b/incl_attachment_dl.php @@ -0,0 +1,51 @@ +misc::hash-test\n"; + +$team_info=get_team_info($game, $team_id); +$cid_list=get_challenge_list($game); + +$li[0]=$team_info["name"]; +$li[1]=$team_info["id"]; + +$li[2]=""; +for($a=0; $a"; + $li[2].="\n"; +} +unset($a); + +$str=file_get_contents_with_lock(__DIR__."/assets/user_index_template.html"); +$str=template_replace_anchor($str, $li); + +echo $str; diff --git a/index.html b/index.html new file mode 100644 index 0000000..63f30cd --- /dev/null +++ b/index.html @@ -0,0 +1,67 @@ + + + + + + + + +ly65的附件分发站 - woodpecker2024 + + + +

欢迎来到 woodpecker::ctf 2024 !

+ +
+这里是 ly65 的一个小站,用于分发本次比赛的部分附件,并提供一些共用容器服务
+
+在继续之前,请仔细阅读以下说明和约定
+
+- 本服务使用 team_token 验证身份,请勿泄露给非本队成员。
+
+- 除非另有说明,否则本附件分发服务提供的附件对每个用户都是固定的,不会因时间或请求次数而改变。
+
+- 为了确保有足够的辨识度,若 flag 需要从图形中读出,此类 flag 统一使用 Ubuntu Mono derivative Powerline 字体绘制(字体licence)
+
+- 本服务器并非靶机,未进行安全防护,且可用资源有限。在比赛期间,它是一个共用容器,因此:
+
+  - 所有交互题目都被设计能够在 30 次 HTTP 请求之内完成。请避免频繁或重复请求,以免过度占用服务器资源。
+
+  - 请勿进行渗透、注入、端口扫描等攻击。但允许对本附件分发服务(仅 /api.php)发送任意 HTTP 请求,只要不频繁发送或携带大量数据。
+
+- 对于可能与其他队伍产生信息交流的特殊题目,请勿泄露任何比赛相关内容,包括但不限于 flag、team_token、解题思路等。
+
+我们会记录比赛期间的服务器日志等信息,以检测违规行为,并视情况对违规者进行警告、禁赛等处罚。
+
+请共同维护公平、友好的比赛环境。
+
+
+继续操作即视为您同意遵守上述约定
+
+
+
+ +
+ + + + +比赛id + + + +请输入您的team_token + + + +
+ +
+
+

附件分发系统 for Woodpecker CTF 2024, created by ly65.
+ + \ No newline at end of file diff --git a/phplib/libattachmentmaker.php b/phplib/libattachmentmaker.php new file mode 100644 index 0000000..9423d14 --- /dev/null +++ b/phplib/libattachmentmaker.php @@ -0,0 +1,86 @@ +$max) { + list($min, $max)=[$max, $min]; + } + $delta=$max-$min; + if($delta<0||$delta>PHP_INT_MAX) { + gen_error_500("\$c_random_int(): \$delta is not between 0 and PHP_INT_MAX(".(string)PHP_INT_MAX.")"); + exit; + } + $t=$delta; + $res=0; + for($a=0; $t>0; $a++) { + $res<<=8; + $res|=unpack("C", $GLOBALS["c_random_int_seed"][$a&63])[1]; //&63 is equal to %64 + $t>>=8; + } + unset($a); + $res&=$delta; //avoid mod(%) operator, as it makes the result not evenly distributed + $GLOBALS["c_random_int_seed"]=hash("sha512", $GLOBALS["c_random_int_seed"], true); + return $min+$res; + }; + + //the function make_attachment_impl($team_hash) should return an array [(string)filename, (string)file_content] on success, or boolean false if it failed to generate. + + $fn=make_attachment_impl($thash); + if($fn===false||!is_array($fn)||count($fn)!=2||gettype($fn[0])!="string"||gettype($fn[1])!="string") { + $out="failed to make attachment for challange ".$proj["name"].": function call to make_attachment_impl(\$team_hash) failed or the returned value is invalid."; + if(gettype($fn)=="string") { + $out.="\nThe generator returned the following error:\n"; + $out.=$fn; + } + gen_error_500($out); + exit; + } + if(strlen($fn[0])<=0) { + $fn[0]="attachment.bin"; + } + return $fn; +} diff --git a/phplib/libchallengelist.php b/phplib/libchallengelist.php new file mode 100644 index 0000000..4c95fc0 --- /dev/null +++ b/phplib/libchallengelist.php @@ -0,0 +1,36 @@ +0||$re===false||strlen($re)<=0) { + gen_error_500("api request failed when trying to fetch team_info: ".$err); + exit; + } + $jo=json_decode($re, true); + if($jo===null) { + gen_error_500("api request failed when trying to fetch team_info: cannot decode response as json"); + exit; + } + if(!array_key_exists("items", $jo)) { + gen_error_500("api request failed when trying to fetch team_info: key \"items\" does not exist"); + exit; + } + $jo1=[]; + for($a=0; $a: raw string. e.g. string + V: variable-like. e.g. "string" + N: same as V, but with quotes removed. e.g. string + U: utf-8 encoded. e.g. \uxxxx\uxxxx\uxxxx + */ + preg_match("/#REPLACE-ANCHOR-([A-Z]*?)([0-9]+)#/", $str, $ma, PREG_OFFSET_CAPTURE, $ptr); + if(count($ma)<=0) { + break; + } + $da=""; + if(array_key_exists((int)$ma[2][0], $li)) { + $da=$li[$ma[2][0]]; + } + + $ma[1][0]=strtoupper($ma[1][0]); + //process flags + for($a=0; $astrlen($haystack)) { + return false; + } + if(strncmp($needle, $haystack, strlen($needle))==0) { + return true; + } + return false; + //end of str_starts_with + } +} + +if(!function_exists("mb_str_pad")) { + function mb_str_pad($str, $pad_len, $pad_str=" ", $dir=STR_PAD_RIGHT, $encoding=null) { + $encoding=($encoding===null?mb_internal_encoding():$encoding); + $padBefore=($dir===STR_PAD_BOTH||$dir===STR_PAD_LEFT); + $padAfter=($dir===STR_PAD_BOTH||$dir===STR_PAD_RIGHT); + $pad_len-=mb_strlen($str, $encoding); + $targetLen=$padBefore&&$padAfter?$pad_len/2:$pad_len; + $strToRepeatLen=mb_strlen($pad_str, $encoding); + $repeatTimes=ceil($targetLen/$strToRepeatLen); + $repeatedString=str_repeat($pad_str, max(0, $repeatTimes)); // safe if used with valid utf-8 strings + $before=$padBefore?mb_substr($repeatedString, 0, floor($targetLen), $encoding):""; + $after=$padAfter?mb_substr($repeatedString, 0, ceil($targetLen), $encoding):""; + return $before.$str.$after; + //end of mb_str_pad + } +} + +function getms() { + list($u, $s)=explode(" ", microtime()); + return (string)round(((float)$u+(float)$s)*1000); +} + +function query2param() { + $qstr=""; + if(array_key_exists("QUERY_STRING", $_SERVER)) { + $qstr=$_SERVER["QUERY_STRING"]; + } else { + $qstr=file_get_contents("php://input"); + } + if(gettype($qstr)!="string"||strlen($qstr)<=0) { + return false; + } + $param=[]; + $qstr=explode("&", $qstr); + for($a=0; $a[ + "cid_7"=>"tid_0", + "cid_1"=>"tid_1", + "cid_2"=>"tid_2", + "cid_3"=>"tid_3", + "cid_4"=>"tid_4", + "cid_5"=>"tid_5", + "cid_6"=>"tid_6", + ], + + "wood-1"=>[ + "cid_39"=>"tid_1", + "cid_40"=>"tid_2", + "cid_43"=>"tid_3", + "cid_42"=>"tid_4", + "cid_44"=>"tid_5", + "cid_41"=>"tid_6", + ], + + "wood-2"=>[ + "cid_1"=>"tid_1", + "cid_2"=>"tid_2", + "cid_3"=>"tid_3", + "cid_4"=>"tid_4", + "cid_5"=>"tid_5", + "cid_6"=>"tid_6", + ], + + ]; \ No newline at end of file diff --git a/phplib/libvar_gsec.example.php b/phplib/libvar_gsec.example.php new file mode 100644 index 0000000..6b98087 --- /dev/null +++ b/phplib/libvar_gsec.example.php @@ -0,0 +1,17 @@ +[ + "gurlbase"=>"http://192.168.1.66/", + "gid"=>1, + "gpub"=>"nvnP000000000000000000000000000000000000gb4=", + "gsalt"=>"bfc90000000000000000000000000000000000000000000000000000000037e5", + ], + ]; diff --git a/phplib/libvar_tid2proj.example.php b/phplib/libvar_tid2proj.example.php new file mode 100644 index 0000000..36dc0c2 --- /dev/null +++ b/phplib/libvar_tid2proj.example.php @@ -0,0 +1,13 @@ +[ + "name"=>"misc::hash-test", + "path"=>"./misc/local-hash-test/", + "hidden"=>false, + ], + + ]; diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..edd93c8 --- /dev/null +++ b/readme.md @@ -0,0 +1,13 @@ +# attachment-server + +这是一个简单的ctf动态附件分发程序,为woodpecker ctf编写 + +## 如果你看到了下面列出的文件*本身*而不是*模板示例*,请立刻上报管理员,这很重要! + +- `phplib/libvar_gsec.php` 存放比赛的 **公钥`gpub`** 和 **`gamesalt`(`gsalt`)** 。 +这两个值分别用于验证`team_token`和计算`team_hash`,此文件泄漏会导致 **全部`team_hash`** 泄漏为可计算的,从而丢失动态flag中`team_hash`的随机性。 + +- `phplib/libvar_tid2proj.php` 存放 **本地题目id `task_id`(`tid`)** 和 **本地工程信息 `proj_info`** 的映射关系,此文件泄漏会导致 **题目文件夹相对路径** 泄漏,从而可能导致 **题目名称** 泄漏。 + +## LICENCE +作者保留所有权利,暂不开放使用