前言
文件包含漏洞是指在 WEB 应用中,由于未对用户输入的文件名进行严格验证,导致攻击者可以通过特定的输入获取服务器上的敏感文件,包括PHP源码。通过利用文件包含漏洞,攻击者可以读取包含PHP源码的文件,甚至可能执行任意代码,从而实现对服务器的控制。
今天在 CTFHUB 做了几道简单的文件包含题,写个 Write up 记录一下。
做题
文件包含
一点进来就可以看到一段 php 源码以及一个 shell 的链接。
这是一段文件包含的源码,当前页面会读取 GET 请求 file 的值,如果 file 字符串中不含 flag 的话,则以 file 字符串作为一个文件地址,include该文件。
但其实这个代码有个 bug,通过 strpos 来判断 flag 在字符串的位置,如果 flag 是字符串的开头,则返回的位置为0, if(!0) 会返回 true……不过这没什么影响,忽略即可。
这里有个 shell 文件的链接,提示我们需要利用这个文件,先来看看这个文件的内容。
这个文件里面也是一段 php 代码,这段代码执行后会拿 ctfhub 的值作为命令执行,不过这是个 txt 文件,而不是 php 文件。
include(),include_once(),require(),require_once(),fopen(),readfile() 等函数都会将文件当做 PHP 代码执行,而不会在意文件时什么类型,因此我们可以利用前面那个页面的 include 来包含 shell.txt 文件,然后再通过 shell.txt 脚本中的 ctfhub 参数来执行命令。
可以看到命令执行成功了,打印了当前目录的文件。
最终在根目录下找到了 flag 文件,成功拿到 flag!
php://input
在 CTF 中,我们经常会使用一些 php 伪协议来读取数据,例如 php://filter、php://input、file:// 等。
这次提示说没有 shell 文件给我们包含了,得想想别的方式。
先来看看代码,代码会判断 file 字符串是否已 php:// 开头,是则 include。
那这次我们可以用 php://input 伪协议来执行 php 代码。php://input 会读取 POST 请求的原始数据,我们把 php 脚本写到 POST 中,通过本地文件包含漏洞,即可执行我们的脚本。
使用 php://input 的前提是 allow_url_include=On,题目给了 phpinfo 的链接,点进去可以看到条件是符合的。
请求 xxx?file=php://input,用 Burp Suite 抓包,把请求改为 POST 请求,并在 POST 写入脚本:
1 | <?php system["ls"];?> |
可以看到命令执行成功了,后面把 flag 文件找出来即可。
读取源代码
这次提示 flag 藏在哪了。
直接用 php://filter 来读取文件源码即可,不需要任何的过滤
远程包含
这道题的解法其实和第二道题一样……就不过多赘述了。
不过这道题的名字是远程包含,其实应该是要我们用包含远程文件的方式来解,应该是可以按照下面这样的方式做的,不过我懒得再写个脚本弄个 web 应用了,用第二道题的解法即可。
总结
文件包含主要分为本地文件包含和远程文件包含,主要是利用 php 的 include(),include_once(),require(),require_once() 等函数包含文件并将文件当成 php 代码执行的特性来执行命令的漏洞。
该类题通常需要用到 php 伪协议,所以熟悉一些常用的 php 伪协议才行,比如 php://input、php://filter。