包含Session文件

PHP的session.save_path配置指定了session文件的结构深度、文件权限、存放路径,格式为N;MODE;/pathN表示子文件夹划分深度,MODE表示文件的umask值(默认为600),path通常为/var/lib/php/sessions/tmp

PHP在大文件流式上传时,为了将上传进度存放在session中,如果不存在session则会自动初始化,直到文件上传结束后销毁(由session.upload_progress.cleanup指定)。当session.upload_progress.enabled为默认值1时,上传文件的同时传递name="PHP_SESSION_UPLOAD_PROGRESS"即可利用(由session.upload_progress.name指定)

session.name通常为PHPSESSID,用作Cookie的键名。当session.use_strict_mode为默认值0时,客户端可以自定义sessionID,即通过Cookie传递PHPSESSID=hosch3n后,服务器将创建对应的sess_hosch3n文件。

因此就可以在利用文件上传自动初始化session的同时自定义sessionID,并利用条件竞争在文件上传完成前通过文件包含实现代码执行。

包含临时文件

即使PHP后端不是处理文件上传的代码,在收到上传文件数据时同样会创建缓存文件,文件名可以在$_FILES变量中找到(通常为/tmp/php[六个随机字符]),通过phpinfo页面可以读到$_FILES

一般的请求等获取到phpinfo中的文件名时已经结束了,此时可控的临时文件就已经被删掉了,但由于phpinfo中$_FILES[file][tmp_name]比其它HTTP头先输出,因此可以在HTTP头中发送大量无用数据,读到临时文件名后立即利用文件包含执行代码,通过条件竞争抢到临时文件被删除前时间窗口。