详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等)

作者是namezz

(看完图相当于做了一轮实验系列)

现有文件代码如下

1.png (21.16 KB, 下载次数: 39)

2017-10-31 18:07 上传

2.png (58.43 KB, 下载次数: 28)

2017-10-31 18:07 上传

3.png (3.13 KB, 下载次数: 44)

2017-10-31 18:07 上传

4.png (2.29 KB, 下载次数: 46)

2017-10-31 18:07 上传

include和include_once、require、require_once用处差不多,故只举include例说明。话不多说,开始正文。(正文太啰嗦了,直接看总结吧)

功能说明

分别包含aaa和zzz,效果如下图所示

5.png (36.06 KB, 下载次数: 27)

2017-10-31 18:07 上传

6.png (36.9 KB, 下载次数: 29)

2017-10-31 18:07 上传

读取到zzz文件的内容<?phpecho __FILE__;并解析执行了,而aaa文件识别不为php,故直接输出源码内容。故包含/etc/passwd同理

7.png (49.38 KB, 下载次数: 28)

2017-10-31 18:07 上传

用readfile读文件如图所示

8.png (67.46 KB, 下载次数: 44)

2017-10-31 18:07 上传

9.png (55.71 KB, 下载次数: 39)

2017-10-31 18:07 上传

10.png (65.69 KB, 下载次数: 40)

2017-10-31 18:07 上传

由于加了图片头header,所以浏览器识别为图片类型。f12或抓包能看到响应包情况,能看到与include等不同的是,readfile是直接读文件内容,而不解析的。file_get_content同理(用法自行百度)。

原理说明:文件包含究竟包含了啥

首先,include函数和readfile函数都是先读取指定的内容(注意,这里是指定的内容而不是文件的内容,后面解释),而include函数会试图解析读取的内容,是否为php代码,如若是则执行,否则直接输出

如图所示,使用file协议、http协议、php协议(官方文档:http://php.net/manual/zh/wrappers.php)效果分别如下

11.png (38.68 KB, 下载次数: 35)

2017-10-31 18:07 上传

12.png (44.64 KB, 下载次数: 34)

2017-10-31 18:07 上传

13.png (40.73 KB, 下载次数: 33)

2017-10-31 18:07 上传

因为默认配置是没开allow_url_include的,所以使用http协议读文件会失败(开了就是远程包含,后面会说)

以上使用file协议和php协议都读到了文件的源码,并执行了

在使用php://filter/read=convert.base64-encode/和php://filter/string.rot13/对读取的内容进行编码看看

14.png (44.78 KB, 下载次数: 48)

2017-10-31 18:07 上传

15.png (3.23 KB, 下载次数: 30)

2017-10-31 18:07 上传

16.png (66.6 KB, 下载次数: 43)

2017-10-31 18:07 上传

这里由于<?php经rot13后转为<?cuc直接输出给浏览器,而浏览器不认识<?cuc标签,所以也没显示出来,但是查看源码也是能看到的

发现,同样是php协议,读取了文件的内容,但是使用了base64或者rot13对内容进行编码,直接输出了,直接读到了zzz的源码,

17.png (83.62 KB, 下载次数: 29)

2017-10-31 18:07 上传

读其他页面源码也是同理。还有需要一提的是这里不要直接包含i.php,因为用的是include而不是incloude_once,会无限包含调用自身,导致死循环(要理解递归,必先理解递归)。

还是看不懂,不知道包含了啥?

可以理解为包含了一个数据流

如readfile('zzz')或include('zzz')打开一个数据流,内容为zzz文件的内容,而include('php://filter/read=convert.base64-encode/resource=zzz')为打开一个数据流,内容为zzz文件的base64编码内容,所以我这里有一个文件,内容为<?phpphpinfo();的base64编码,

18.png (5.22 KB, 下载次数: 36)

2017-10-31 18:07 上传

再用php://filter/read=convert.base64-decode/resource=p.php去包含它,可以发现是执行了的

19.png (91.19 KB, 下载次数: 42)

2017-10-31 18:07 上传allow_url_fopen和allow_url_include对文件包含的影响

首先,看字面意思,allow_url_fopen是允许来自url的fopen,allow_url_include是允许来自url的include。下面用几个例子来说明一下

r.php?a=http://127.0.0.1/zzz

r.php?a=data:text/plain,qweraaa

r.php?a=data:text/plain;base64,cXdlcmFhYQ==

r.php?a=php://input

20.png (45.69 KB, 下载次数: 28)

2017-10-31 18:07 上传

21.png (47.44 KB, 下载次数: 36)

2017-10-31 18:07 上传

22.png (48.81 KB, 下载次数: 37)

2017-10-31 18:07 上传

接下来把allow_url_fopen关了再试一下

23.png (4.63 KB, 下载次数: 36)

2017-10-31 18:07 上传

修改php.ini然后重启httpd服务

24.png (62.29 KB, 下载次数: 45)

2017-10-31 18:07 上传

25.png (56.96 KB, 下载次数: 30)

2017-10-31 18:07 上传

发现failed了,但是php://input这个是不受allow_url_fopen影响的,关了也能读到post数据。

而allow_url_include,字面意思,控制include类函数能引用的数据流来源,是否允许直接包含来自url获取的数据流,只要开了的话就能直接远程包含getshell,举例说明如下

i.php?a=zzz

i.php?a=file:///var/www/html/zzz

i.php?a=php://filter/read=/resource=zzz

i.php?a=http://127.0.0.1/zzz

i.php?a=php://input

i.php?a=data:text/plain,<?phpsystem('date');?>

i.php?a=data:text/plain;base64,PD9waHAgc3lzdGVtKCdkYXRlJyk7Pz4=

关闭allow_url_include的情况下,除了前三个是本地包含,后面的都走远程包含的全都报错,如图所示

26.png (63.43 KB, 下载次数: 30)

2017-10-31 18:07 上传

打开allow_url_include后远程包含就行了,至此可以直接包含shell了

27.png (37.06 KB, 下载次数: 38)

2017-10-31 18:07 上传

28.png (43.07 KB, 下载次数: 30)

2017-10-31 18:07 上传

29.png (39.05 KB, 下载次数: 29)

2017-10-31 18:07 上传

30.png (43.57 KB, 下载次数: 32)

2017-10-31 18:07 上传图片马以及使用php协议绕过过滤进而getshell1、存在本地文件包含且只允许上传图片文件

这是一个图片

31.png (3.08 KB, 下载次数: 37)

2017-10-31 18:07 上传

打开后长这样

32.png (107.4 KB, 下载次数: 33)

2017-10-31 18:07 上传

包含它,是乱码

33.png (57.83 KB, 下载次数: 24)

2017-10-31 18:07 上传

在理解文件包含原理后,往图片添加php代码

34.png (46.81 KB, 下载次数: 45)

2017-10-31 18:07 上传

打开图片,还是长这样,没变化

35.png (112.51 KB, 下载次数: 33)

2017-10-31 18:07 上传

不过源码已经带了php代码

36.png (177.12 KB, 下载次数: 39)

2017-10-31 18:07 上传

包含图片

37.png (59.73 KB, 下载次数: 33)

2017-10-31 18:07 上传

php代码已经被执行了。2、存在本地文件包含且只允许上传图片文件且校验包含文件后缀是否为php

代码示例如下:

$f=$_GET[f];

if ( isset( $f )&&strtolower( substr( $f, -4 ) ) == ".php" )

{

require( $f );

}

使用zip或者phar协议

新建shell文件

38.png (15.61 KB, 下载次数: 40)

2017-10-31 18:07 上传

压缩为zip

39.png (44.38 KB, 下载次数: 34)

2017-10-31 18:07 上传

重命名为jpg

40.png (80.18 KB, 下载次数: 34)

2017-10-31 18:07 上传

41.png (22.43 KB, 下载次数: 33)

2017-10-31 18:07 上传

然后上传

打开当然显示图片损坏

42.png (48.69 KB, 下载次数: 33)

2017-10-31 18:07 上传

43.png (65.94 KB, 下载次数: 39)

2017-10-31 18:07 上传

然后使用phar协议或zip协议包含

44.png (73.75 KB, 下载次数: 38)

2017-10-31 18:07 上传

45.png (71.62 KB, 下载次数: 30)

2017-10-31 18:07 上传本地文件包含利用之一:包含日志文件getshell

这是一个空的日志文件

46.png (2.24 KB, 下载次数: 26)

2017-10-31 18:07 上传

47.png (65.73 KB, 下载次数: 31)

2017-10-31 18:07 上传

当然是404,但是在日志里面已经记录了这个请求了

48.png (6.94 KB, 下载次数: 36)

2017-10-31 18:07 上传

不过发现get请求的uri是经过url编码的,这样是不能被识别为php代码解析执行的。我们修改ua为<?phpphpinfo();?>再次访问

49.png (62.69 KB, 下载次数: 29)

2017-10-31 18:07 上传

50.png (22.58 KB, 下载次数: 31)

2017-10-31 18:07 上传

好的ua这里日志记录进去了,接下来包含日志就能执行php代码了

51.png (81.53 KB, 下载次数: 30)

2017-10-31 18:07 上传

注意,这里有的默认配置日志文件夹仅允许root可读写,httpd默认用户apache是没权限的,会报错failed to open stream

ermission denied总结

file_get_content、readfile类函数先读取对象的数据流,从文件或者php协议或者file协议或者http协议等读取数据流,而include、require类函数读取数据流后尝试对其进行解析与执行。故可以对数据流进行编码包含输出,导致读取源码或者任意文件下载,还可以花式编码解码绕过waf。

zzz、php://filter/read=/resource=zzz、http://127.0.0.1/zzz、file:///var/www/html/zzz、phar://s.jpg/s.php、zip://s.jpg%23s.php的数据流内容为对应的php代码,包含以上数据流就相当于包含对应php代码,相应协议的具体用法自行百度。

图片马本质是包含解析执行图片里面的php语句。

包含日志文件getshell原理一样,利用httpd日志记录访问情况,控制其中ua字段(由于uri字段会被编码,导致不被识别为php代码),再包含日志实际上也是包含对应的php代码。

so文件包含的目的是直接包含精心构造的恶意php代码,进而直接任意命令执行,当然如果能够直接上传.php文件并解析执行那就更好了,不用绕弯子绕文件包含那么麻烦。然而事情总不会是一帆风顺,在无法直接命令执行的时候(例如无法上传文件,不给上传恶意php代码等),就用文件包含去读源码,读配置文件,万一就找到其他地方存在漏洞了。

LFI(本地文件包含)和RFI(远程文件包含)的区别就在于allow_url_include的设置。allow_url_include=1基本就可以为所欲为了。

一些多余的东西

data:,<文本数据>

data:text/plain,<文本数据>

data:text/html,<HTML代码>

data:text/html;base64,<base64编码的HTML代码>

data:text/css,<CSS代码>

data:text/css;base64,<base64编码的CSS代码>

data:text/javascript,<Javascript代码>

<scriptsrc="data:text/javascript,alert('hello')"/>

data:text/javascript;base64,<base64编码的Javascript代码>

data:image/gif;base64,base64编码的gif图片数据

扫码投喂作者,打多打少是个缘

<imgsrc="https://img-blog.csdnimg.cn/2022010616070817169.png"height="80" width="80"/>

data:image/png;base64,base64编码的png图片数据

data:image/jpeg;base64,base64编码的jpeg图片数据

data:image/x-icon;base64,base64编码的icon图片数据

data:text/html,<html><body><p><b>Hello,world!</b></p></body></html>

-------------------------------------------------------------------------------------------------------

发个小福利

在前30评论中抽一个带入门,传授多年学习(装x)经验,妹子优先,会卖萌会撒娇会嘤嘤嘤者更佳

-------------------------------------------------------------------------------------------------------

php读取图片文件流,详解php文件包含原理(读取文件源码、图片马、各种协议、远程getshell等)...相关推荐

  1. java中batch基础_详解Spring batch 入门学习教程(附源码)

    详解Spring batch 入门学习教程(附源码) 发布时间:2020-09-08 00:28:40 来源:脚本之家 阅读:99 作者:achuo Spring batch 是一个开源的批处理框架. ...

  2. 详解linux下auto工具制作Makefile源码包(制作篇)

    2019独角兽企业重金招聘Python工程师标准>>> 详解linux下auto工具制作Makefile源码包(制作篇) 水木杨 一.     概述 为了更好的制作configure ...

  3. Android中mesure过程详解 (结合Android 4.0.4 最新源码)

    如何遍历并绘制View树?之前的文章Android中invalidate() 函数详解(结合Android 4.0.4 最新源码)中提到invalidate()最后会发起一个View树遍历的请求,并通 ...

  4. Android中layout过程详解 (结合Android 4.0.4 最新源码)

    上一篇文章Android中mesure过程详解 (结合Android 4.0.4 最新源码)介绍了View树的measure过程,相对与measure过程,本文介绍的layout过程要简单多了,正如l ...

  5. c语言 头文件卫士详解,C/C++中的“头文件卫士”

    在Objective C中可以用#import来防止重复包含,但在C/C++中就不同了,只能用"头文件卫士"了. 下面的程序是有错误的: // global.h 文件 // #if ...

  6. ADI Blackfin DSP处理器-BF533的开发详解66:MP3解码(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 代码实现功能 代码实现了读取工程目录下的一个 ...

  7. Yarn上MRAppMaster组件详解以及任务资源申请、启动的源码分析

    MRAppMaster是MapReduce的ApplicationMaster实现,它使得MapReduce计算框架可以运行于YARN之上.在YARN中,MRAppMaster负责管理MapReduc ...

  8. 深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)

    我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根节点下面,可配置properties.typeAliases.plugins.objectFa ...

  9. load python txt文件_详解Python中numpy.loadtxt()读取txt文件

    为了方便使用和记忆,有时候我们会把 numpy.loadtxt() 缩写成np.loadtxt() ,本篇文章主要讲解用它来读取txt文件. 读取txt文件我们通常使用 numpy 中的 loadtx ...

最新文章

  1. python画图哆啦a梦-python 绘制哆啦A梦
  2. Java使用MyEclipse2017时的一些小细节
  3. 表单美化-原生javascript和jQuery下拉列表(兼容IE6)
  4. 言有三新书预售,不贵,有料
  5. 设计模式(二十四)解释器模式
  6. Exception in thread main java.lang.NullPointerException一例解决
  7. C语言试题三之计算并输出 s=1+(1+2^(0.5))+(1+2^(0.5)+3^(0.5))+…+(1+2^(0.5)+3^(0.5)+…+n^(0.5))
  8. jvm(10)-早期(编译期)优化
  9. MySQL的复制:MySQL系列之十三
  10. P5713 【深基3.例5】洛谷团队系统(python3实现)
  11. SQL Alias(别名)
  12. call() apply() bind()
  13. 计算机过程控制系统李向舜pdf,2010-2011学年一学期(16-19周)考试安排表(1)
  14. Python数据结构实战——单向链表(LinkedList)
  15. Hbase 的Java API 操作
  16. 毕业两年程序员Java学习路线
  17. ESPN:韦德续约狠打LBJ脸 他诠释忠诚大于王权
  18. 微信小程序获取验证码
  19. 维多利亚计算机专业怎么样,维多利亚大学计算机科学专业 学生要学哪些内容...
  20. C++ MFC 大湿兄作品!游戏自动跳跳防AFK 支持 自动按空格 取消 隐藏以及显示游戏。方便在公司玩。支持最小化到托盘 魔兽世界防AFK掉线

热门文章

  1. Layui调整layui.confirm的样式
  2. 反Secure Boot垄断:兼谈如何在Windows 8电脑上安装
  3. 驼峰设计 PPT美化
  4. 电脑时间长自动关机,睡眠后自动关机休眠,如何保持不关机
  5. Excel 2010 VBA 入门 055 计算文本公式(Evaluate)
  6. win10 双屏显示双壁纸
  7. 熵减-华为活力之源-笔记
  8. 企业团队知识库对企业团队来说有何意义?
  9. Angular 入门教程系列:36:Restful的增删改查
  10. K2T突然掉电——原来是电源坏了