Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
mst-sec-lecture-notes
提交
c6efe548
M
mst-sec-lecture-notes
项目概览
OpenDocCN
/
mst-sec-lecture-notes
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
mst-sec-lecture-notes
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c6efe548
编写于
3月 01, 2017
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
includev2
上级
ea44c75f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
101 addition
and
16 deletion
+101
-16
漏洞篇 文件包含.md
漏洞篇 文件包含.md
+101
-16
未找到文件。
漏洞篇 文件包含.md
浏览文件 @
c6efe548
...
...
@@ -10,7 +10,7 @@
文件包含就是将一个文件包含到自己的文件中执行。它可分为本地包含和远程包含,本地包含即包含本地磁盘上的文件,文件名称是相对路径或绝对路径,远程包含即包含互联网上的文件,文件名称是 URL。
##
示例代码
##
本地包含
比如我们有一个
`test.txt`
文件,仅仅调用
`phpinfo`
来测试:
...
...
@@ -23,24 +23,109 @@
```
php
<?php
$file
=@
$_GET
[
'file'
];
$b
=@
$_GET
[
'b'
];
if
(
$file
!==
null
){
echo
"<center>File:"
.
$file
.
"<br/>Result:</center>"
;
include
$file
;
}
else
if
(
$b
!==
null
){
echo
"<center>File:"
.
$b
.
"<br/>Result:</center>"
;
require
(
$b
);
require
(
$b
.
".php"
);
if
(
$file
){
echo
"<center>File:"
.
$file
.
"<br/>Result:</center>"
;
include
$file
;
}
```
第一行代码获取 URL 参数
`file`
的内容。
第二行代码获得 URL 参数
`b`
的内容。3 ~ 5 行首先判断
`$file`
是否为空,若不为空,输出其内容,并将其作为文件名称包含。6 ~ 9 行,若
`$file`
为空,则判断
`$b`
是否为空,不为空的话
,输出其内容,并将其作为文件名称包含。
第一行代码获取 URL 参数
`file`
的内容。
2 ~ 4 行首先判断
`$file`
是否为空,若不为空
,输出其内容,并将其作为文件名称包含。
我们
在相同目录下执行
`php -S 0.0.0.0:80`
,之后访问
`http://localhost/fileinclude.php?file=test.txt`
,会看到
`phpinfo`
的输出。
我们
将其部署在
`localhost`
下
,之后访问
`http://localhost/fileinclude.php?file=test.txt`
,会看到
`phpinfo`
的输出。
![](
http://
ww1.sinaimg.cn/large/841aea59jw1faturdjq4aj213d0ndgo0
.jpg
)
![](
http://
upload-images.jianshu.io/upload_images/118142-1a3322f9c2f5774e
.jpg
)
为了演示远程包含,我们需要将 PHP 配置文件中的
`allow_url_include`
设置为
`on`
,之后重启 PHP。远程包含的话,我们需要将
`file`
参数改为
`http://localhost/text.txt`
,可以看到相同结果。
我这里之所以用
`txt`
文件,就是想说明这个漏洞是无视扩展名的。跟文件上传漏洞不一样,文件上传漏洞中如果我们上传的文件不是
`.php`
就执行不了(当然也有一些绕过手段),但是文件包含漏洞中的扩展名是任意的,这里我们上传了
`.txt`
,证实有效,那么这个
`.jpg`
也是有效的。
要注意,如果被包含的文件里面没有 PHP 标签,那么就当成 HTML 内容如实显示出来。就比如我们放入之前的
`top100.txt`
:
![](
http://upload-images.jianshu.io/upload_images/118142-086434212534c816.jpg
)
## 远程包含
为了演示远程包含,我们需要将 PHP 配置文件中的
`allow_url_include`
设置为
`on`
,之后重启 PHP。PHP 配置文件的位置可以在
`phpinfo`
的输出中寻找,我们搜索
`ini`
即可:
![](
http://upload-images.jianshu.io/upload_images/118142-9148e3fa1cf3e7c5.jpg
)
我这里是
`C:\php-5.5.10\php.ini`
,你那里可能有些差别。我们打开它,搜索
`allow_url_include`
,会看到下面这些行,如果是
`Off`
把它改成
`On`
。
```
; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-include
allow_url_include = On
```
我们需要将
`file`
参数改为
`http://localhost/text.txt`
,可以看到相同结果。
## 技巧
### 00 截断
有些程序会给被包含内容加一些后缀,比如如果
`fileinclude.php`
是这样。
```
php
<?php
$file
=@
$_GET
[
'file'
];
if
(
$file
){
$file
.
=
'.php'
;
echo
"<center>File:"
.
$file
.
"<br/>Result:</center>"
;
include
$file
;
}
```
它后面加了个
`.php`
,也就是说,如果我们传入
`file=test`
则是正常的,传入
`file=test.txt`
,或变成
`test.txt.php`
,从而包含失败。那么我们应该怎么办呢?
如果 PHP 版本小于 5.3,并且
`magic_quotes_gpc`
已取消,我们就可以使用
`%00`
来截断。我们传入
`file=test.txt%00`
,就可以实现包含。
### 路径遍历
+
`./`
(或省略):当前目录
+
`../`
:上级目录
+
`/`
:根目录(Windows 中为当前盘内的根目录)
+
`~/`
:用户的主目录
例如,在 Linux 下,我们就可以使用
`file=/etc/passwd`
来读取系统密码。
这里是一些常见的日志文件位置:
+
apache+Linux日志默认路径
+
`/etc/httpd/logs/access.log`
+
`/var/log/httpd/access.log`
+
apache+win2003日志默认路径
+
`D:\xampp\apache\logs\access.log`
+
`D:\xampp\apache\logs\error.log`
+
IIS6.0+win2003默认日志文件
+
`C:\WINDOWS\system32\Lognames`
+
IIS7.0+win2003 默认日志文件
+
`%SystemDrive%\inetpub\logs\Lognames`
+
nginx 日志文件
+
`<安装目录>/logs`
+
如果安装目录为
`/usr/local/nginx`
,则为
`/usr/local/nginx/logs`
+
apache+linux 默认配置文件
+
`/etc/httpd/conf/httpd.conf`
+
`/etc/init.d/httpd`
+
IIS6.0+win2003 配置文件
+
`C:/Windows/system32/inetsrv/metabase.xml`
+
IIS7.0+WIN 配置文件
+
`C:\Windows\System32\inetsrv\config\applicationHost.config`
### PHP 伪协议
允许远程包含的情况下,我们可以使用
`php://`
伪协议,比如
`php://filter/resource=test.txt`
可以读取相同文件。
我们还可以加一个过滤器让它显示为 BASE64 编码格式,
`php://filter/read=convert.base64-encode/resource=test.txt`
。如果我们要获取的文件里面有不可打印的字符,或者我们想要获取代码的内容,可以用这种方式来获取,之后解码即可。
![](
http://upload-images.jianshu.io/upload_images/118142-1e6b92a7b9aaafb0.jpg
)
`php://input`
可以读取原始的 HTTP 正文内容。如果我们将
`file`
设置为
`php://input`
,并且在 HTTP 正文中传入 PHP 代码,例如
`<?php phpinfo();?>,即可执行代码。
![](http://upload-images.jianshu.io/upload_images/118142-427fcb5433711e67.png)
### Data URI
Data URI 的格式是`
data://text/plain;base64,
<base64>
`,同样需要远程包含。我们首先把一句话用 base64 编码,得到`
PD9waHAgcGhwaW5mbygpOz8+
`,然后将`
file
`设置为`
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
`(注意URL编码),即可执行代码。
![](http://upload-images.jianshu.io/upload_images/118142-862575e1b772aa41.jpg)
## 如何挖掘
...
...
@@ -48,12 +133,10 @@ if($file!==null){
## 利用
当我们发现了本地
或远程
包含漏洞时,首先寻找上传点,比如用户头像上传功能。然后我们可以构造一个纯文本文件,内容为
`<?php phpinfo();?>`
,并将其命名为
`xxx.jpg`
。
当我们发现了本地包含漏洞时,首先寻找上传点,比如用户头像上传功能。然后我们可以构造一个纯文本文件,内容为`
<?php phpinfo();?>
`,并将其命名为`
xxx.jpg
`。
之后我们就可以把`
xxx.jpg
`上传上去,并通过应用得到它的位置,假设是`
/upload/xxx.jpg
`,然后我们就可以把`
file
`参数的值改为它。以前面的代码为例,URL 是`
http://localhost/fileinclude.php?file=/upload/xxx.jpg
`。
要注意这个漏洞是无!视!扩!展!名!的!跟文件上传漏洞不一样,文件上传漏洞中如果我们上传的文件不是
`.php`
就执行不了(当然也有一些绕过手段),但是文件包含漏洞中的用户名是任意的,前面我们上传了
`.txt`
,证实有效,那么这个
`.jpg`
也是有效的。
如果我们把`
xxx.jpg
`的内容改为菜刀的一句话,那就可以用菜刀连接。
![](http://ww2.sinaimg.cn/large/841aea59jw1faturiysztj20sg0fjt9e.jpg)
...
...
@@ -65,3 +148,5 @@ if($file!==null){
## 附录
+
[
新手指南:DVWA-1.9全级别教程之File Inclusion
](
http://www.freebuf.com/articles/web/119150.html
)
+
[
PHP 伪协议
](
http://php.net/manual/zh/wrappers.php.php
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录