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

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

作者是namezz

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

现有文件代码如下

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

功能说明

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

用readfile读文件如图所示

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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)效果分别如下

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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/对读取的内容进行编码看看

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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编码,

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

接下来把allow_url_fopen关了再试一下

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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的情况下,除了前三个是本地包含,后面的都走远程包含的全都报错,如图所示

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

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

这是一个图片

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

打开后长这样

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

包含它,是乱码

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

不过源码已经带了php代码

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

包含图片

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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文件

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

压缩为zip

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

重命名为jpg

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

然后上传

打开当然显示图片损坏

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

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

这是一个空的日志文件

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

8f3ff2fbfdd7c7c8339951a6542705fa.gif

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

2017-10-31 18:07 上传

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

9baf2b6185ba2463f18727a712af6ad1.gifermission 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)经验,妹子优先,会卖萌会撒娇会嘤嘤嘤者更佳

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值